diff --git a/.changeset/strong-rings-hide.md b/.changeset/strong-rings-hide.md new file mode 100644 index 00000000..42b61b48 --- /dev/null +++ b/.changeset/strong-rings-hide.md @@ -0,0 +1,5 @@ +--- +"@proofkit/cli": patch +--- + +Limit `proofkit add` to supported ProofKit add-ons and remove the unused registry-backed install path. diff --git a/apps/docs/content/docs/cli/guides/adding-components/index.mdx b/apps/docs/content/docs/cli/guides/adding-components/index.mdx index 272fe0f4..f6ee1651 100644 --- a/apps/docs/content/docs/cli/guides/adding-components/index.mdx +++ b/apps/docs/content/docs/cli/guides/adding-components/index.mdx @@ -10,41 +10,12 @@ import { CliCommand } from "@/components/CliCommand"; After initializing a new ProofKit project, prefer agents or package-native tools such as shadcn and `@proofkit/typegen` for most post-init changes. -The old `proofkit add` flows are being phased out. This page is now legacy guidance only. +`proofkit add` is now limited to ProofKit add-ons. Legacy component-install flows are no longer supported. -The ProofKit package is installed in your project, and as a script in your `package.json`, so you can run the following command (as long as your current directory is your project root): +The supported `add` flow is: - + - -This will prompt you with a list of available components and features to add to your project. - -## Adding a Page - -ProofKit includes many page templates to help you build out your web app. Use this command to select one. - - - -If the template you select requires data, you may be prompted to select which data source and schema to use. (If there is only one, it will be selected by default without prompting) - -## Adding a Data Source - -If you need to connect to a new database or FileMaker file, use this command. - - - -For FileMaker data sources, a single "Data Source" consists of: - -- A FileMaker Server -- A FileMaker File -- An OttoFMS API Key (representing a single account name with permission to the file) - -If you need to change any one of these (i.e. to connect to a different file on the same server), you'll want to add a new data source. - -## Adding Schema - -When you want to interact with data from a new table or layout, you'll need to add a `schema`. - - +Use package-native tools or agents for everything else. diff --git a/apps/docs/content/docs/cli/guides/adding-components/meta.json b/apps/docs/content/docs/cli/guides/adding-components/meta.json index 18c4c7fc..2241b489 100644 --- a/apps/docs/content/docs/cli/guides/adding-components/meta.json +++ b/apps/docs/content/docs/cli/guides/adding-components/meta.json @@ -1,6 +1,6 @@ { "title": "Adding Components", "icon": "puzzle", - "pages": ["templates"], + "pages": [], "defaultOpen": true } diff --git a/apps/docs/content/docs/cli/guides/adding-components/templates.mdx b/apps/docs/content/docs/cli/guides/adding-components/templates.mdx deleted file mode 100644 index fdf728ab..00000000 --- a/apps/docs/content/docs/cli/guides/adding-components/templates.mdx +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: All Templates -icon: ExternalLink ---- - -import Redirect from "@/components/redirect"; - -# ProofKit Templates - diff --git a/apps/docs/content/docs/cli/guides/auth/add-on.mdx b/apps/docs/content/docs/cli/guides/auth/add-on.mdx index 28f80484..6da2e869 100644 --- a/apps/docs/content/docs/cli/guides/auth/add-on.mdx +++ b/apps/docs/content/docs/cli/guides/auth/add-on.mdx @@ -18,7 +18,7 @@ While FileMaker Add-on Auth is built to be secure, it is more advanced than a ty From within a ProofKit project, run the following command: - + This auth integration requires that some specific tables and layouts exist in your FileMaker file. The CLI will detect if these layouts and not in your file, and notify you to install the FileMaker Add-on if they are missing. The FileMaker Add-on encapsulates all of the changes needed and makes it easy to add the requirements to your file. @@ -94,4 +94,4 @@ By default, the layout for the password reset table should be named `proofkit_au ### Alternative Authentication Methods -At this time, FileMaker Add-on Auth will only setup email/password authentication for you, but any other authentication methods can be added by modifying the code yourself. Guides for integrating OAuth providers, passkeys (WebAuthn), two-factor, and more are available in the [Lucia documentation](https://lucia-auth.com/). Just keep in mind that you'll likely need to add more fields to the tables and layouts as mentioned above to support those additional features. \ No newline at end of file +At this time, FileMaker Add-on Auth will only setup email/password authentication for you, but any other authentication methods can be added by modifying the code yourself. Guides for integrating OAuth providers, passkeys (WebAuthn), two-factor, and more are available in the [Lucia documentation](https://lucia-auth.com/). Just keep in mind that you'll likely need to add more fields to the tables and layouts as mentioned above to support those additional features. diff --git a/apps/docs/content/docs/cli/guides/auth/clerk.mdx b/apps/docs/content/docs/cli/guides/auth/clerk.mdx index 2116721d..faf9b05d 100644 --- a/apps/docs/content/docs/cli/guides/auth/clerk.mdx +++ b/apps/docs/content/docs/cli/guides/auth/clerk.mdx @@ -4,17 +4,10 @@ description: How to add Clerk authentication to your ProofKit project --- -import { CliCommand } from "@/components/CliCommand"; - - ## What is Clerk? [Clerk](https://clerk.com/) is a hosted authentication service that is extremely easy to set up and use. It's a great choice to secure most customer-facing web apps, including built-in features such as Social logins, magic link, multi-factor authentication, and more. ## Adding Clerk to your ProofKit project -To add Clerk to your ProofKit project, run the following command: - - - -For further details on how to use Clerk, see the [Clerk documentation](https://clerk.com/docs/references/nextjs/overview). \ No newline at end of file +ProofKit no longer installs Clerk through `proofkit add`. Set up Clerk directly in your app using the [Clerk documentation](https://clerk.com/docs/references/nextjs/overview). diff --git a/apps/docs/content/docs/cli/registry/index.mdx b/apps/docs/content/docs/cli/registry/index.mdx deleted file mode 100644 index e977f272..00000000 --- a/apps/docs/content/docs/cli/registry/index.mdx +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: ProofKit Registry -description: A collection of ProofKit templates for building great apps ---- - -The ProofKit Registry is a collection of ProofKit templates for building great apps. - -## Templates - -### @proofkit/template-basic - -A basic ProofKit template for building great apps. \ No newline at end of file diff --git a/apps/docs/content/docs/cli/v2.mdx b/apps/docs/content/docs/cli/v2.mdx index 67ac71fb..15fb42bc 100644 --- a/apps/docs/content/docs/cli/v2.mdx +++ b/apps/docs/content/docs/cli/v2.mdx @@ -9,9 +9,9 @@ description: In this major release, the ProofKit CLI has been reimagined as a mo When you start a new app using the ProofKit CLI, the new template is based on shadcn and tailwindcss instead of Mantine. This new simple template still includes the best practices from the Proof team, but now with even more flexibility. -### A new way to add [anything] +### A new starting point for add-ons -The `proofkit add` command leverages the shadcn CLI to install any component or utility into your app, or you can use the shadcn CLI directly to install any component from any compatible library. Even better, these templates are now published right here on the docs site, so we can more easily release updates and new components that you can use right away. +The CLI still supports ProofKit-specific add-ons where that workflow makes sense, but general component installation should use package-native tools directly. ### A new level of compatibility @@ -19,15 +19,15 @@ You can now use the ProofKit CLI in an existing Next.js app, even if it wasn’t # Why the change? -Adding new templates to the ProofKit CLI was always a challenge, and arguably the most lacking of the whole system. The templates are meant to be just a starting place, so they needed to be generic to fit any project, yet useful enough to warrant inclusion in the binary everyone downloads to run the CLI. That wasn’t scalable. But shadcn has taken the JavaScript world by storm over the past few years, especially with the rise of AI and especially tools like v0. We needed to unlock the ability to easily add anything to your JavaScript projects, whether it was a template from Proof, shadcn, v0 (AI-generated), or from any of the other emerging UI libraries built on the shadcn CLI. +Adding new templates to the ProofKit CLI was always a challenge, and arguably the most lacking of the whole system. The templates are meant to be just a starting place, so they needed to be generic to fit any project, yet useful enough to warrant inclusion in the binary everyone downloads to run the CLI. That wasn’t scalable. But this required a new starting point. While mantine and tailwind can be used together in the same project, they get in each other’s way. At Proof, we’ve been building new projects without ProofKit for a few months now, so it was time to bring those learnings back to the framework so we could all move more quickly. New projects will start with a new foundation based on tailwindcss. It’s easier for AI to understand, and more compatible with any UI component built for shadcn to install for you. -But the shadcn CLI isn’t just about UI components. It can install any utility or set of components into your app. Take the new `@proofkit/better-auth` package that was recently released. It’s the best way to quickly and easily add self-hosted authentication to your web app, without having to compromise on login options or pay for an external auth service. But setting it up was not easy...until now! Check out our @proofkit/better-auth [guide](/docs/better-auth/installation) for more details. +Take the new `@proofkit/better-auth` package that was recently released. It’s the best way to quickly and easily add self-hosted authentication to your web app, without having to compromise on login options or pay for an external auth service. Check out our @proofkit/better-auth [guide](/docs/better-auth/installation) for more details. # Upgrade from v1 -Unfortunately, there is not an easy path for you to upgrade projects that were created with v1 to be fully compatible with v2. But if you are able to setup tailwindcss and shadcn in your existing project, you can still use the ProofKit CLI to add new components and utilities to your app. +Unfortunately, there is not an easy path for you to upgrade projects that were created with v1 to be fully compatible with v2. But if you are able to setup tailwindcss and shadcn in your existing project, you can still use package-native tools directly alongside ProofKit. Basic steps: diff --git a/apps/docs/content/docs/meta.json b/apps/docs/content/docs/meta.json index 3d35848a..7a5bbf74 100644 --- a/apps/docs/content/docs/meta.json +++ b/apps/docs/content/docs/meta.json @@ -1,11 +1,3 @@ { - "pages": [ - "cli", - "templates", - "fmdapi", - "fmodata", - "webviewer", - "typegen", - "better-auth" - ] + "pages": ["cli", "fmdapi", "fmodata", "webviewer", "typegen", "better-auth"] } diff --git a/apps/docs/content/docs/templates/index.mdx b/apps/docs/content/docs/templates/index.mdx deleted file mode 100644 index 7898e6a7..00000000 --- a/apps/docs/content/docs/templates/index.mdx +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: ProofKit Templates ---- \ No newline at end of file diff --git a/apps/docs/content/docs/templates/meta.json b/apps/docs/content/docs/templates/meta.json deleted file mode 100644 index 5347a602..00000000 --- a/apps/docs/content/docs/templates/meta.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "title": "Templates", - "description": "Quickly install via CLI", - "icon": "Puzzle", - "root": true -} diff --git a/apps/docs/next.config.ts b/apps/docs/next.config.ts index 5e2bb4a6..c33f2091 100644 --- a/apps/docs/next.config.ts +++ b/apps/docs/next.config.ts @@ -8,7 +8,7 @@ const withMDX = createMDX(); const config: NextConfig = { reactStrictMode: true, serverExternalPackages: ["typescript", "twoslash", "shiki"], - transpilePackages: ["@proofkit/fmdapi", "@proofkit/registry", "@proofkit/typegen"], + transpilePackages: ["@proofkit/fmdapi", "@proofkit/typegen"], turbopack: { root: path.resolve(__dirname, "../.."), }, @@ -21,14 +21,7 @@ const config: NextConfig = { return config; }, async redirects() { - return [ - { - source: "/registry/:path*", - destination: "/r/:path*", - permanent: true, - }, - { source: "/docs", destination: "/docs/cli", permanent: false }, - ]; + return [{ source: "/docs", destination: "/docs/cli", permanent: false }]; }, }; diff --git a/apps/docs/package.json b/apps/docs/package.json index 36bc5b63..a84db07b 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -4,7 +4,7 @@ "type": "module", "private": true, "scripts": { - "build": "pnpm --filter @proofkit/typegen build && node scripts/bundle-registry-templates.js && next build", + "build": "pnpm --filter @proofkit/typegen build && next build", "dev": "next dev -p 3005", "start": "next start -p 3005", "postinstall": "fumadocs-mdx", @@ -14,7 +14,6 @@ }, "dependencies": { "@base-ui-components/react": "1.0.0-rc.0", - "@proofkit/registry": "workspace:*", "@proofkit/typegen": "workspace:*", "@proofkit/webviewer": "workspace:*", "@radix-ui/react-collapsible": "^1.1.12", diff --git a/apps/docs/scripts/bundle-registry-templates.js b/apps/docs/scripts/bundle-registry-templates.js deleted file mode 100755 index 0fe4e83a..00000000 --- a/apps/docs/scripts/bundle-registry-templates.js +++ /dev/null @@ -1,100 +0,0 @@ -#!/usr/bin/env node - -import fs from "node:fs"; -import path from "node:path"; -import { fileURLToPath } from "node:url"; - -const __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); - -/** - * This script copies registry template files into the Next.js build - * so they're available as static assets in serverless environments - */ - -function bundleRegistryTemplates() { - console.log("📦 Bundling registry templates..."); - - try { - // Source: registry package templates - const registryPath = path.resolve(__dirname, "../../../packages/registry/templates"); - - // Destination: Next.js public directory (served as static assets) - const publicRegistryPath = path.resolve(__dirname, "../public/registry-templates"); - - // Clean and create destination directory - if (fs.existsSync(publicRegistryPath)) { - fs.rmSync(publicRegistryPath, { recursive: true }); - } - fs.mkdirSync(publicRegistryPath, { recursive: true }); - - // Copy all template files - copyDirectory(registryPath, publicRegistryPath); - - console.log("✅ Registry templates bundled successfully!"); - console.log(`📁 Templates available at: ${publicRegistryPath}`); - - // Also create a manifest of all available templates - const manifest = createTemplateManifest(publicRegistryPath); - fs.writeFileSync(path.join(publicRegistryPath, "manifest.json"), JSON.stringify(manifest, null, 2)); - - console.log(`📋 Template manifest created with ${manifest.templates.length} templates`); - } catch (error) { - console.error("❌ Failed to bundle registry templates:", error); - process.exit(1); - } -} - -function copyDirectory(src, dest) { - if (!fs.existsSync(src)) { - throw new Error(`Source directory does not exist: ${src}`); - } - - const entries = fs.readdirSync(src, { withFileTypes: true }); - - for (const entry of entries) { - const srcPath = path.join(src, entry.name); - const destPath = path.join(dest, entry.name); - - if (entry.isDirectory()) { - fs.mkdirSync(destPath, { recursive: true }); - copyDirectory(srcPath, destPath); - } else { - fs.copyFileSync(srcPath, destPath); - } - } -} - -function createTemplateManifest(templatesPath) { - const templates = []; - - function scanDirectory(dir, relativePath = "") { - const entries = fs.readdirSync(dir, { withFileTypes: true }); - - for (const entry of entries) { - const fullPath = path.join(dir, entry.name); - const relPath = path.join(relativePath, entry.name); - - if (entry.isDirectory()) { - scanDirectory(fullPath, relPath); - } else if (entry.name === "_meta.ts") { - // Found a template directory - const templatePath = relativePath || "."; - templates.push({ - name: templatePath.replace(/\\/g, "/"), // normalize path separators - path: templatePath, - metaFile: relPath.replace(/\\/g, "/"), - }); - } - } - } - - scanDirectory(templatesPath); - - return { - generatedAt: new Date().toISOString(), - templates, - }; -} - -bundleRegistryTemplates(); diff --git a/apps/docs/src/app/(home)/page.tsx b/apps/docs/src/app/(home)/page.tsx index c6adc8c4..3c81d125 100644 --- a/apps/docs/src/app/(home)/page.tsx +++ b/apps/docs/src/app/(home)/page.tsx @@ -45,7 +45,7 @@ export default function HomePage() { } title="ProofKit CLI"> - A command line tool to start a new project, or easily apply templates and common patterns with{" "} + A command line tool to start a new project, or manage ProofKit-specific workflows with{" "} no JavaScript experience required. } title={"Typegen"}> diff --git a/apps/docs/src/app/docs/templates/[...slug]/page.tsx b/apps/docs/src/app/docs/templates/[...slug]/page.tsx deleted file mode 100644 index ac4340a1..00000000 --- a/apps/docs/src/app/docs/templates/[...slug]/page.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import type { Metadata } from "next"; -import { notFound } from "next/navigation"; -import { CliCommand } from "@/components/CliCommand"; -import { getAllTemplates, getTemplateByName } from "@/lib/templates"; -import { getCategoryConfig } from "../category-config"; - -interface TemplatePageProps { - params: Promise<{ slug: string[] }>; -} - -export async function generateStaticParams() { - const templates = await getAllTemplates(); - - return templates.map((template) => ({ - slug: template.name.split("/"), - })); -} - -export async function generateMetadata({ params }: TemplatePageProps): Promise { - const { slug } = await params; - const templateName = slug.join("/"); - - const template = await getTemplateByName(templateName); - - if (!template) { - return { - title: "Template Not Found", - }; - } - - return { - title: `${template.title} - ProofKit Templates`, - description: template.description || `Learn about the ${template.title} template for ProofKit applications.`, - }; -} - -export default async function TemplatePage({ params }: TemplatePageProps) { - const { slug } = await params; - const templateName = slug.join("/"); - - const template = await getTemplateByName(templateName); - - if (!template) { - notFound(); - } - - return ( -
- {/* Template header */} -
-
-
- {(() => { - const CategoryIcon = getCategoryConfig(template.category).icon; - return ; - })()} -
-
-

