better formatting

This commit is contained in:
Hellings 2026-10-23 09:12:49 -04:00
parent 36a07eaf92
commit f6e2db8891
3 changed files with 45 additions and 16 deletions

View file

@ -1 +1,4 @@
export { shadcnIntegration, type ShadcnIntegrationOptions } from "./src/integration.ts"; export {
shadcnIntegration,
type ShadcnIntegrationOptions,
} from "./src/integration.ts";

View file

@ -1,7 +1,9 @@
{ {
"name": "@muddle/shadcn", "name": "@muddle/shadcn",
"type": "module", "type": "module",
"exports": "./index.ts", "exports": "./index.ts",
"version": "0.1.0", "version": "0.1.0",
"peerDependencies": { "muddle": "*" } "peerDependencies": {
"muddle": "*"
}
} }

View file

@ -1,6 +1,11 @@
import { mkdir, writeFile } from "node:fs/promises"; import { mkdir, writeFile } from "node:fs/promises";
import { basename, extname, join, resolve } from "node:path"; import { basename, extname, join, resolve } from "node:path";
import { cssToStcss, reactToSpug, type Integration, type IntegrationContext } from "muddle"; import {
cssToStcss,
reactToSpug,
type Integration,
type IntegrationContext,
} from "muddle";
export interface ShadcnIntegrationOptions { export interface ShadcnIntegrationOptions {
components: string[]; components: string[];
@ -15,32 +20,51 @@ interface RegistryItem {
} }
/** Pulls ShadCN registry entries and writes their Muddle ports into the host project. */ /** Pulls ShadCN registry entries and writes their Muddle ports into the host project. */
export function shadcnIntegration(options: ShadcnIntegrationOptions): Integration { export function shadcnIntegration(
options: ShadcnIntegrationOptions,
): Integration {
return { return {
name: "shadcn", name: "shadcn",
async setup(context: IntegrationContext) { async setup(context: IntegrationContext) {
const fetcher = options.fetch ?? globalThis.fetch; const fetcher = options.fetch ?? globalThis.fetch;
const destination = resolve(context.config.root, options.dir ?? "modules/app/views/components"); const destination = resolve(
context.config.root,
options.dir ?? "modules/app/views/components",
);
const styles = resolve(context.config.root, "styles/shadcn"); const styles = resolve(context.config.root, "styles/shadcn");
const seen = new Set<string>(); const seen = new Set<string>();
const pull = async (name: string): Promise<void> => { const pull = async (name: string): Promise<void> => {
if (seen.has(name)) return; if (seen.has(name)) return;
seen.add(name); seen.add(name);
const base = options.registry ?? "https://ui.shadcn.com/r/styles/new-york/{name}.json"; const base =
const url = base.includes("{name}") ? base.replace("{name}", encodeURIComponent(name)) : `${base.replace(/\/$/, "")}/${encodeURIComponent(name)}.json`; options.registry ??
"https://ui.shadcn.com/r/styles/new-york/{name}.json";
const url = base.includes("{name}")
? base.replace("{name}", encodeURIComponent(name))
: `${base.replace(/\/$/, "")}/${encodeURIComponent(name)}.json`;
const response = await fetcher(url); const response = await fetcher(url);
if (!response.ok) throw new Error(`shadcn registry request failed for ${name} with ${response.status}`); if (!response.ok)
const item = await response.json() as RegistryItem; throw new Error(
for (const dependency of item.registryDependencies ?? []) await pull(dependency.replace(/^@[^/]+\//, "")); `shadcn registry request failed for ${name} with ${response.status}`,
);
const item = (await response.json()) as RegistryItem;
for (const dependency of item.registryDependencies ?? [])
await pull(dependency.replace(/^@[^/]+\//, ""));
for (const file of item.files ?? []) { for (const file of item.files ?? []) {
const extension = extname(file.path).toLowerCase(); const extension = extname(file.path).toLowerCase();
const stem = basename(file.path).replace(/\.(tsx|jsx|css)$/i, ""); const stem = basename(file.path).replace(/\.(tsx|jsx|css)$/i, "");
if (extension === ".tsx" || extension === ".jsx") { if (extension === ".tsx" || extension === ".jsx") {
await mkdir(destination, { recursive: true }); await mkdir(destination, { recursive: true });
await writeFile(join(destination, `${stem}.spug`), reactToSpug(file.content, file.path)); await writeFile(
join(destination, `${stem}.spug`),
reactToSpug(file.content, file.path),
);
} else if (extension === ".css") { } else if (extension === ".css") {
await mkdir(styles, { recursive: true }); await mkdir(styles, { recursive: true });
await writeFile(join(styles, `${stem}.stcss`), cssToStcss(file.content, file.path)); await writeFile(
join(styles, `${stem}.stcss`),
cssToStcss(file.content, file.path),
);
} }
} }
}; };