{template.title}

- {template.description &&

{template.description}

} -
-
- -
- - {getCategoryConfig(template.category).name} - - {template.name} -
-
- - {/* Installation command */} -
-

Installation

- -
-
- ); -} diff --git a/apps/docs/src/app/docs/templates/category-config.ts b/apps/docs/src/app/docs/templates/category-config.ts deleted file mode 100644 index aa7e83f8..00000000 --- a/apps/docs/src/app/docs/templates/category-config.ts +++ /dev/null @@ -1,58 +0,0 @@ -import type { TemplateMetadata } from "@proofkit/registry"; -import type { LucideProps } from "lucide-react"; -import { Anchor, File, Mail, Package, Wrench } from "lucide-react"; -import type { ComponentType } from "react"; - -type Category = TemplateMetadata["category"]; - -export interface CategoryConfig { - category: Category; - name: string; - icon: ComponentType; -} - -export const categoryConfigs: CategoryConfig[] = [ - { - category: "component", - name: "Components", - icon: Package, - }, - { - category: "page", - name: "Pages", - icon: File, - }, - { - category: "hook", - name: "Hooks", - icon: Anchor, - }, - { - category: "email", - name: "Emails", - icon: Mail, - }, - { - category: "utility", - name: "Utilities", - icon: Wrench, - }, -]; - -// Create a lookup map for O(1) access -export const categoryConfigMap = categoryConfigs.reduce( - (acc, config) => { - acc[config.category] = config; - return acc; - }, - {} as Record, -); - -// Helper function to get category configuration -export const getCategoryConfig = (category: Category): CategoryConfig => { - const config = categoryConfigMap[category]; - if (!config) { - throw new Error(`Unknown template category: ${category as string}`); - } - return config; -}; diff --git a/apps/docs/src/app/docs/templates/layout.tsx b/apps/docs/src/app/docs/templates/layout.tsx deleted file mode 100644 index 1849a158..00000000 --- a/apps/docs/src/app/docs/templates/layout.tsx +++ /dev/null @@ -1,100 +0,0 @@ -import type * as PageTree from "fumadocs-core/page-tree"; -import { DocsLayout } from "fumadocs-ui/layouts/docs"; -import { getSidebarTabs } from "fumadocs-ui/utils/get-sidebar-tabs"; -import type { ReactNode } from "react"; -import { source } from "@/lib/source"; -import { getTemplatesByCategory } from "@/lib/templates"; -import { baseOptions } from "../../layout.config"; -import { categoryConfigs } from "./category-config"; - -async function buildTemplatesTree() { - const templatesByCategory = await getTemplatesByCategory(); - - const children: PageTree.Root["children"] = [ - { - name: "Overview", - url: "/docs/templates", - type: "page", - }, - ]; - - // Add each category as a separator followed by its templates in the defined order - for (const { category, name } of categoryConfigs) { - const templates = templatesByCategory[category]; - if (!templates || templates.length === 0) { - continue; - } - - // Add category separator - children.push({ - name, - type: "separator", - }); - - // Add all templates in this category - for (const template of templates) { - children.push({ - name: template.title, - url: `/docs${template.path}`, - type: "page", - }); - } - } - - return { - children, - }; -} - -export default async function Layout({ children }: { children: ReactNode }) { - const templatesTree = await buildTemplatesTree(); - - // Find the existing Templates folder in the source tree - const _templatesFolder = source.pageTree.children.find( - (child) => child.type === "folder" && child.name === "Templates", - ); - - // Create a new tree with the Templates folder replaced - const newChildren = source.pageTree.children.map((child) => { - if (child.type === "folder" && child.name === "Templates") { - // Replace the Templates folder with our custom one that includes dynamic templates - return { - ...child, // Preserve the original properties (including icon, root, etc.) - children: templatesTree.children, - }; - } - return child; - }); - - const newTree: PageTree.Root = { - ...source.pageTree, - children: newChildren, - }; - - const tabs = getSidebarTabs(newTree); - - return ( - -

- Made with ❤️ by{" "} - - Proof - -

- - ), - }} - > -
{children}
-
- ); -} diff --git a/apps/docs/src/app/docs/templates/page.tsx b/apps/docs/src/app/docs/templates/page.tsx deleted file mode 100644 index a4ce6a99..00000000 --- a/apps/docs/src/app/docs/templates/page.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import type { Metadata } from "next"; -import { getAllTemplates, getTemplatesByCategory } from "@/lib/templates"; -import { TemplatesPageClient } from "./templates-client"; - -export const metadata: Metadata = { - title: "Templates - ProofKit", - description: "Discover and explore our collection of templates for building FileMaker-powered applications.", -}; - -export default async function TemplatesPage() { - const [templates, templatesByCategory] = await Promise.all([getAllTemplates(), getTemplatesByCategory()]); - - return ( -
-
-

ProofKit Templates

-

- Discover and explore our collection of templates for building FileMaker-powered applications. -

-
- - -
- ); -} diff --git a/apps/docs/src/app/docs/templates/templates-client.tsx b/apps/docs/src/app/docs/templates/templates-client.tsx deleted file mode 100644 index 0b860602..00000000 --- a/apps/docs/src/app/docs/templates/templates-client.tsx +++ /dev/null @@ -1,184 +0,0 @@ -"use client"; - -import type { TemplateMetadata } from "@proofkit/registry"; -import { Package, Search } from "lucide-react"; -import Link from "next/link"; -import { useMemo, useState } from "react"; -import type { TemplateWithPath } from "@/lib/templates"; -import { categoryConfigs, getCategoryConfig } from "./category-config"; - -type Category = TemplateMetadata["category"]; - -interface TemplatesPageClientProps { - templates: TemplateWithPath[]; - templatesByCategory: Record; -} - -export function TemplatesPageClient({ templates, templatesByCategory }: TemplatesPageClientProps) { - const [searchQuery, setSearchQuery] = useState(""); - const [selectedCategory, setSelectedCategory] = useState(null); - - const filteredTemplates = useMemo(() => { - let filtered = templates; - - // Filter by search query - if (searchQuery.trim()) { - const query = searchQuery.toLowerCase(); - filtered = filtered.filter( - (template) => - template.title.toLowerCase().includes(query) || - template.description?.toLowerCase().includes(query) || - template.name.toLowerCase().includes(query) || - template.category.toLowerCase().includes(query), - ); - } - - // Filter by category - if (selectedCategory) { - filtered = filtered.filter((template) => template.category === selectedCategory); - } - - return filtered; - }, [templates, searchQuery, selectedCategory]); - - // Use category configuration order instead of alphabetical sort - const categories = categoryConfigs - .filter((config) => templatesByCategory[config.category]?.length > 0) - .map((config) => config.category); - - return ( -
- {/* Search and filters */} -
- {/* Search */} -
-
- - setSearchQuery(e.target.value)} - placeholder="Search templates..." - type="text" - value={searchQuery} - /> -
-
- - {/* Category filters */} -
- - {categories.map((category) => { - const config = getCategoryConfig(category); - const CategoryIcon = config.icon; - return ( - - ); - })} -
-
- - {/* Main content */} -
- {/* Results header */} -
-

- {filteredTemplates.length} template - {filteredTemplates.length !== 1 ? "s" : ""} found - {selectedCategory && ( - - {" "} - in {getCategoryConfig(selectedCategory).name} - - )} - {searchQuery && ( - - {" "} - matching "{searchQuery}" - - )} -

-
- - {/* Templates grid */} - {filteredTemplates.length > 0 ? ( -
- {filteredTemplates.map((template) => ( - -
-
- {(() => { - const CategoryIcon = getCategoryConfig(template.category).icon; - return ; - })()} -
-
-

- {template.title} -

- {template.description && ( -

{template.description}

- )} -
- - {template.category} - - {template.name} -
-
-
- - ))} -
- ) : ( -
- -

No templates found

-

- {searchQuery || selectedCategory - ? "Try adjusting your search or filter criteria." - : "There are no templates available at the moment."} -

- {(searchQuery || selectedCategory) && ( - - )} -
- )} -
-
- ); -} diff --git a/apps/docs/src/app/llms.txt/route.ts b/apps/docs/src/app/llms.txt/route.ts index 8b208be6..bbe636f1 100644 --- a/apps/docs/src/app/llms.txt/route.ts +++ b/apps/docs/src/app/llms.txt/route.ts @@ -7,7 +7,6 @@ const PACKAGES = [ { name: "cli", desc: "Interactive CLI for scaffolding ProofKit projects" }, { name: "better-auth", desc: "Better Auth adapter for FileMaker" }, { name: "webviewer", desc: "FileMaker WebViewer utilities" }, - { name: "templates", desc: "Project templates and starter kits" }, ] as const; export function GET() { diff --git a/apps/docs/src/app/llms/[package]/route.ts b/apps/docs/src/app/llms/[package]/route.ts index a204c04c..5f9a87fc 100644 --- a/apps/docs/src/app/llms/[package]/route.ts +++ b/apps/docs/src/app/llms/[package]/route.ts @@ -4,14 +4,13 @@ import { source } from "@/lib/source"; export const revalidate = false; -const PACKAGES = ["better-auth", "cli", "fmdapi", "fmodata", "templates", "typegen", "webviewer"] as const; +const PACKAGES = ["better-auth", "cli", "fmdapi", "fmodata", "typegen", "webviewer"] as const; const PACKAGE_DESCRIPTIONS: Record = { "better-auth": "Better Auth adapter for FileMaker authentication", cli: "Interactive CLI for scaffolding ProofKit projects", fmdapi: "FileMaker Data API client (REST)", fmodata: "FileMaker OData API client with Drizzle-like ORM", - templates: "Project templates and starter kits", typegen: "TypeScript type generator from FileMaker layouts", webviewer: "FileMaker WebViewer utilities", }; diff --git a/apps/docs/src/app/r/[[...name]]/registry.ts b/apps/docs/src/app/r/[[...name]]/registry.ts deleted file mode 100644 index af874857..00000000 --- a/apps/docs/src/app/r/[[...name]]/registry.ts +++ /dev/null @@ -1,89 +0,0 @@ -import path from "node:path"; -import type { TemplateMetadata } from "@proofkit/registry"; -import { getComponentMeta, getRegistryIndex, getStaticComponentForShadcn } from "@proofkit/registry"; -import { Hono } from "hono"; -import { createMiddleware } from "hono/factory"; - -// Regex patterns for path manipulation -const JSON_EXTENSION_REGEX = /\.json$/; -const LEADING_SLASH_REGEX = /^\/+/; - -// Path to bundled templates in public directory -const getTemplatesPath = () => { - if (process.env.NODE_ENV === "production") { - // In production, templates are bundled in the public directory - return path.join(process.cwd(), "public/registry-templates"); - } - // In development, read directly from registry package - return path.resolve(process.cwd(), "../../packages/registry/templates"); -}; - -const app = new Hono().basePath("/r"); - -app.get("/", async (c) => { - try { - const templatesPath = getTemplatesPath(); - const index = await getRegistryIndex(templatesPath); - return c.json(index); - } catch (_error) { - return c.json({ error: "Failed to fetch registry index." }, { status: 500 }); - } -}); - -const componentMeta = (basePath: string) => - createMiddleware<{ - Variables: { meta: TemplateMetadata; path: string }; - }>(async (c, next) => { - console.log("c.req.path", c.req.path); - console.log("basePath", basePath); - const componentPath = c.req.path.replace(basePath, "").replace(JSON_EXTENSION_REGEX, ""); - console.log("path", componentPath); - c.set("path", componentPath); - - try { - const templatesPath = getTemplatesPath(); - const meta = await getComponentMeta(componentPath, templatesPath); - c.set("meta", meta); - await next(); - } catch (error) { - console.error(error); - return c.json({ error: "Component not found." }, { status: 404 }); - } - }); - -// Handle meta requests first (more specific route) -app.get("/meta/*", componentMeta("/r/meta"), (c) => { - const meta = c.get("meta"); - return c.json(meta, 200); -}); - -// Handle registry requests at base path "/r" (less specific route) -app.get("/*", componentMeta("/r"), async (c) => { - const componentPath = c.get("path"); - const requestUrl = new URL(c.req.url); - - console.log("requestUrl", requestUrl); - - const routeNameQuery = c.req.query("routeName"); - const routeNameRaw = routeNameQuery ? decodeURIComponent(routeNameQuery) : undefined; - // remove leading slash if present - const routeName = routeNameRaw ? routeNameRaw.replace(LEADING_SLASH_REGEX, "") : undefined; - - try { - const templatesPath = getTemplatesPath(); - const data = await getStaticComponentForShadcn(componentPath, { - routeName, - templatesPath, - }); - - return c.json({ - ...data, - registryDependencies: data.registryDependencies?.map((x: string) => x.replace("{proofkit}", requestUrl.origin)), - }); - } catch (error) { - console.error(error); - return c.json({ error: "Component not found." }, { status: 404 }); - } -}); - -export default app; diff --git a/apps/docs/src/app/r/[[...name]]/route.ts b/apps/docs/src/app/r/[[...name]]/route.ts deleted file mode 100644 index 0d2924c1..00000000 --- a/apps/docs/src/app/r/[[...name]]/route.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { handle } from "hono/vercel"; -import app from "./registry"; - -export const GET = handle(app); diff --git a/apps/docs/src/lib/templates.ts b/apps/docs/src/lib/templates.ts deleted file mode 100644 index af5fe89b..00000000 --- a/apps/docs/src/lib/templates.ts +++ /dev/null @@ -1,95 +0,0 @@ -import path from "node:path"; -import { getRegistryIndex, type TemplateMetadata } from "@proofkit/registry"; - -type Category = TemplateMetadata["category"]; - -export interface TemplateWithPath { - name: string; - title: string; - description?: string; - category: Category; - path: string; -} - -/** - * Get the path to templates based on environment - */ -function getTemplatesPath(): string { - if (process.env.NODE_ENV === "production") { - // In production, templates are bundled in the public directory - return path.join(process.cwd(), "public/registry-templates"); - } - // In development, read directly from registry package - return path.resolve(process.cwd(), "../../packages/registry/templates"); -} - -/** - * Load all templates from the registry at build time - */ -export async function getAllTemplates(): Promise { - try { - const templatesPath = getTemplatesPath(); - const index = await getRegistryIndex(templatesPath); - - return index.map((template) => ({ - ...template, - path: `/templates/${template.name}`, - })); - } catch (error) { - console.error("Failed to load templates:", error); - return []; - } -} - -/** - * Get templates grouped by category - */ -export async function getTemplatesByCategory(): Promise> { - const templates = await getAllTemplates(); - - const grouped = templates.reduce( - (acc, template) => { - const category = template.category; - if (!acc[category]) { - acc[category] = []; - } - acc[category].push(template); - return acc; - }, - {} as Record, - ); - - // Sort templates within each category by title - for (const category of Object.keys(grouped) as Category[]) { - grouped[category].sort((a, b) => a.title.localeCompare(b.title)); - } - - return grouped; -} - -/** - * Get a single template by name - */ -export async function getTemplateByName(name: string): Promise { - const templates = await getAllTemplates(); - return templates.find((template) => template.name === name) || null; -} - -/** - * Search templates by title or description - */ -export function searchTemplates(templates: TemplateWithPath[], query: string): TemplateWithPath[] { - if (!query.trim()) { - return templates; - } - - const lowercaseQuery = query.toLowerCase(); - - return templates.filter( - (template) => - template.title.toLowerCase().includes(lowercaseQuery) || - template.description?.toLowerCase().includes(lowercaseQuery) || - template.name.toLowerCase().includes(lowercaseQuery) || - template.category.toLowerCase().includes(lowercaseQuery), - ); -} diff --git a/apps/docs/tests/smoke.test.ts b/apps/docs/tests/smoke.test.ts new file mode 100644 index 00000000..1cb41062 --- /dev/null +++ b/apps/docs/tests/smoke.test.ts @@ -0,0 +1,7 @@ +import { describe, expect, it } from "vitest"; + +describe("docs", () => { + it("has a smoke test", () => { + expect(true).toBe(true); + }); +}); diff --git a/apps/docs/tests/utils.manifest.test.ts b/apps/docs/tests/utils.manifest.test.ts deleted file mode 100644 index b91cda17..00000000 --- a/apps/docs/tests/utils.manifest.test.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { getRegistryIndex, getStaticComponent, type RegistryItem } from "@proofkit/registry"; -import { describe, expect, it } from "vitest"; - -describe("Registry utils (dynamic scanning)", () => { - it("reads index dynamically", async () => { - const index = await getRegistryIndex(); - expect(Array.isArray(index)).toBe(true); - // Should find the mode-toggle template - expect(index.length).toBeGreaterThan(0); - expect(index[0]).toHaveProperty("name"); - expect(index[0]).toHaveProperty("category"); - expect(index[0]).toHaveProperty("title"); - expect(index[0]).toHaveProperty("description"); - // RegistryIndexItem has name, category, title, description - not type or files - }); - - it("reads a known template (mode-toggle)", async () => { - const comp = await getStaticComponent("components/mode-toggle"); - expect(comp).toHaveProperty("files"); - expect(comp.files).toBeInstanceOf(Array); - if (!comp.files) { - throw new Error("Files is undefined"); - } - expect(comp.files.length).toBeGreaterThan(0); - }); - - it("throws error for non-existent template", async () => { - await expect(getStaticComponent("non-existent")).rejects.toThrow('Template "non-existent" not found'); - }); - - it("passes type check", () => { - // this test doesn't return anything, but it should not throw any TypeScript errors - const _test1: RegistryItem = { - name: "test", - type: "registry:component", - files: [ - { - type: "registry:block", - path: "test.tsx", - content: "test", - target: "~/test.tsx", - }, - ], - }; - - // Note: RegistryItem from shadcn/registry has content and files as optional - const _test2: RegistryItem = { - name: "test", - type: "registry:component", - files: [ - { - type: "registry:block", - path: "test.tsx", - target: "~/test.tsx", - }, - ], - }; - - const _test3: RegistryItem = { - name: "test", - type: "registry:component", - }; - }); -}); diff --git a/apps/docs/tsconfig.json b/apps/docs/tsconfig.json index 6ee9ef73..2fd305dc 100644 --- a/apps/docs/tsconfig.json +++ b/apps/docs/tsconfig.json @@ -34,5 +34,5 @@ ".next/types/**/*.ts", ".next/dev/types/**/*.ts" ], - "exclude": ["node_modules", "public/registry-templates/**/*"] + "exclude": ["node_modules"] } diff --git a/apps/docs/turbo.json b/apps/docs/turbo.json index b9f944cb..a06308ff 100644 --- a/apps/docs/turbo.json +++ b/apps/docs/turbo.json @@ -3,7 +3,7 @@ "extends": ["//"], "tasks": { "build": { - "outputs": [".next/**", "!.next/cache/**", "public/registry-templates/**"] + "outputs": [".next/**", "!.next/cache/**"] } } } diff --git a/packages/cli/package.json b/packages/cli/package.json index a882b05d..7d398127 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -98,7 +98,6 @@ "@planetscale/database": "^1.19.0", "@prisma/adapter-planetscale": "^5.22.0", "@prisma/client": "^5.22.0", - "@proofkit/registry": "workspace:*", "@rollup/plugin-replace": "^6.0.3", "@t3-oss/env-nextjs": "^0.10.1", "@tanstack/react-query": "^5.90.16", diff --git a/packages/cli/src/cli/add/auth.ts b/packages/cli/src/cli/add/auth.ts index b10ed112..a6c7e911 100644 --- a/packages/cli/src/cli/add/auth.ts +++ b/packages/cli/src/cli/add/auth.ts @@ -93,7 +93,7 @@ export const makeAddAuthCommand = () => { .action(async () => { const settings = getSettings(); if (settings.ui === "shadcn") { - throw new Error("Shadcn projects should add auth using the template registry"); + throw new Error("`proofkit add auth` is no longer supported for shadcn projects"); } if (settings.auth.type !== "none") { throw new Error("Auth already exists"); diff --git a/packages/cli/src/cli/add/index.ts b/packages/cli/src/cli/add/index.ts index a505b1e1..19f429e6 100644 --- a/packages/cli/src/cli/add/index.ts +++ b/packages/cli/src/cli/add/index.ts @@ -1,194 +1,12 @@ -import type { RegistryIndex } from "@proofkit/registry"; -import { Command } from "commander"; -import { capitalize, groupBy, uniq } from "es-toolkit"; -import ora from "ora"; -import { select } from "~/cli/prompts.js"; -import { debugOption, nonInteractiveOption } from "~/globalOptions.js"; -import { initProgramState, state } from "~/state.js"; import { logger } from "~/utils/logger.js"; -import { getSettings, type Settings } from "~/utils/parseSettings.js"; -import { runAddReactEmailCommand } from "../react-email.js"; -import { runAddTanstackQueryCommand } from "../tanstack-query.js"; -import { abortIfCancel, ensureProofKitProject } from "../utils.js"; -import { makeAddAddonCommand, runAddAddonAction } from "./addon.js"; -import { makeAddAuthCommand, runAddAuthAction } from "./auth.js"; -import { makeAddDataSourceCommand, runAddDataSourceCommand } from "./data-source/index.js"; -import { makeAddSchemaCommand, runAddSchemaAction } from "./fmschema.js"; -import { makeAddPageCommand, runAddPageAction } from "./page/index.js"; -import { installFromRegistry } from "./registry/install.js"; -import { listItems } from "./registry/listItems.js"; -import { preflightAddCommand } from "./registry/preflight.js"; +import { runAddAddonAction } from "./addon.js"; -const runAddFromRegistry = async (_options?: { noInstall?: boolean }) => { - const settings = getSettings(); - - const spinner = ora("Loading available components...").start(); - let items: RegistryIndex; - try { - items = await listItems(); - } catch (error) { - spinner.fail("Failed to load registry components"); - logger.error(error); - return; - } - - const itemsNotInstalled = items.filter((item) => !settings.registryTemplates.includes(item.name)); - - const groupedByCategory = groupBy(itemsNotInstalled, (item) => item.category); - const categories = uniq(itemsNotInstalled.map((item) => item.category)); - - spinner.succeed(); - - const addType = abortIfCancel( - await select({ - message: "What do you want to add to your project?", - options: [ - // if there are pages available to install, show them first - ...(categories.includes("page") ? [{ label: "Page", value: "page" }] : []), - - // only show schema option if there is at least one data source - ...(settings.dataSources.length > 0 - ? [ - { - label: "Schema", - value: "schema", - hint: "load data from a new table or layout from an existing data source", - }, - ] - : []), - - { - label: "Data Source", - value: "data", - hint: "to connect to a new database or FileMaker file", - }, - - // show the rest of the categories - ...categories - .filter((category) => category !== "page") - .map((category) => ({ - label: capitalize(category), - value: category, - })), - ], - }), - ); - - if (addType === "schema") { - await runAddSchemaAction(); - } else if (addType === "data") { - await runAddDataSourceCommand(); - } else if ((categories as string[]).includes(addType)) { - // one of the categories - const itemsFromCategory = groupedByCategory[addType as keyof typeof groupedByCategory]; - - const itemName = abortIfCancel( - await select({ - message: `Select a ${addType} to add to your project`, - options: itemsFromCategory.map((item) => ({ - label: item.title, - hint: item.description, - value: item.name, - })), - }), - ); - - await installFromRegistry(itemName); - } else { - logger.error(`Could not find any available components in the category "${addType}"`); - } -}; +const ADDON_ONLY_MESSAGE = "Only `proofkit add addon ` is supported."; export const runAdd = async (name: string | undefined, options?: { noInstall?: boolean; target?: string }) => { if (name === "addon") { return await runAddAddonAction(options?.target); } - if (name === "tanstack-query") { - return await runAddTanstackQueryCommand(); - } - if (name !== undefined) { - // an arbitrary name was provided, so we'll try to install from the registry - return await installFromRegistry(name); - } - - let settings: Settings; - try { - settings = getSettings(); - } catch { - await preflightAddCommand(); - return await runAddFromRegistry(options); - } - - if (settings.ui === "shadcn") { - return await runAddFromRegistry(options); - } - ensureProofKitProject({ commandName: "add" }); - - const addType = abortIfCancel( - await select({ - message: "What do you want to add to your project?", - options: [ - { label: "Page", value: "page" }, - // only show schema option if there is at least one data source - ...(settings.dataSources.length > 0 - ? [ - { - label: "Schema", - value: "schema", - hint: "load data from a new table or layout from an existing data source", - }, - ] - : []), - { label: "React Email", value: "react-email" }, - { - label: "Data Source", - value: "data", - hint: "to connect to a new database or FileMaker file", - }, - ...(settings.auth.type === "none" && settings.appType === "browser" ? [{ label: "Auth", value: "auth" }] : []), - ], - }), - ); - - if (addType === "auth") { - await runAddAuthAction(); - } else if (addType === "data") { - await runAddDataSourceCommand(); - } else if (addType === "page") { - await runAddPageAction(); - } else if (addType === "schema") { - await runAddSchemaAction(); - } else if (addType === "react-email") { - await runAddReactEmailCommand({ noInstall: options?.noInstall }); - } -}; - -export const makeAddCommand = () => { - const addCommand = new Command("add") - .description("Add a new component to your project") - .argument("[name]", "Type of component to add") - .addOption(nonInteractiveOption) - .addOption(debugOption) - .option("--noInstall", "Do not run your package manager install command", false) - .action(async (name, options) => { - await runAdd(name, options); - }); - - addCommand.hook("preAction", (_thisCommand, _actionCommand) => { - // console.log("preAction", _actionCommand.opts()); - initProgramState(_actionCommand.opts()); - state.baseCommand = "add"; - }); - addCommand.hook("preSubcommand", (_thisCommand, _subCommand) => { - // console.log("preSubcommand", _subCommand.opts()); - initProgramState(_subCommand.opts()); - state.baseCommand = "add"; - }); - - addCommand.addCommand(makeAddAuthCommand()); - addCommand.addCommand(makeAddAddonCommand()); - addCommand.addCommand(makeAddPageCommand()); - addCommand.addCommand(makeAddSchemaCommand()); - addCommand.addCommand(makeAddDataSourceCommand()); - return addCommand; + logger.error(ADDON_ONLY_MESSAGE); + throw new Error(ADDON_ONLY_MESSAGE); }; diff --git a/packages/cli/src/cli/add/registry/getOptions.ts b/packages/cli/src/cli/add/registry/getOptions.ts deleted file mode 100644 index 9e778b10..00000000 --- a/packages/cli/src/cli/add/registry/getOptions.ts +++ /dev/null @@ -1,44 +0,0 @@ -import path from "node:path"; -import fg from "fast-glob"; -import fs from "fs-extra"; - -import { state } from "~/state.js"; -import { registryFetch } from "./http.js"; - -export async function getMetaFromRegistry(name: string) { - const result = await registryFetch("@get/meta/:name", { - params: { name }, - }); - - if (result.error) { - if (result.error.status === 404) { - return null; - } - throw new Error(result.error.message); - } - - return result.data; -} - -const PROJECT_SHARED_IGNORE = ["**/node_modules/**", ".next", "public", "dist", "build"]; - -export async function getProjectInfo() { - const cwd = state.projectDir || process.cwd(); - const [configFiles, isSrcDir] = await Promise.all([ - fg.glob("**/{next,vite,astro,app}.config.*|gatsby-config.*|composer.json|react-router.config.*", { - cwd, - deep: 3, - ignore: PROJECT_SHARED_IGNORE, - }), - fs.pathExists(path.resolve(cwd, "src")), - ]); - - const isUsingAppDir = await fs.pathExists(path.resolve(cwd, `${isSrcDir ? "src/" : ""}app`)); - - // Next.js. - if (configFiles.find((file) => file.startsWith("next.config."))?.length) { - return isUsingAppDir ? "next-app" : "next-pages"; - } - - return "manual"; -} diff --git a/packages/cli/src/cli/add/registry/http.ts b/packages/cli/src/cli/add/registry/http.ts deleted file mode 100644 index 5625d73b..00000000 --- a/packages/cli/src/cli/add/registry/http.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { createFetch, createSchema } from "@better-fetch/fetch"; -import { registryIndexSchema, templateMetadataSchema } from "@proofkit/registry"; - -import { getRegistryUrl } from "~/helpers/shadcn-cli.js"; - -const schema = createSchema({ - "@get/meta/:name": { - output: templateMetadataSchema, - }, - "@get/": { - output: registryIndexSchema, - }, -}); - -export const registryFetch = createFetch({ - baseURL: `${getRegistryUrl()}/r`, - schema, -}); diff --git a/packages/cli/src/cli/add/registry/install.ts b/packages/cli/src/cli/add/registry/install.ts deleted file mode 100644 index 9d7a2aef..00000000 --- a/packages/cli/src/cli/add/registry/install.ts +++ /dev/null @@ -1,223 +0,0 @@ -import { getOtherProofKitDependencies } from "@proofkit/registry"; -import { capitalize, uniq } from "es-toolkit"; -import ora from "ora"; -import semver from "semver"; -import * as p from "~/cli/prompts.js"; - -import { abortIfCancel } from "~/cli/utils.js"; -import { getExistingSchemas } from "~/generators/fmdapi.js"; -import { addRouteToNav } from "~/generators/route.js"; -import { getRegistryUrl, shadcnInstall } from "~/helpers/shadcn-cli.js"; -import { state } from "~/state.js"; -import { getVersion } from "~/utils/getProofKitVersion.js"; -import { logger } from "~/utils/logger.js"; -import { type DataSource, getSettings, mergeSettings } from "~/utils/parseSettings.js"; -import { getMetaFromRegistry } from "./getOptions.js"; -import { buildHandlebarsData, randerHandlebarsToFile } from "./postInstall/handlebars.js"; -import { processPostInstallStep } from "./postInstall/index.js"; -import { preflightAddCommand } from "./preflight.js"; - -async function promptForSchemaFromDataSource({ - projectDir = process.cwd(), - dataSource, -}: { - projectDir?: string; - dataSource: DataSource; -}) { - if (dataSource.type === "supabase") { - throw new Error("Not implemented"); - } - const schemas = getExistingSchemas({ - projectDir, - dataSourceName: dataSource.name, - }) - .map((s) => s.schemaName) - .filter((schemaName): schemaName is string => Boolean(schemaName)); - - if (schemas.length === 0) { - p.cancel("This data source doesn't have any schemas to load data from"); - return undefined; - } - - if (schemas.length === 1) { - return schemas[0]; - } - - const schemaName = abortIfCancel( - await p.select({ - message: "Which schema should this template use?", - options: schemas.map((schema) => ({ label: schema, value: schema })), - }), - ); - return schemaName; -} - -export async function installFromRegistry(name: string) { - const spinner = ora("Validating template").start(); - - try { - await preflightAddCommand(); - const meta = await getMetaFromRegistry(name); - if (!meta) { - spinner.fail(`Template ${name} not found in the ProofKit registry`); - return; - } - - if (meta.minimumProofKitVersion && semver.gt(meta.minimumProofKitVersion, getVersion())) { - logger.error( - `Template ${name} requires ProofKit version ${meta.minimumProofKitVersion}, but you are using version ${getVersion()}`, - ); - spinner.fail("Template is not compatible with your ProofKit version"); - return; - } - spinner.succeed(); - - const otherProofKitDependencies = getOtherProofKitDependencies(meta); - let previouslyInstalledTemplates = getSettings().registryTemplates; - - // Handle schema requirement if template needs it - let dataSource: DataSource | undefined; - let schemaName: string | undefined; - let routeName: string | undefined; - let pageName: string | undefined; - - if (meta.schemaRequired) { - const settings = getSettings(); - - if (settings.dataSources.length === 0) { - spinner.fail("This template requires a data source, but you don't have any. Add a data source first."); - return; - } - - const dataSourceName = - settings.dataSources.length > 1 - ? abortIfCancel( - await p.select({ - message: "Which data source should be used for this template?", - options: settings.dataSources.map((ds) => ({ - value: ds.name, - label: ds.name, - })), - }), - ) - : settings.dataSources[0]?.name; - - dataSource = settings.dataSources.find((ds) => ds.name === dataSourceName); - - if (!dataSource) { - spinner.fail(`Data source ${dataSourceName} not found`); - return; - } - - schemaName = await promptForSchemaFromDataSource({ - projectDir: state.projectDir, - dataSource, - }); - - if (!schemaName) { - spinner.fail("Schema selection was cancelled"); - return; - } - } - - if (meta.category === "page") { - // Prompt user for the URL path of the page - routeName = abortIfCancel( - await p.text({ - message: "Enter the URL PATH for your new page", - validate: (value) => { - if (value.length === 0) { - return "URL path is required"; - } - return; - }, - }), - ); - - if (routeName.startsWith("/")) { - routeName = routeName.slice(1); - } - - pageName = capitalize(routeName.replace("/", "").trim()); - } - - const url = new URL(`${getRegistryUrl()}/r/${name}`); - if (meta.category === "page") { - url.searchParams.set("routeName", `/(main)/${routeName ?? name}`); - } - - // a (hopefully) temporary workaround because the shadcn command installs the env file in the wrong place if it's a dependency - if ( - name === "fmdapi" && - !previouslyInstalledTemplates.includes("utils/t3-env") && - // this last guard will allow this workaroudn to be bypassed if the registry server updates to start serving the dependency again - meta.registryDependencies?.find((d) => d.includes("utils/t3-env")) === undefined - ) { - // install the t3-env template manually first - await installFromRegistry("utils/t3-env"); - previouslyInstalledTemplates = getSettings().registryTemplates; - } - - // now install the template using shadcn-install - await shadcnInstall([url.toString()], meta.title); - - const handlebarsFiles = meta.files.filter((file) => file.handlebars); - - if (handlebarsFiles.length > 0) { - // Build template data with schema information if available - const baseTemplateData = - dataSource && schemaName - ? buildHandlebarsData({ - dataSource, - schemaName, - }) - : buildHandlebarsData(); - - // Add page information to template data if available - const templateData = { - ...baseTemplateData, - ...(routeName && { routeName }), - ...(pageName && { pageName }), - }; - - // Resolve __PATH__ placeholders in file paths before handlebars processing - const resolvedFiles = handlebarsFiles.map((file) => ({ - ...file, - destinationPath: file.destinationPath?.replace("__PATH__", `/(main)/${routeName ?? name}`), - })); - - for (const file of resolvedFiles) { - await randerHandlebarsToFile(file, templateData); - } - } - - // Add route to navigation if this is a page template - if (meta.category === "page" && routeName && pageName) { - await addRouteToNav({ - projectDir: state.projectDir, - navType: "primary", - label: pageName, - href: `/${routeName}`, - }); - } - - // if post-install steps, process those - if (meta.postInstall) { - for (const step of meta.postInstall) { - if (step._from && previouslyInstalledTemplates.includes(step._from)) { - // don't re-run post-install steps for templates that have already been installed - continue; - } - await processPostInstallStep(step); - } - } - - // update the settings - mergeSettings({ - registryTemplates: uniq([...previouslyInstalledTemplates, name, ...otherProofKitDependencies]), - }); - } catch (error) { - spinner.fail("Failed to fetch template metadata."); - logger.error(error); - } -} diff --git a/packages/cli/src/cli/add/registry/listItems.ts b/packages/cli/src/cli/add/registry/listItems.ts deleted file mode 100644 index 046f5c73..00000000 --- a/packages/cli/src/cli/add/registry/listItems.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { registryFetch } from "./http.js"; - -export async function listItems() { - const { data: items, error } = await registryFetch("@get/"); - if (error) { - throw new Error(`Failed to fetch items from registry: ${error.message}`); - } - return items; -} diff --git a/packages/cli/src/cli/add/registry/postInstall/handlebars.ts b/packages/cli/src/cli/add/registry/postInstall/handlebars.ts deleted file mode 100644 index 2ef0b79c..00000000 --- a/packages/cli/src/cli/add/registry/postInstall/handlebars.ts +++ /dev/null @@ -1,189 +0,0 @@ -import path from "node:path"; -import { decodeHandlebarsFromShadcn, type TemplateFile } from "@proofkit/registry"; -import fs from "fs-extra"; -import handlebars from "handlebars"; -import { getClientSuffix, getFieldNamesForSchema } from "~/generators/fmdapi.js"; -import { getShadcnConfig } from "~/helpers/shadcn-cli.js"; -import { state } from "~/state.js"; -import { type DataSource, getSettings } from "~/utils/parseSettings.js"; - -// Register handlebars helpers -handlebars.registerHelper("eq", (a, b) => a === b); - -interface HandlebarsContext { - [key: string]: unknown; -} - -handlebars.registerHelper("findFirst", function (this: HandlebarsContext, array, predicate, options) { - if (!(array && Array.isArray(array))) { - return options.inverse(this); - } - - for (const item of array) { - if (predicate === "fm" && item.type === "fm") { - return options.fn(item); - } - } - return options.inverse(this); -}); - -interface DataSourceForTemplate { - dataSource: DataSource; - schemaName: string; -} - -const commonFieldNamesToExclude = [ - "id", - "pk", - "createdat", - "updatedat", - "primarykey", - "createdby", - "modifiedby", - "creationtimestamp", - "modificationtimestamp", -]; - -function filterOutCommonFieldNames(fieldNames: string[]): string[] { - return fieldNames.filter( - (fieldName) => !commonFieldNamesToExclude.includes(fieldName.toLowerCase()) || fieldName.startsWith("_"), - ); -} - -function buildDataSourceData(args: DataSourceForTemplate) { - const { dataSource, schemaName } = args; - - const clientSuffix = getClientSuffix({ - projectDir: state.projectDir ?? process.cwd(), - dataSourceName: dataSource.name, - }); - - const allFieldNames = getFieldNamesForSchema({ - schemaName, - dataSourceName: dataSource.name, - }).filter(Boolean) as string[]; - - return { - sourceName: dataSource.name, - schemaName, - clientSuffix, - allFieldNames, - fieldNames: filterOutCommonFieldNames(allFieldNames), - }; -} - -export function buildHandlebarsData(args?: DataSourceForTemplate) { - const proofkit = getSettings(); - const shadcn = getShadcnConfig(); - - return { - proofkit, - shadcn, - schema: args - ? buildDataSourceData(args) - : { - sourceName: "UnknownDataSource", - schemaName: "UnknownSchema", - clientSuffix: "UnknownClientSuffix", - allFieldNames: ["UnknownFieldName"], - fieldNames: ["UnknownFieldName"], - }, - }; -} - -export async function randerHandlebarsToFile(file: TemplateFile, data: ReturnType) { - const inputPath = getFilePath(file, data); - let rawTemplate = await fs.readFile(inputPath, "utf8"); - - // Decode placeholder tokens back to handlebars syntax - // This uses the centralized decoding function from the registry package - rawTemplate = decodeHandlebarsFromShadcn(rawTemplate); - - const template = handlebars.compile(rawTemplate); - const rendered = template(data); - await fs.writeFile(inputPath, rendered); -} - -export function getFilePath(file: TemplateFile, data: ReturnType): string { - const thePath = file.sourceFileName; - - if (file.destinationPath) { - return file.destinationPath; - } - - const cwd = state.projectDir ?? process.cwd(); - const { shadcn } = data; - - // Create a mapping between registry types and their corresponding shadcn config aliases - let blockAlias = "src/components/blocks"; - if (shadcn?.aliases?.components) { - if (shadcn.aliases.components.startsWith("@/")) { - blockAlias = `${shadcn.aliases.components.replace("@/", "src/")}/blocks`; - } else { - blockAlias = `src/${shadcn.aliases.components}/blocks`; - } - } - - const typeToAliasMap: Record = { - "registry:lib": shadcn?.aliases?.lib || shadcn?.aliases?.utils, - "registry:component": shadcn?.aliases?.components, - "registry:ui": shadcn?.aliases?.ui || shadcn?.aliases?.components, - "registry:hook": shadcn?.aliases?.hooks, - // These types don't have direct aliases, so we use fallback paths - "registry:file": "src", - "registry:page": "src/app", - "registry:block": blockAlias, - "registry:theme": "src/theme", - "registry:style": "src/styles", - }; - - const aliasPath = typeToAliasMap[file.type]; - - if (aliasPath) { - // Handle @/ prefix which represents the src directory - if (aliasPath.startsWith("@/")) { - const resolvedPath = aliasPath.replace("@/", "src/"); - return path.join(cwd, resolvedPath, thePath); - } - // If the alias starts with a path separator or contains src/, treat it as a relative path from cwd - if (aliasPath.startsWith("/") || aliasPath.includes("src/")) { - return path.join(cwd, aliasPath, thePath); - } - // Otherwise, treat it as an alias that should be resolved relative to src/ - - return path.join(cwd, "src", aliasPath, thePath); - } - - // Fallback to hardcoded paths for unsupported types - switch (file.type) { - case "registry:lib": - return path.join(cwd, "src", "lib", thePath); - case "registry:file": - return path.join(cwd, "src", thePath); - case "registry:page": { - // For page templates, use the route name if available in template data - const routeName = "routeName" in data ? (data.routeName as string) : undefined; - if (routeName) { - // Add /(main) prefix for Next.js app router structure - const pageRoute = routeName === "/" ? "" : routeName; - return path.join(cwd, "src", "app", "(main)", pageRoute, thePath); - } - return path.join(cwd, "src", "app", thePath); - } - case "registry:block": - return path.join(cwd, "src", "components", "blocks", thePath); - case "registry:component": - return path.join(cwd, "src", "components", thePath); - case "registry:ui": - return path.join(cwd, "src", "components", thePath); - case "registry:hook": - return path.join(cwd, "src", "hooks", thePath); - case "registry:theme": - return path.join(cwd, "src", "theme", thePath); - case "registry:style": - return path.join(cwd, "src", "styles", thePath); - default: - // default to source file name - return thePath; - } -} diff --git a/packages/cli/src/cli/add/registry/postInstall/index.ts b/packages/cli/src/cli/add/registry/postInstall/index.ts deleted file mode 100644 index 6afb4233..00000000 --- a/packages/cli/src/cli/add/registry/postInstall/index.ts +++ /dev/null @@ -1,22 +0,0 @@ -import type { PostInstallStep } from "@proofkit/registry"; - -import { addToEnv } from "~/utils/addToEnvs.js"; -import { logger } from "~/utils/logger.js"; -import { addScriptToPackageJson } from "./package-script.js"; -import { wrapProvider } from "./wrap-provider.js"; - -export async function processPostInstallStep(step: PostInstallStep) { - if (step.action === "package.json script") { - addScriptToPackageJson(step); - } else if (step.action === "wrap provider") { - await wrapProvider(step); - } else if (step.action === "next-steps") { - logger.info(step.data.message); - } else if (step.action === "env") { - await addToEnv({ - envs: step.data.envs, - }); - } else { - logger.error(`Unknown post-install step: ${step}`); - } -} diff --git a/packages/cli/src/cli/add/registry/postInstall/package-script.ts b/packages/cli/src/cli/add/registry/postInstall/package-script.ts deleted file mode 100644 index 50df220c..00000000 --- a/packages/cli/src/cli/add/registry/postInstall/package-script.ts +++ /dev/null @@ -1,12 +0,0 @@ -import fs from "node:fs"; -import path from "node:path"; -import type { PostInstallStep } from "@proofkit/registry"; - -import { state } from "~/state.js"; - -export function addScriptToPackageJson(step: Extract) { - const packageJsonPath = path.join(state.projectDir, "package.json"); - const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8")); - packageJson.scripts[step.data.scriptName] = step.data.scriptCommand; - fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2)); -} diff --git a/packages/cli/src/cli/add/registry/postInstall/wrap-provider.ts b/packages/cli/src/cli/add/registry/postInstall/wrap-provider.ts deleted file mode 100644 index dd1ec34e..00000000 --- a/packages/cli/src/cli/add/registry/postInstall/wrap-provider.ts +++ /dev/null @@ -1,132 +0,0 @@ -import path from "node:path"; -import type { PostInstallStep } from "@proofkit/registry"; -import { type ImportDeclarationStructure, type JsxChild, type JsxElement, StructureKind, SyntaxKind } from "ts-morph"; - -import { getShadcnConfig } from "~/helpers/shadcn-cli.js"; -import { state } from "~/state.js"; -import { logger } from "~/utils/logger.js"; -import { formatAndSaveSourceFiles, getNewProject } from "~/utils/ts-morph.js"; - -export async function wrapProvider(step: Extract) { - const { parentTag, imports: importConfigs, providerCloseTag, providerOpenTag } = step.data; - - try { - const projectDir = state.projectDir; - const project = getNewProject(projectDir); - const shadcnConfig = getShadcnConfig(); - - // Resolve the components alias to a filesystem path - // @/components -> src/components, ./components -> components, etc. - const resolveAlias = (alias: string): string => { - if (alias.startsWith("@/")) { - return alias.replace("@/", "src/"); - } - if (alias.startsWith("./")) { - return alias.substring(2); - } - return alias; - }; - - // Look for providers.tsx in the components directory - const componentsDir = resolveAlias(shadcnConfig.aliases.components); - const providersPath = path.join(projectDir, componentsDir, "providers.tsx"); - - const providersFile = project.addSourceFileAtPath(providersPath); - - // Add all import statements - for (const importConfig of importConfigs) { - const importDeclaration: ImportDeclarationStructure = { - moduleSpecifier: importConfig.moduleSpecifier, - kind: StructureKind.ImportDeclaration, - }; - - if (importConfig.defaultImport) { - importDeclaration.defaultImport = importConfig.defaultImport; - } - - if (importConfig.namedImports && importConfig.namedImports.length > 0) { - importDeclaration.namedImports = importConfig.namedImports; - } - - providersFile.addImportDeclaration(importDeclaration); - } - - // Handle providers.tsx file - look for the default export function - const exportDefault = providersFile.getFunction((dec) => dec.isDefaultExport()); - - if (!exportDefault) { - logger.warn(`No default export function found in ${providersPath}`); - return; - } - - const returnStatement = exportDefault?.getBody()?.getFirstDescendantByKind(SyntaxKind.ReturnStatement); - - if (!returnStatement) { - logger.warn("No return statement found in default export function"); - return; - } - - let targetElement: JsxElement | undefined; - - // Try to find the parent tag if specified - if (parentTag && parentTag.length > 0) { - for (const tag of parentTag) { - targetElement = returnStatement - ?.getDescendantsOfKind(SyntaxKind.JsxOpeningElement) - .find((openingElement) => openingElement.getTagNameNode().getText() === tag) - ?.getParentIfKind(SyntaxKind.JsxElement); - - if (targetElement) { - break; - } - } - } - - if (targetElement) { - // If we found a parent tag, wrap its children - const childrenText = targetElement - ?.getJsxChildren() - .map((child: JsxChild) => child.getText()) - .filter(Boolean) - .join("\n"); - - const newContent = `${providerOpenTag} - ${childrenText} - ${providerCloseTag}`; - - targetElement.getChildSyntaxList()?.replaceWithText(newContent); - } else { - // If no parent tag found or specified, wrap the entire return statement - const returnExpression = returnStatement?.getExpression(); - if (returnExpression) { - // Check if the expression is a ParenthesizedExpression - const isParenthesized = returnExpression.getKind() === SyntaxKind.ParenthesizedExpression; - - let innerExpressionText: string; - if (isParenthesized) { - // Get the inner expression from the parenthesized expression - const parenthesizedExpr = returnExpression.asKindOrThrow(SyntaxKind.ParenthesizedExpression); - innerExpressionText = parenthesizedExpr.getExpression().getText(); - } else { - innerExpressionText = returnExpression.getText(); - } - - const newReturnContent = `return ( - ${providerOpenTag} - ${innerExpressionText} - ${providerCloseTag} - );`; - - returnStatement?.replaceWithText(newReturnContent); - } else { - logger.warn("No return expression found to wrap"); - } - } - - await formatAndSaveSourceFiles(project); - logger.success(`Successfully wrapped provider in ${providersPath}`); - } catch (error) { - logger.error(`Failed to wrap provider: ${error}`); - throw error; - } -} diff --git a/packages/cli/src/cli/add/registry/preflight.ts b/packages/cli/src/cli/add/registry/preflight.ts deleted file mode 100644 index a7e973f0..00000000 --- a/packages/cli/src/cli/add/registry/preflight.ts +++ /dev/null @@ -1,17 +0,0 @@ -import path from "node:path"; -import fs from "fs-extra"; - -import { stealthInit } from "~/helpers/stealth-init.js"; -import { state } from "~/state.js"; - -export async function preflightAddCommand() { - const cwd = state.projectDir ?? process.cwd(); - // make sure shadcn is installed, throw if not - const shadcnInstalled = await fs.pathExists(path.join(cwd, "components.json")); - if (!shadcnInstalled) { - throw new Error("Shadcn is not installed. Please run `pnpm dlx shadcn@latest init` to install it."); - } - - // if proofkit is not inited, try to stealth init - await stealthInit(); -} diff --git a/packages/cli/src/consts.ts b/packages/cli/src/consts.ts index 306c005c..6dfe55c9 100644 --- a/packages/cli/src/consts.ts +++ b/packages/cli/src/consts.ts @@ -15,11 +15,6 @@ export const AGENT_INSTRUCTIONS = [ "Use the ProofKit docs as the primary reference for this project: https://proofkit.dev/docs", "Before doing any AI-assisted development here, run `npx @tanstack/intent@latest install` in the project root to load skills relevant to this project", ].join("\n"); - -// Registry URL is injected at build time via tsdown define. -declare const __REGISTRY_URL__: string; -export const DEFAULT_REGISTRY_URL = - typeof __REGISTRY_URL__ !== "undefined" && __REGISTRY_URL__ ? __REGISTRY_URL__ : "https://proofkit.dev"; const TITLE_ASCII = ` _______ ___ ___ ____ _ _ |_ __ \\ .' ..]|_ ||_ _| (_) / |_ diff --git a/packages/cli/src/generators/auth.ts b/packages/cli/src/generators/auth.ts index 3ecd4080..7c366c9f 100644 --- a/packages/cli/src/generators/auth.ts +++ b/packages/cli/src/generators/auth.ts @@ -27,7 +27,7 @@ export async function addAuth({ }) { const settings = getSettings(); if (settings.ui === "shadcn") { - throw new Error("Shadcn projects should add auth using the template registry"); + throw new Error("`proofkit add auth` is no longer supported for shadcn projects"); } if (settings.auth.type !== "none") { throw new Error("Auth already exists"); diff --git a/packages/cli/src/helpers/shadcn-cli.ts b/packages/cli/src/helpers/shadcn-cli.ts deleted file mode 100644 index 4c235380..00000000 --- a/packages/cli/src/helpers/shadcn-cli.ts +++ /dev/null @@ -1,80 +0,0 @@ -import fs from "node:fs"; -import path from "node:path"; -import { execa } from "execa"; - -import { DEFAULT_REGISTRY_URL } from "~/consts.js"; -import { state } from "~/state.js"; -import { logger } from "~/utils/logger.js"; -import { getSettings } from "~/utils/parseSettings.js"; - -export async function shadcnInstall(components: string | string[], _friendlyComponentName?: string) { - const componentsArray = Array.isArray(components) ? components : [components]; - const command = ["shadcn@latest", "add", ...componentsArray]; - // Use execa to run the shadcn add command directly - - try { - await execa("pnpm", ["dlx", ...command], { - stdio: "inherit", - cwd: state.projectDir ?? process.cwd(), - }); - } catch (error) { - logger.error(`Failed to run shadcn add: ${error}`); - throw error; - } -} - -export function getRegistryUrl(): string { - let url: string; - try { - url = getSettings().registryUrl ?? DEFAULT_REGISTRY_URL; - } catch { - // If we can't get settings (e.g., during development or outside a ProofKit project), - // fall back to the default registry URL - url = DEFAULT_REGISTRY_URL; - } - return url.endsWith("/") ? url.slice(0, -1) : url; -} - -export interface ShadcnConfig { - style: "default" | "new-york"; - tailwind: { - config: string; - css: string; - baseColor: string; - cssVariables: boolean; - prefix?: string; - [k: string]: unknown; - }; - rsc: boolean; - tsx?: boolean; - iconLibrary?: string; - aliases: { - utils: string; - components: string; - ui?: string; - lib?: string; - hooks?: string; - [k: string]: unknown; - }; - registries?: { - [k: string]: - | string - | { - url: string; - params?: { - [k: string]: string; - }; - headers?: { - [k: string]: string; - }; - [k: string]: unknown; - }; - }; - [k: string]: unknown; -} - -export function getShadcnConfig() { - const componentsJsonPath = path.join(state.projectDir, "components.json"); - const componentsJson = JSON.parse(fs.readFileSync(componentsJsonPath, "utf8")); - return componentsJson as ShadcnConfig; -} diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index a526696a..6d9c265c 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -207,8 +207,8 @@ function makeAddCommand() { return makeCommand( "add", { - name: optionalArg(textArg({ name: "name" })).pipe(withArgDescription("Component or registry item to add")), - target: optionalArg(textArg({ name: "target" })).pipe(withArgDescription("Optional add target")), + name: optionalArg(textArg({ name: "name" })).pipe(withArgDescription("Supported add target, currently `addon`")), + target: optionalArg(textArg({ name: "target" })).pipe(withArgDescription("Add-on target")), noInstall: booleanOption("no-install").pipe(withOptionDescription("Skip package installation")), CI: booleanOption("ci").pipe(withOptionDescription("Deprecated alias for --non-interactive")), nonInteractive: booleanOption("non-interactive").pipe( @@ -235,7 +235,7 @@ function makeAddCommand() { }, { nonInteractive: CI || nonInteractive, debug }, ), - ).pipe(withCommandDescription("Legacy command. Prefer package-native tools, agents, or shadcn.")); + ).pipe(withCommandDescription("Add a supported ProofKit add-on.")); } function makeRemoveCommand() { diff --git a/packages/cli/src/installers/envVars.ts b/packages/cli/src/installers/envVars.ts index 2eb95da9..ebcd8cd9 100644 --- a/packages/cli/src/installers/envVars.ts +++ b/packages/cli/src/installers/envVars.ts @@ -38,6 +38,6 @@ export function findT3EnvFile(throwIfNotFound?: boolean): string | null { return null; } - logger.warn(`Could not find T3 env files. Run "proofkit add utils/t3-env" to initialize them.`); + logger.warn("Could not find T3 env files. Initialize them manually before continuing."); throw new Error("T3 env file not found"); } diff --git a/packages/cli/tests/cli.test.ts b/packages/cli/tests/cli.test.ts index b655984f..efd4870f 100644 --- a/packages/cli/tests/cli.test.ts +++ b/packages/cli/tests/cli.test.ts @@ -152,4 +152,15 @@ describe("proofkit CLI", () => { expect(await fs.pathExists(path.join(addonModulesDir, "ProofKitWV"))).toBe(true); }); + + it("rejects unsupported add targets", () => { + const result = spawnSync("node", [distEntry, "add", "page"], { + cwd: packageDir, + stdio: "pipe", + encoding: "utf8", + }); + + expect(result.status).not.toBe(0); + expect(`${result.stdout}\n${result.stderr}`).toContain("Only `proofkit add addon ` is supported."); + }); }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4bd2047f..d50af1ef 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -63,9 +63,6 @@ importers: '@base-ui-components/react': specifier: 1.0.0-rc.0 version: 1.0.0-rc.0(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) - '@proofkit/registry': - specifier: workspace:* - version: link:../../packages/registry '@proofkit/typegen': specifier: workspace:* version: link:../../packages/typegen @@ -384,9 +381,6 @@ importers: '@prisma/client': specifier: ^5.22.0 version: 5.22.0(prisma@5.22.0) - '@proofkit/registry': - specifier: workspace:* - version: link:../registry '@rollup/plugin-replace': specifier: ^6.0.3 version: 6.0.3(rollup@4.55.1) @@ -1524,23 +1518,23 @@ packages: '@effect/rpc': ^0.74.0 effect: ^3.20.0 + '@emnapi/core@1.10.0': + resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} + '@emnapi/core@1.8.1': resolution: {integrity: sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==} - '@emnapi/core@1.9.1': - resolution: {integrity: sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA==} + '@emnapi/runtime@1.10.0': + resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} '@emnapi/runtime@1.8.1': resolution: {integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==} - '@emnapi/runtime@1.9.1': - resolution: {integrity: sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==} - '@emnapi/wasi-threads@1.1.0': resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} - '@emnapi/wasi-threads@1.2.0': - resolution: {integrity: sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==} + '@emnapi/wasi-threads@1.2.1': + resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} '@esbuild-kit/core-utils@3.3.2': resolution: {integrity: sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==} @@ -2706,8 +2700,8 @@ packages: '@napi-rs/wasm-runtime@1.1.1': resolution: {integrity: sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==} - '@napi-rs/wasm-runtime@1.1.2': - resolution: {integrity: sha512-sNXv5oLJ7ob93xkZ1XnxisYhGYXfaG9f65/ZgYuAu3qt7b3NadcOEhLvx28hv31PgX8SZJRYrAIPQilQmFpLVw==} + '@napi-rs/wasm-runtime@1.1.4': + resolution: {integrity: sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==} peerDependencies: '@emnapi/core': ^1.7.1 '@emnapi/runtime': ^1.7.1 @@ -2799,8 +2793,8 @@ packages: resolution: {integrity: sha512-a61ljmRVVyG5MC/698C8/FfFDw5a8LOIvyOLW5fztgUXqUpc1jOfQzOitSCbge657OgXXThmY3Tk8fpiDb4UcA==} engines: {node: '>= 20.0.0'} - '@oxc-project/types@0.123.0': - resolution: {integrity: sha512-YtECP/y8Mj1lSHiUWGSRzy/C6teUKlS87dEfuVKT09LgQbUsBW1rNg+MiJ4buGu3yuADV60gbIvo9/HplA56Ew==} + '@oxc-project/types@0.127.0': + resolution: {integrity: sha512-aIYXQBo4lCbO4z0R3FHeucQHpF46l2LbMdxRvqvuRuW2OxdnSkcng5B8+K12spgLDj93rtN3+J2Vac/TIO+ciQ==} '@oxc-resolver/binding-android-arm-eabi@11.16.2': resolution: {integrity: sha512-lVJbvydLQIDZHKUb6Zs9Rq80QVTQ9xdCQE30eC9/cjg4wsMoEOg65QZPymUAIVJotpUAWJD0XYcwE7ugfxx5kQ==} @@ -3803,91 +3797,91 @@ packages: peerDependencies: react: '>=18.2.0' - '@rolldown/binding-android-arm64@1.0.0-rc.13': - resolution: {integrity: sha512-5ZiiecKH2DXAVJTNN13gNMUcCDg4Jy8ZjbXEsPnqa248wgOVeYRX0iqXXD5Jz4bI9BFHgKsI2qmyJynstbmr+g==} + '@rolldown/binding-android-arm64@1.0.0-rc.17': + resolution: {integrity: sha512-s70pVGhw4zqGeFnXWvAzJDlvxhlRollagdCCKRgOsgUOH3N1l0LIxf83AtGzmb5SiVM4Hjl5HyarMRfdfj3DaQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@rolldown/binding-darwin-arm64@1.0.0-rc.13': - resolution: {integrity: sha512-tz/v/8G77seu8zAB3A5sK3UFoOl06zcshEzhUO62sAEtrEuW/H1CcyoupOrD+NbQJytYgA4CppXPzlrmp4JZKA==} + '@rolldown/binding-darwin-arm64@1.0.0-rc.17': + resolution: {integrity: sha512-4ksWc9n0mhlZpZ9PMZgTGjeOPRu8MB1Z3Tz0Mo02eWfWCHMW1zN82Qz/pL/rC+yQa+8ZnutMF0JjJe7PjwasYw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-x64@1.0.0-rc.13': - resolution: {integrity: sha512-8DakphqOz8JrMYWTJmWA+vDJxut6LijZ8Xcdc4flOlAhU7PNVwo2MaWBF9iXjJAPo5rC/IxEFZDhJ3GC7NHvug==} + '@rolldown/binding-darwin-x64@1.0.0-rc.17': + resolution: {integrity: sha512-SUSDOI6WwUVNcWxd02QEBjLdY1VPHvlEkw6T/8nYG322iYWCTxRb1vzk4E+mWWYehTp7ERibq54LSJGjmouOsw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@rolldown/binding-freebsd-x64@1.0.0-rc.13': - resolution: {integrity: sha512-4wBQFfjDuXYN/SVI8inBF3Aa+isq40rc6VMFbk5jcpolUBTe5cYnMsHZ51nFWsx3PVyyNN3vgoESki0Hmr/4BA==} + '@rolldown/binding-freebsd-x64@1.0.0-rc.17': + resolution: {integrity: sha512-hwnz3nw9dbJ05EDO/PvcjaaewqqDy7Y1rn1UO81l8iIK1GjenME75dl16ajbvSSMfv66WXSRCYKIqfgq2KCfxw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.13': - resolution: {integrity: sha512-JW/e4yPIXLms+jmnbwwy5LA/LxVwZUWLN8xug+V200wzaVi5TEGIWQlh8o91gWYFxW609euI98OCCemmWGuPrw==} + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.17': + resolution: {integrity: sha512-IS+W7epTcwANmFSQFrS1SivEXHtl1JtuQA9wlxrZTcNi6mx+FDOYrakGevvvTwgj2JvWiK8B29/qD9BELZPyXQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.13': - resolution: {integrity: sha512-ZfKWpXiUymDnavepCaM6KG/uGydJ4l2nBmMxg60Ci4CbeefpqjPWpfaZM7PThOhk2dssqBAcwLc6rAyr0uTdXg==} + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.17': + resolution: {integrity: sha512-e6usGaHKW5BMNZOymS1UcEYGowQMWcgZ71Z17Sl/h2+ZziNJ1a9n3Zvcz6LdRyIW5572wBCTH/Z+bKuZouGk9Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.13': - resolution: {integrity: sha512-bmRg3O6Z0gq9yodKKWCIpnlH051sEfdVwt+6m5UDffAQMUUqU0xjnQqqAUm+Gu7ofAAly9DqiQDtKu2nPDEABA==} + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.17': + resolution: {integrity: sha512-b/CgbwAJpmrRLp02RPfhbudf5tZnN9nsPWK82znefso832etkem8H7FSZwxrOI9djcdTP7U6YfNhbRnh7djErg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.13': - resolution: {integrity: sha512-8Wtnbw4k7pMYN9B/mOEAsQ8HOiq7AZ31Ig4M9BKn2So4xRaFEhtCSa4ZJaOutOWq50zpgR4N5+L/opnlaCx8wQ==} + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.17': + resolution: {integrity: sha512-4EII1iNGRUN5WwGbF/kOh/EIkoDN9HsupgLQoXfY+D1oyJm7/F4t5PYU5n8SWZgG0FEwakyM8pGgwcBYruGTlA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] - '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.13': - resolution: {integrity: sha512-D/0Nlo8mQuxSMohNJUF2lDXWRsFDsHldfRRgD9bRgktj+EndGPj4DOV37LqDKPYS+osdyhZEH7fTakTAEcW7qg==} + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.17': + resolution: {integrity: sha512-AH8oq3XqQo4IibpVXvPeLDI5pzkpYn0WiZAfT05kFzoJ6tQNzwRdDYQ45M8I/gslbodRZwW8uxLhbSBbkv96rA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.13': - resolution: {integrity: sha512-eRrPvat2YaVQcwwKi/JzOP6MKf1WRnOCr+VaI3cTWz3ZoLcP/654z90lVCJ4dAuMEpPdke0n+qyAqXDZdIC4rA==} + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.17': + resolution: {integrity: sha512-cLnjV3xfo7KslbU41Z7z8BH/E1y5mzUYzAqih1d1MDaIGZRCMqTijqLv76/P7fyHuvUcfGsIpqCdddbxLLK9rA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - '@rolldown/binding-linux-x64-musl@1.0.0-rc.13': - resolution: {integrity: sha512-PsdONiFRp8hR8KgVjTWjZ9s7uA3uueWL0t74/cKHfM4dR5zXYv4AjB8BvA+QDToqxAFg4ZkcVEqeu5F7inoz5w==} + '@rolldown/binding-linux-x64-musl@1.0.0-rc.17': + resolution: {integrity: sha512-0phclDw1spsL7dUB37sIARuis2tAgomCJXAHZlpt8PXZ4Ba0dRP1e+66lsRqrfhISeN9bEGNjQs+T/Fbd7oYGw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - '@rolldown/binding-openharmony-arm64@1.0.0-rc.13': - resolution: {integrity: sha512-hCNXgC5dI3TVOLrPT++PKFNZ+1EtS0mLQwfXXXSUD/+rGlB65gZDwN/IDuxLpQP4x8RYYHqGomlUXzpO8aVI2w==} + '@rolldown/binding-openharmony-arm64@1.0.0-rc.17': + resolution: {integrity: sha512-0ag/hEgXOwgw4t8QyQvUCxvEg+V0KBcA6YuOx9g0r02MprutRF5dyljgm3EmR02O292UX7UeS6HzWHAl6KgyhA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@rolldown/binding-wasm32-wasi@1.0.0-rc.13': - resolution: {integrity: sha512-viLS5C5et8NFtLWw9Sw3M/w4vvnVkbWkO7wSNh3C+7G1+uCkGpr6PcjNDSFcNtmXY/4trjPBqUfcOL+P3sWy/g==} - engines: {node: '>=14.0.0'} + '@rolldown/binding-wasm32-wasi@1.0.0-rc.17': + resolution: {integrity: sha512-LEXei6vo0E5wTGwpkJ4KoT3OZJRnglwldt5ziLzOlc6qqb55z4tWNq2A+PFqCJuvWWdP53CVhG1Z9NtToDPJrA==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [wasm32] - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.13': - resolution: {integrity: sha512-Fqa3Tlt1xL4wzmAYxGNFV36Hb+VfPc9PYU+E25DAnswXv3ODDu/yyWjQDbXMo5AGWkQVjLgQExuVu8I/UaZhPQ==} + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.17': + resolution: {integrity: sha512-gUmyzBl3SPMa6hrqFUth9sVfcLBlYsbMzBx5PlexMroZStgzGqlZ26pYG89rBb45Mnia+oil6YAIFeEWGWhoZA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.13': - resolution: {integrity: sha512-/pLI5kPkGEi44TDlnbio3St/5gUFeN51YWNAk/Gnv6mEQBOahRBh52qVFVBpmrnU01n2yysvBML9Ynu7K4kGAQ==} + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.17': + resolution: {integrity: sha512-3hkiolcUAvPB9FLb3UZdfjVVNWherN1f/skkGWJP/fgSQhYUZpSIRr0/I8ZK9TkF3F7kxvJAk0+IcKvPHk9qQg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -3895,8 +3889,8 @@ packages: '@rolldown/pluginutils@1.0.0-beta.27': resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} - '@rolldown/pluginutils@1.0.0-rc.13': - resolution: {integrity: sha512-3ngTAv6F/Py35BsYbeeLeecvhMKdsKm4AoOETVhAA+Qc8nrA2I0kF7oa93mE9qnIurngOSpMnQ0x2nQY2FPviA==} + '@rolldown/pluginutils@1.0.0-rc.17': + resolution: {integrity: sha512-n8iosDOt6Ig1UhJ2AYqoIhHWh/isz0xpicHTzpKBeotdVsTEcxsSA/i3EVM7gQAj0rU27OLAxCjzlj15IWY7bg==} '@rollup/plugin-replace@6.0.3': resolution: {integrity: sha512-J4RZarRvQAm5IF0/LwUUg+obsm+xZhYnbMXmXROyoSE1ATJe3oXSb9L5MMppdxP2ylNSjv6zFBwKYjcKMucVfA==} @@ -7973,8 +7967,8 @@ packages: vue-tsc: optional: true - rolldown@1.0.0-rc.13: - resolution: {integrity: sha512-bvVj8YJmf0rq4pSFmH7laLa6pYrhghv3PRzrCdRAr23g66zOKVJ4wkvFtgohtPLWmthgg8/rkaqRHrpUEh0Zbw==} + rolldown@1.0.0-rc.17: + resolution: {integrity: sha512-ZrT53oAKrtA4+YtBWPQbtPOxIbVDbxT0orcYERKd63VJTF13zPcgXTvD4843L8pcsI7M6MErt8QtON6lrB9tyA==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true @@ -9819,24 +9813,24 @@ snapshots: '@effect/rpc': 0.74.0(@effect/platform@0.95.0(effect@3.20.0))(effect@3.20.0) effect: 3.20.0 - '@emnapi/core@1.8.1': + '@emnapi/core@1.10.0': dependencies: - '@emnapi/wasi-threads': 1.1.0 + '@emnapi/wasi-threads': 1.2.1 tslib: 2.8.1 optional: true - '@emnapi/core@1.9.1': + '@emnapi/core@1.8.1': dependencies: - '@emnapi/wasi-threads': 1.2.0 + '@emnapi/wasi-threads': 1.1.0 tslib: 2.8.1 optional: true - '@emnapi/runtime@1.8.1': + '@emnapi/runtime@1.10.0': dependencies: tslib: 2.8.1 optional: true - '@emnapi/runtime@1.9.1': + '@emnapi/runtime@1.8.1': dependencies: tslib: 2.8.1 optional: true @@ -9846,7 +9840,7 @@ snapshots: tslib: 2.8.1 optional: true - '@emnapi/wasi-threads@1.2.0': + '@emnapi/wasi-threads@1.2.1': dependencies: tslib: 2.8.1 optional: true @@ -10827,10 +10821,10 @@ snapshots: '@tybys/wasm-util': 0.10.1 optional: true - '@napi-rs/wasm-runtime@1.1.2(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)': + '@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': dependencies: - '@emnapi/core': 1.9.1 - '@emnapi/runtime': 1.9.1 + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 '@tybys/wasm-util': 0.10.1 optional: true @@ -10889,7 +10883,7 @@ snapshots: '@orama/orama@3.1.18': {} - '@oxc-project/types@0.123.0': {} + '@oxc-project/types@0.127.0': {} '@oxc-resolver/binding-android-arm-eabi@11.16.2': optional: true @@ -11859,58 +11853,58 @@ snapshots: dependencies: react: 19.2.3 - '@rolldown/binding-android-arm64@1.0.0-rc.13': + '@rolldown/binding-android-arm64@1.0.0-rc.17': optional: true - '@rolldown/binding-darwin-arm64@1.0.0-rc.13': + '@rolldown/binding-darwin-arm64@1.0.0-rc.17': optional: true - '@rolldown/binding-darwin-x64@1.0.0-rc.13': + '@rolldown/binding-darwin-x64@1.0.0-rc.17': optional: true - '@rolldown/binding-freebsd-x64@1.0.0-rc.13': + '@rolldown/binding-freebsd-x64@1.0.0-rc.17': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.13': + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.17': optional: true - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.13': + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.17': optional: true - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.13': + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.17': optional: true - '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.13': + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.17': optional: true - '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.13': + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.17': optional: true - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.13': + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.17': optional: true - '@rolldown/binding-linux-x64-musl@1.0.0-rc.13': + '@rolldown/binding-linux-x64-musl@1.0.0-rc.17': optional: true - '@rolldown/binding-openharmony-arm64@1.0.0-rc.13': + '@rolldown/binding-openharmony-arm64@1.0.0-rc.17': optional: true - '@rolldown/binding-wasm32-wasi@1.0.0-rc.13': + '@rolldown/binding-wasm32-wasi@1.0.0-rc.17': dependencies: - '@emnapi/core': 1.9.1 - '@emnapi/runtime': 1.9.1 - '@napi-rs/wasm-runtime': 1.1.2(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1) + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) optional: true - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.13': + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.17': optional: true - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.13': + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.17': optional: true '@rolldown/pluginutils@1.0.0-beta.27': {} - '@rolldown/pluginutils@1.0.0-rc.13': {} + '@rolldown/pluginutils@1.0.0-rc.17': {} '@rollup/plugin-replace@6.0.3(rollup@4.55.1)': dependencies: @@ -16709,7 +16703,7 @@ snapshots: rfdc@1.4.1: {} - rolldown-plugin-dts@0.15.10(oxc-resolver@11.16.2)(rolldown@1.0.0-rc.13)(typescript@5.9.3): + rolldown-plugin-dts@0.15.10(oxc-resolver@11.16.2)(rolldown@1.0.0-rc.17)(typescript@5.9.3): dependencies: '@babel/generator': 7.28.5 '@babel/parser': 7.28.5 @@ -16719,33 +16713,33 @@ snapshots: debug: 4.4.3(supports-color@5.5.0) dts-resolver: 2.1.3(oxc-resolver@11.16.2) get-tsconfig: 4.13.0 - rolldown: 1.0.0-rc.13 + rolldown: 1.0.0-rc.17 optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: - oxc-resolver - supports-color - rolldown@1.0.0-rc.13: + rolldown@1.0.0-rc.17: dependencies: - '@oxc-project/types': 0.123.0 - '@rolldown/pluginutils': 1.0.0-rc.13 + '@oxc-project/types': 0.127.0 + '@rolldown/pluginutils': 1.0.0-rc.17 optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.0-rc.13 - '@rolldown/binding-darwin-arm64': 1.0.0-rc.13 - '@rolldown/binding-darwin-x64': 1.0.0-rc.13 - '@rolldown/binding-freebsd-x64': 1.0.0-rc.13 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.13 - '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.13 - '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.13 - '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.13 - '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.13 - '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.13 - '@rolldown/binding-linux-x64-musl': 1.0.0-rc.13 - '@rolldown/binding-openharmony-arm64': 1.0.0-rc.13 - '@rolldown/binding-wasm32-wasi': 1.0.0-rc.13 - '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.13 - '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.13 + '@rolldown/binding-android-arm64': 1.0.0-rc.17 + '@rolldown/binding-darwin-arm64': 1.0.0-rc.17 + '@rolldown/binding-darwin-x64': 1.0.0-rc.17 + '@rolldown/binding-freebsd-x64': 1.0.0-rc.17 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.17 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.17 + '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.17 + '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.17 + '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.17 + '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.17 + '@rolldown/binding-linux-x64-musl': 1.0.0-rc.17 + '@rolldown/binding-openharmony-arm64': 1.0.0-rc.17 + '@rolldown/binding-wasm32-wasi': 1.0.0-rc.17 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.17 + '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.17 rollup-plugin-preserve-directives@0.4.0(rollup@4.55.1): dependencies: @@ -17405,8 +17399,8 @@ snapshots: diff: 8.0.2 empathic: 2.0.0 hookable: 5.5.3 - rolldown: 1.0.0-rc.13 - rolldown-plugin-dts: 0.15.10(oxc-resolver@11.16.2)(rolldown@1.0.0-rc.13)(typescript@5.9.3) + rolldown: 1.0.0-rc.17 + rolldown-plugin-dts: 0.15.10(oxc-resolver@11.16.2)(rolldown@1.0.0-rc.17)(typescript@5.9.3) semver: 7.7.3 tinyexec: 1.0.2 tinyglobby: 0.2.15