sigma-ui
Version:
CLI for SIGMA-UI components.
1,603 lines (1,583 loc) • 852 kB
JavaScript
#!/usr/bin/env node
import {
__export
} from "./chunk-PZ5AY32C.js";
// src/index.ts
import process6 from "node:process";
import { Command as Command4 } from "commander";
// src/commands/add.ts
import { existsSync as existsSync3, promises as fs3 } from "node:fs";
import process3 from "node:process";
import path5 from "pathe";
import { consola as consola3 } from "consola";
import { colors as colors2 } from "consola/utils";
import { Command } from "commander";
import ora from "ora";
import prompts from "prompts";
import { z as z2 } from "zod";
// src/utils/package-manager.ts
import { execSync } from "node:child_process";
import { existsSync, readFileSync } from "node:fs";
import path from "pathe";
async function detectPackageManager(cwd) {
const lockFiles = [
{ name: "pnpm", files: ["pnpm-lock.yaml", "pnpm-workspace.yaml"] },
{ name: "yarn", files: ["yarn.lock"] },
{ name: "bun", files: ["bun.lockb"] },
{ name: "npm", files: ["package-lock.json"] }
];
for (const pm of lockFiles) {
for (const file of pm.files) {
if (existsSync(path.join(cwd, file))) {
return { name: pm.name };
}
}
}
try {
const packageJsonPath = path.join(cwd, "package.json");
if (existsSync(packageJsonPath)) {
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
if (packageJson.packageManager) {
const [name, version] = packageJson.packageManager.split("@");
return { name, version };
}
}
} catch {
}
return { name: "pnpm" };
}
async function addDependency(dependencies, options8 = { cwd: process.cwd() }) {
await installPackages(dependencies, "dependencies", options8);
}
async function addDevDependency(dependencies, options8 = { cwd: process.cwd() }) {
await installPackages(dependencies, "devDependencies", options8);
}
async function installPackages(dependencies, type2, options8 = { cwd: process.cwd() }) {
const pm = await detectPackageManager(options8.cwd);
const devFlag = type2 === "devDependencies" ? "-D " : "";
let command = "";
switch (pm?.name) {
case "npm":
command = `npm install ${devFlag}${dependencies.join(" ")}`;
break;
case "yarn":
command = `yarn add ${devFlag}${dependencies.join(" ")}`;
break;
case "bun":
command = `bun add ${devFlag}${dependencies.join(" ")}`;
break;
case "pnpm":
default:
command = `pnpm add ${devFlag}${dependencies.join(" ")}`;
break;
}
const stdio = options8.silent ? "pipe" : "inherit";
execSync(command, { cwd: options8.cwd, stdio });
}
// src/utils/transformers/index.ts
import { promises as fs } from "node:fs";
import { tmpdir } from "node:os";
import path2 from "pathe";
import { Project, ScriptKind } from "ts-morph";
// src/utils/transformers/transform-import.ts
var transformImport = async ({ sourceFile, config }) => {
const importDeclarations = sourceFile.getImportDeclarations();
for (const importDeclaration of importDeclarations) {
const moduleSpecifier = importDeclaration.getModuleSpecifierValue();
if (moduleSpecifier.startsWith("@ui/registry/")) {
if (config.aliases.components) {
importDeclaration.setModuleSpecifier(
moduleSpecifier.replace(/^@ui\/registry\/[^/]+\/ui/, config.aliases.components)
);
} else {
importDeclaration.setModuleSpecifier(
moduleSpecifier.replace(
/^@ui\/registry\/[^/]+/,
config.aliases.components
)
);
}
}
if (moduleSpecifier === "@ui/utils") {
const namedImports = importDeclaration.getNamedImports();
const cnImport = namedImports.find((i2) => i2.getName() === "cn");
if (cnImport) {
importDeclaration.setModuleSpecifier(
moduleSpecifier.replace(/^@ui\/utils/, config.aliases.utils)
);
}
}
}
return sourceFile;
};
// src/utils/transformers/index.ts
var transformers = [
transformImport
// transformTwPrefixes,
];
var project = new Project({
compilerOptions: {}
});
async function createTempSourceFile(filename) {
const dir = await fs.mkdtemp(path2.join(tmpdir(), "sigma-ui-"));
return path2.join(dir, filename);
}
async function transform(opts) {
const tempFile = await createTempSourceFile(opts.filename);
const sourceFile = project.createSourceFile(tempFile, opts.raw, {
scriptKind: ScriptKind.Unknown
});
for (const transformer of transformers) {
transformer({ sourceFile, ...opts });
}
return sourceFile?.getFullText();
}
// src/utils/get-config.ts
import { existsSync as existsSync2 } from "node:fs";
import process2 from "node:process";
import path3 from "pathe";
import { loadConfig as c12LoadConfig } from "c12";
import { loadConfig } from "tsconfig-paths";
import consola from "consola";
import { colors } from "consola/utils";
// src/utils/resolve-import.ts
import { createMatchPath } from "tsconfig-paths";
function resolveImport(importPath, config) {
return createMatchPath(config.absoluteBaseUrl, config.paths)(
importPath,
void 0,
() => true,
[".ts", ".tsx", ".vue"]
);
}
// src/schemas/index.ts
import { z } from "zod";
var DEFAULT_TYPESCRIPT_CONFIG = "tsconfig.json";
var DEFAULT_TAILWIND_BASE_COLOR = "grayscale";
var commonFields = {
styleSystem: z.string(),
baseColor: z.string().default(DEFAULT_TAILWIND_BASE_COLOR),
components: z.array(z.string()).optional(),
cwd: z.string(),
yes: z.boolean(),
path: z.string().optional()
};
var tailwindFields = {
config: z.string(),
prefix: z.string().optional()
};
var registryItemSchema = z.object({
name: z.string(),
dependencies: z.array(z.string()).optional(),
devDependencies: z.array(z.string()).optional(),
registryDependencies: z.array(z.string()).optional(),
files: z.array(z.string()),
type: z.enum(["components:ui", "components:component", "components:example"])
});
var registryIndexSchema = z.array(registryItemSchema);
var registryItemWithContentSchema = registryItemSchema.extend({
files: z.array(
z.object({
name: z.string(),
content: z.string()
})
)
});
var registryWithContentSchema = z.array(registryItemWithContentSchema);
var stylesSchema = z.array(
z.object({
name: z.string(),
label: z.string()
})
);
var registryBaseColorSchema = z.object({
inlineColors: z.object({
light: z.record(z.string(), z.string()),
dark: z.record(z.string(), z.string())
}),
cssVars: z.object({
light: z.record(z.string(), z.string()),
dark: z.record(z.string(), z.string())
}),
templates: z.object({
tailwind: z.object({
withVariables: z.string()
}),
css: z.object({
withVariables: z.string()
})
})
});
var rawConfigSchema = z.object({
$schema: z.string().optional(),
styleSystem: commonFields.styleSystem,
tsConfigPath: z.string().default(DEFAULT_TYPESCRIPT_CONFIG),
setupTailwind: z.boolean().default(false),
framework: z.string().default("vite"),
cssPath: z.string(),
baseColor: commonFields.baseColor,
tailwind: z.object({
config: tailwindFields.config,
prefix: tailwindFields.prefix
}),
aliases: z.object({
utils: z.string().default(""),
components: z.string()
}),
generatePreflight: z.boolean().optional().default(true)
});
var configSchema = rawConfigSchema.extend({
resolvedPaths: z.object({
tailwindConfig: z.string(),
tailwindCss: z.string(),
utils: z.string().optional(),
components: z.string()
})
});
var initOptionsSchema = z.object({
cwd: commonFields.cwd,
yes: commonFields.yes
});
var addOptionsSchema = z.object({
components: commonFields.components,
yes: commonFields.yes,
overwrite: z.boolean(),
cwd: commonFields.cwd,
all: z.boolean(),
path: commonFields.path
});
var configValidationSchema = z.object({
styleSystem: commonFields.styleSystem,
baseColor: commonFields.baseColor,
tailwind: z.object({
config: tailwindFields.config
})
});
var diffOptionsSchema = z.object({
component: z.string().optional(),
yes: commonFields.yes,
cwd: commonFields.cwd,
path: commonFields.path
});
// ../shared/consts/index.ts
var DEFAULT_COMPONENTS = "@/components/ui";
var DEFAULT_UTILS = "@/lib/utils";
var DEFAULT_TAILWIND_CONFIG = "tailwind.config.js";
var INIT_COMMAND = "npx sigma-ui init";
var CONFIG_FILE_PATH = "sigma-ui.config.json";
var TAILWIND_CSS_PATH = {
nuxt: "assets/css/tailwind.css",
vite: "src/assets/index.css",
laravel: "resources/css/app.css",
astro: "src/styles/globals.css"
};
// src/utils/get-config.ts
async function getConfig(cwd) {
const config = await getRawConfig(cwd);
if (!config) {
return null;
}
return await resolveConfigPaths(cwd, config);
}
async function handleConfigIsMissing() {
consola.warn(`Configuration is missing. Run ${colors.green(INIT_COMMAND)} command to create config file`);
process2.exit(1);
}
async function resolveConfigPaths(cwd, config) {
let tsConfig;
let tsConfigPath = path3.resolve(
cwd,
config.tsConfigPath
);
tsConfig = loadConfig(tsConfigPath);
if ("paths" in tsConfig && Object.keys(tsConfig.paths).length === 0) {
tsConfigPath = path3.resolve(cwd, "./tsconfig.app.json");
if (existsSync2(tsConfigPath)) {
tsConfig = loadConfig(tsConfigPath);
}
}
if (tsConfig.resultType === "failed") {
throw new Error(
`Failed to load ${tsConfigPath}. ${tsConfig.message ?? ""}`.trim()
);
}
return configSchema.parse({
...config,
resolvedPaths: {
tailwindConfig: path3.resolve(cwd, config.tailwind.config),
tailwindCss: path3.resolve(cwd, config.cssPath),
utils: resolveImport(config.aliases.utils, tsConfig),
components: resolveImport(config.aliases.components, tsConfig)
}
});
}
async function getRawConfig(cwd) {
try {
const configResult = await c12LoadConfig({
name: "components",
configFile: CONFIG_FILE_PATH,
cwd
});
if (!configResult.config || Object.keys(configResult.config).length === 0) {
return null;
}
return rawConfigSchema.parse(configResult.config);
} catch (error) {
throw new Error(`Invalid configuration found in ${cwd}/${CONFIG_FILE_PATH}. ${error}`);
}
}
// src/utils/handle-error.ts
import { consola as consola2 } from "consola";
function handleError(error) {
if (typeof error === "string") {
consola2.error(error);
process.exit(1);
}
if (error instanceof Error) {
consola2.error(error.message);
process.exit(1);
}
consola2.error("Something went wrong. Please try again.");
process.exit(1);
}
// src/utils/registry/index.ts
import fs2 from "node:fs";
import path4 from "pathe";
// ../../apps/docs/src/lib/registry/themes.ts
var themes = [
{
name: "grayscale",
label: "Grayscale",
previewColor: "#52525b",
cssVars: {
light: {
"background": "0 0% 100%",
"foreground": "240 10% 3.9%",
"muted": "240 4.8% 95.9%",
"muted-foreground": "240 3.8% 46.1%",
"popover": "0 0% 100%",
"popover-foreground": "240 10% 3.9%",
"card": "0 0% 100%",
"card-foreground": "240 10% 3.9%",
"border": "240 5.9% 90%",
"input": "0 0% 100%",
"primary": "240 5.9% 10%",
"primary-foreground": "0 0% 98%",
"secondary": "240 4.8% 95.9%",
"secondary-foreground": "240 5.9% 10%",
"destructive": "0 84.2% 60.2%",
"destructive-foreground": "0 0% 98%",
"ring": "240 5.9% 10%"
},
dark: {
"background": "240 10% 3.9%",
"foreground": "0 0% 98%",
"muted": "240 3.7% 15.9%",
"muted-foreground": "240 5% 64.9%",
"popover": "240 10% 3.9%",
"popover-foreground": "0 0% 98%",
"card": "240 10% 3.9%",
"card-foreground": "0 0% 98%",
"border": "240 3.7% 15.9%",
"input": "240 10% 3.9%",
"primary": "0 0% 98%",
"primary-foreground": "240 5.9% 10%",
"secondary": "240 3.7% 15.9%",
"secondary-foreground": "0 0% 98%",
"destructive": "0 62.8% 30.6%",
"destructive-foreground": "0 0% 98%",
"ring": "240 4.9% 83.9%"
}
}
},
{
name: "frosted-glass",
label: "Frosted glass",
previewColor: "#587aa9",
cssVars: {
light: {
"background": "0 0% 100%",
"foreground": "224 71.4% 4.1%",
"muted": "220 14.3% 95.9%",
"muted-foreground": "220 8.9% 46.1%",
"popover": "0 0% 100% / 10%",
"popover-foreground": "224 71.4% 4.1%",
"card": "0 0% 100% / 10%",
"card-foreground": "224 71.4% 4.1%",
"border": "220 13% 91%",
"input": "0 0% 100%",
"primary": "220.9 39.3% 11%",
"primary-foreground": "210 20% 98%",
"secondary": "220 14.3% 95.9%",
"secondary-foreground": "220.9 39.3% 11%",
"destructive": "0 84.2% 60.2%",
"destructive-foreground": "210 20% 98%",
"ring": "224 71.4% 4.1%"
},
dark: {
"background": "224 71.4% 4.1%",
"foreground": "210 20% 98%",
"muted": "215 27.9% 16.9%",
"muted-foreground": "217.9 10.6% 64.9%",
"popover": "224 71.4% 4.1% / 20%",
"popover-foreground": "210 20% 98%",
"card": "215 27.9% 16.9% / 30%",
"card-foreground": "210 20% 98%",
"border": "215 27.9% 16.9%",
"input": "224 71.4% 4.1% / 50%",
"primary": "210 20% 98%",
"primary-foreground": "220.9 39.3% 11%",
"secondary": "215 27.9% 16.9% / 50%",
"secondary-foreground": "210 20% 98%",
"destructive": "0 62.8% 30.6%",
"destructive-foreground": "210 20% 98%",
"ring": "216 12.2% 83.9%"
}
}
},
{
name: "red",
label: "Red",
previewColor: "#dc2626",
cssVars: {
light: {
"background": "0 0% 100%",
"foreground": "0 0% 3.9%",
"muted": "0 0% 96.1%",
"muted-foreground": "0 0% 45.1%",
"popover": "0 0% 100%",
"popover-foreground": "0 0% 3.9%",
"card": "0 0% 100%",
"card-foreground": "0 0% 3.9%",
"border": "0 0% 89.8%",
"input": "0 0% 100%",
"primary": "0 72.2% 50.6%",
"primary-foreground": "0 85.7% 97.3%",
"secondary": "0 0% 96.1%",
"secondary-foreground": "0 0% 9%",
"destructive": "0 84.2% 60.2%",
"destructive-foreground": "0 0% 98%",
"ring": "0 72.2% 50.6%"
},
dark: {
"background": "0 0% 3.9%",
"foreground": "0 0% 98%",
"muted": "0 0% 14.9%",
"muted-foreground": "0 0% 63.9%",
"popover": "0 0% 3.9%",
"popover-foreground": "0 0% 98%",
"card": "0 0% 3.9%",
"card-foreground": "0 0% 98%",
"border": "0 0% 14.9%",
"input": "0 0% 3.9%",
"primary": "0 72.2% 50.6%",
"primary-foreground": "0 85.7% 97.3%",
"secondary": "0 0% 14.9%",
"secondary-foreground": "0 0% 98%",
"destructive": "0 62.8% 30.6%",
"destructive-foreground": "0 0% 98%",
"ring": "0 72.2% 50.6%"
}
}
},
{
name: "rose",
label: "Rose",
previewColor: "#e11d48",
cssVars: {
light: {
"background": "0 0% 100%",
"foreground": "240 10% 3.9%",
"muted": "240 4.8% 95.9%",
"muted-foreground": "240 3.8% 46.1%",
"popover": "0 0% 100%",
"popover-foreground": "240 10% 3.9%",
"card": "0 0% 100%",
"card-foreground": "240 10% 3.9%",
"border": "240 5.9% 90%",
"input": "0 0% 100%",
"primary": "346.8 77.2% 49.8%",
"primary-foreground": "355.7 100% 97.3%",
"secondary": "240 4.8% 95.9%",
"secondary-foreground": "240 5.9% 10%",
"destructive": "0 84.2% 60.2%",
"destructive-foreground": "0 0% 98%",
"ring": "346.8 77.2% 49.8%"
},
dark: {
"background": "20 14.3% 4.1%",
"foreground": "0 0% 95%",
"muted": "0 0% 15%",
"muted-foreground": "240 5% 64.9%",
"popover": "0 0% 9%",
"popover-foreground": "0 0% 95%",
"card": "24 9.8% 10%",
"card-foreground": "0 0% 95%",
"border": "240 3.7% 15.9%",
"input": "20 14.3% 4.1%",
"primary": "346.8 77.2% 49.8%",
"primary-foreground": "355.7 100% 97.3%",
"secondary": "240 3.7% 15.9%",
"secondary-foreground": "0 0% 98%",
"destructive": "0 62.8% 30.6%",
"destructive-foreground": "0 85.7% 97.3%",
"ring": "346.8 77.2% 49.8%"
}
}
},
{
name: "orange",
label: "Orange",
previewColor: "#ea580c",
cssVars: {
light: {
"background": "0 0% 100%",
"foreground": "20 14.3% 4.1%",
"muted": "60 4.8% 95.9%",
"muted-foreground": "25 5.3% 44.7%",
"popover": "0 0% 100%",
"popover-foreground": "20 14.3% 4.1%",
"card": "0 0% 100%",
"card-foreground": "20 14.3% 4.1%",
"border": "20 5.9% 90%",
"input": "0 0% 100%",
"primary": "24.6 95% 53.1%",
"primary-foreground": "60 9.1% 97.8%",
"secondary": "60 4.8% 95.9%",
"secondary-foreground": "24 9.8% 10%",
"destructive": "0 84.2% 60.2%",
"destructive-foreground": "60 9.1% 97.8%",
"ring": "24.6 95% 53.1%"
},
dark: {
"background": "20 14.3% 4.1%",
"foreground": "60 9.1% 97.8%",
"muted": "12 6.5% 15.1%",
"muted-foreground": "24 5.4% 63.9%",
"popover": "20 14.3% 4.1%",
"popover-foreground": "60 9.1% 97.8%",
"card": "20 14.3% 4.1%",
"card-foreground": "60 9.1% 97.8%",
"border": "12 6.5% 15.1%",
"input": "20 14.3% 4.1%",
"primary": "20.5 90.2% 48.2%",
"primary-foreground": "60 9.1% 97.8%",
"secondary": "12 6.5% 15.1%",
"secondary-foreground": "60 9.1% 97.8%",
"destructive": "0 72.2% 50.6%",
"destructive-foreground": "60 9.1% 97.8%",
"ring": "20.5 90.2% 48.2%"
}
}
},
{
name: "green",
label: "Green",
previewColor: "#16a34a",
cssVars: {
light: {
"background": "0 0% 100%",
"foreground": "240 10% 3.9%",
"muted": "240 4.8% 95.9%",
"muted-foreground": "240 3.8% 46.1%",
"popover": "0 0% 100%",
"popover-foreground": "240 10% 3.9%",
"card": "0 0% 100%",
"card-foreground": "240 10% 3.9%",
"border": "240 5.9% 90%",
"input": "0 0% 100%",
"primary": "142.1 76.2% 36.3%",
"primary-foreground": "355.7 100% 97.3%",
"secondary": "240 4.8% 95.9%",
"secondary-foreground": "240 5.9% 10%",
"destructive": "0 84.2% 60.2%",
"destructive-foreground": "0 0% 98%",
"ring": "142.1 76.2% 36.3%"
},
dark: {
"background": "20 14.3% 4.1%",
"foreground": "0 0% 95%",
"muted": "0 0% 15%",
"muted-foreground": "240 5% 64.9%",
"popover": "0 0% 9%",
"popover-foreground": "0 0% 95%",
"card": "24 9.8% 10%",
"card-foreground": "0 0% 95%",
"border": "240 3.7% 15.9%",
"input": "20 14.3% 4.1%",
"primary": "142.1 70.6% 45.3%",
"primary-foreground": "144.9 80.4% 10%",
"secondary": "240 3.7% 15.9%",
"secondary-foreground": "0 0% 98%",
"destructive": "0 62.8% 30.6%",
"destructive-foreground": "0 85.7% 97.3%",
"ring": "142.4 71.8% 29.2%"
}
}
},
{
name: "blue",
label: "Blue",
previewColor: "#2563eb",
cssVars: {
light: {
"background": "0 0% 100%",
"foreground": "222.2 84% 4.9%",
"muted": "210 40% 96.1%",
"muted-foreground": "215.4 16.3% 46.9%",
"popover": "0 0% 100%",
"popover-foreground": "222.2 84% 4.9%",
"card": "0 0% 100%",
"card-foreground": "222.2 84% 4.9%",
"border": "214.3 31.8% 91.4%",
"input": "0 0% 100%",
"primary": "221.2 83.2% 53.3%",
"primary-foreground": "210 40% 98%",
"secondary": "210 40% 96.1%",
"secondary-foreground": "222.2 47.4% 11.2%",
"destructive": "0 84.2% 60.2%",
"destructive-foreground": "210 40% 98%",
"ring": "221.2 83.2% 53.3%"
},
dark: {
"background": "222.2 84% 4.9%",
"foreground": "210 40% 98%",
"muted": "217.2 32.6% 17.5%",
"muted-foreground": "215 20.2% 65.1%",
"popover": "222.2 84% 4.9%",
"popover-foreground": "210 40% 98%",
"card": "222.2 84% 4.9%",
"card-foreground": "210 40% 98%",
"border": "217.2 32.6% 17.5%",
"input": "222.2 84% 4.9%",
"primary": "217.2 91.2% 59.8%",
"primary-foreground": "222.2 47.4% 11.2%",
"secondary": "217.2 32.6% 17.5%",
"secondary-foreground": "210 40% 98%",
"destructive": "0 62.8% 30.6%",
"destructive-foreground": "210 40% 98%",
"ring": "224.3 76.3% 48%"
}
}
},
{
name: "yellow",
label: "Yellow",
previewColor: "#ca8a04",
cssVars: {
light: {
"background": "0 0% 100%",
"foreground": "20 14.3% 4.1%",
"muted": "60 4.8% 95.9%",
"muted-foreground": "25 5.3% 44.7%",
"popover": "0 0% 100%",
"popover-foreground": "20 14.3% 4.1%",
"card": "0 0% 100%",
"card-foreground": "20 14.3% 4.1%",
"border": "20 5.9% 90%",
"input": "0 0% 100%",
"primary": "47.9 95.8% 53.1%",
"primary-foreground": "26 83.3% 14.1%",
"secondary": "60 4.8% 95.9%",
"secondary-foreground": "24 9.8% 10%",
"destructive": "0 84.2% 60.2%",
"destructive-foreground": "60 9.1% 97.8%",
"ring": "20 14.3% 4.1%"
},
dark: {
"background": "20 14.3% 4.1%",
"foreground": "60 9.1% 97.8%",
"muted": "12 6.5% 15.1%",
"muted-foreground": "24 5.4% 63.9%",
"popover": "20 14.3% 4.1%",
"popover-foreground": "60 9.1% 97.8%",
"card": "20 14.3% 4.1%",
"card-foreground": "60 9.1% 97.8%",
"border": "12 6.5% 15.1%",
"input": "20 14.3% 4.1%",
"primary": "47.9 95.8% 53.1%",
"primary-foreground": "26 83.3% 14.1%",
"secondary": "12 6.5% 15.1%",
"secondary-foreground": "60 9.1% 97.8%",
"destructive": "0 62.8% 30.6%",
"destructive-foreground": "60 9.1% 97.8%",
"ring": "35.5 91.7% 32.9%"
}
}
}
];
var baseColors = themes.map((theme) => ({
name: theme.name,
label: theme.label
}));
// src/utils/registry/index.ts
var REGISTRY_PATH = new URL("../__generated/registry-schemes/", import.meta.url);
var DIRS = {
STYLE_SYSTEM: "style-system",
COLORS: "colors"
};
var filePaths = {
index: () => `index.json`,
styles: () => `${DIRS.STYLE_SYSTEM}/index.json`,
baseColors: (baseColor) => `${DIRS.COLORS}/${baseColor}.json`,
selectedStyleComponent: (params) => `${DIRS.STYLE_SYSTEM}/${params.styleSystem}/${params.componentName}.json`
};
function getRegistryBaseColors() {
return baseColors;
}
async function getSchemeFileData(filePath) {
const filePathUrl = new URL(filePath, REGISTRY_PATH);
const fileData = await fs2.promises.readFile(filePathUrl, "utf8");
const jsonObject = JSON.parse(fileData);
return jsonObject;
}
async function getRegistryIndex() {
try {
const fileData = await getSchemeFileData(filePaths.index());
return registryIndexSchema.parse(fileData);
} catch (error) {
console.error("Error reading components data:", error);
throw new Error("Failed to load components from registry.");
}
}
async function getRegistryStyles() {
try {
const fileData = await getSchemeFileData(filePaths.styles());
return stylesSchema.parse(fileData);
} catch (error) {
console.error("Error reading styles data:", error);
throw new Error("Failed to load styles from registry.");
}
}
async function getRegistryBaseColor(baseColor) {
try {
const fileData = await getSchemeFileData(filePaths.baseColors(baseColor));
return registryBaseColorSchema.parse(fileData);
} catch (error) {
console.error("Error reading base color data:", error);
throw new Error("Failed to load base color from registry.");
}
}
async function fetchTree(styleSystem, tree) {
try {
const results = await Promise.all(
tree.map(async (component) => {
const fileData = await getSchemeFileData(filePaths.selectedStyleComponent({ styleSystem, componentName: component.name }));
return fileData;
})
);
return registryWithContentSchema.parse(results);
} catch (error) {
throw new Error(`Failed to load tree from registry. ${error}`);
}
}
async function resolveTree(index, names) {
const tree = [];
for (const name of names) {
const entry = index.find((entry2) => entry2.name === name);
if (!entry) {
continue;
}
tree.push(entry);
if (entry.registryDependencies) {
const dependencies = await resolveTree(index, entry.registryDependencies);
tree.push(...dependencies);
}
}
return tree.filter(
(component, index2, self) => self.findIndex((c2) => c2.name === component.name) === index2
);
}
function getItemTargetPath(config, item, override) {
if (override) {
return override;
}
if (item.type === "components:ui" && config.aliases.components) {
return config.resolvedPaths.components;
}
const [parent, type2] = item.type.split(":");
if (!(parent in config.resolvedPaths)) {
return null;
}
return path4.join(
config.resolvedPaths[parent] ?? "",
type2
);
}
// src/commands/add.ts
var ComponentInstallError = class extends Error {
constructor(message, component) {
super(message);
this.component = component;
this.name = "ComponentInstallError";
}
};
var add = new Command().name("add").description("add a component to your project").argument("[components...]", "the components to add").option("-y, --yes", "skip confirmation prompt.", true).option("-o, --overwrite", "overwrite existing files.", false).option(
"-c, --cwd <cwd>",
"the working directory. defaults to the current directory.",
process3.cwd()
).option("-a, --all", "add all available components", false).option("-p, --path <path>", "the path to add the component to.").action(async (components, opts) => {
try {
const spinner = ora("Fetching components...").start();
const options8 = parseOptions(components, opts);
const cwd = validateAndResolveCwd(options8.cwd);
const config = await getConfigOrExit(cwd);
try {
configValidationSchema.parse(config);
} catch (error) {
if (error instanceof z2.ZodError) {
consola3.error("Invalid configuration:", error.errors);
process3.exit(1);
}
throw error;
}
const registryIndex = await getRegistryIndex();
spinner.stop();
const selectedComponents = await getSelectedComponents(options8, registryIndex);
if (!selectedComponents?.length) {
consola3.warn("No components selected. Exiting.");
process3.exit(0);
}
const { payload, baseColor } = await getRegistryPayload(config, selectedComponents, registryIndex);
if (!payload.length) {
consola3.warn("Selected components not found. Exiting.");
process3.exit(0);
}
await confirmProceed(options8);
await processPayload(payload, options8, config, baseColor, cwd, selectedComponents);
consola3.success("Done.");
} catch (error) {
if (error instanceof ComponentInstallError) {
consola3.error(`Failed to install component ${error.component}: ${error.message}`);
}
handleError(error);
}
});
function parseOptions(components, opts) {
return addOptionsSchema.parse({
components,
...opts
});
}
function validateAndResolveCwd(cwd) {
const resolvedCwd = path5.resolve(cwd);
if (!existsSync3(resolvedCwd)) {
consola3.error(`The path ${resolvedCwd} does not exist. Try again.`);
process3.exit(1);
}
return resolvedCwd;
}
async function getConfigOrExit(cwd) {
const config = await getConfig(cwd);
if (!config) {
handleConfigIsMissing();
process3.exit(1);
}
return config;
}
async function getSelectedComponents(options8, registryIndex) {
if (options8.all) {
return registryIndex.map((entry) => entry.name);
}
if (options8.components && options8.components.length > 0) {
return options8.components;
}
const { components } = await prompts({
type: "multiselect",
name: "components",
message: "Which components would you like to add?",
hint: "[Space] - select | [A] - toggle all | [Enter] - submit.",
instructions: false,
choices: registryIndex.map((entry) => ({
title: entry.name,
value: entry.name,
selected: options8.all ? true : options8.components?.includes(entry.name)
}))
});
return components;
}
async function getRegistryPayload(config, selectedComponents, registryIndex) {
const tree = await resolveTree(registryIndex, selectedComponents);
const payload = await fetchTree(config.styleSystem, tree);
const baseColor = await getRegistryBaseColor(config.baseColor);
return { payload, baseColor };
}
async function confirmProceed(options8) {
if (!options8.yes) {
const { proceed } = await prompts({
type: "confirm",
name: "proceed",
message: "Ready to install components and dependencies. Proceed?",
initial: true
});
if (!proceed) {
process3.exit(0);
}
}
}
async function processPayload(payload, options8, config, baseColor, cwd, selectedComponents) {
const spinner = ora("Installing components...").start();
for (const item of payload) {
spinner.text = `Installing ${item.name}...`;
const targetDir = getItemTargetPath(
config,
item,
options8.path ? path5.resolve(cwd, options8.path) : void 0
);
if (!targetDir) {
continue;
}
await processItem(item, targetDir, options8, config, baseColor, cwd, selectedComponents, spinner);
}
spinner.succeed();
}
async function processItem(item, targetDir, options8, config, baseColor, cwd, selectedComponents, spinner) {
try {
if (!existsSync3(targetDir)) {
await fs3.mkdir(targetDir, { recursive: true });
}
const componentPath = path5.resolve(targetDir, item.name);
const existingComponent = item.files.filter(
(file) => existsSync3(path5.resolve(componentPath, file.name))
);
if (existingComponent.length && !options8.overwrite) {
if (selectedComponents.includes(item.name)) {
spinner.stop();
const { overwrite } = await prompts({
type: "confirm",
name: "overwrite",
message: `Component ${item.name} already exists. Would you like to overwrite?`,
initial: false
});
if (!overwrite) {
consola3.info(
`Skipped ${item.name}. To overwrite, run with the ${colors2.green(
"--overwrite"
)} flag.`
);
return;
}
spinner.start(`Installing ${item.name}...`);
} else {
return;
}
}
await installDependencies(item, cwd);
await writeComponentFiles(item, componentPath, config, baseColor);
} catch (error) {
throw new ComponentInstallError(
error instanceof Error ? error.message : "Unknown error",
item.name
);
}
}
async function installDependencies(item, cwd) {
const installTasks = [
item.dependencies?.length && { type: "dependencies", deps: item.dependencies, installer: addDependency },
item.devDependencies?.length && { type: "devDependencies", deps: item.devDependencies, installer: addDevDependency }
].filter(Boolean);
for (const task of installTasks) {
try {
consola3.info(`Installing ${task.type}: ${task.deps.join(", ")}`);
await task.installer(task.deps, { cwd });
consola3.success(`Successfully installed ${task.type}.`);
} catch (error) {
const errorMessage = error instanceof Error ? error.message : "Unknown error";
throw new ComponentInstallError(
`Failed to install ${task.type}: ${errorMessage}`,
item.name
);
}
}
}
async function writeComponentFiles(item, componentDir, config, baseColor) {
if (!existsSync3(componentDir)) {
await fs3.mkdir(componentDir, { recursive: true });
}
const files = item.files.map((file) => ({
...file,
path: path5.resolve(componentDir, file.name)
}));
for (const file of files) {
const content = await transform({
filename: file.path,
raw: file.content,
config,
baseColor
});
const filePath = file.path;
await fs3.writeFile(filePath, content);
}
}
// src/commands/diff.ts
import { existsSync as existsSync4, promises as fs4 } from "node:fs";
import process4 from "node:process";
import path6 from "pathe";
import { consola as consola4 } from "consola";
import { colors as colors3 } from "consola/utils";
import { Command as Command2 } from "commander";
import { diffLines } from "diff";
var diff = new Command2().name("diff").description("check for updates against the registry").argument("[component]", "the component name").option("-y, --yes", "skip confirmation prompt.", false).option(
"-c, --cwd <cwd>",
"the working directory. defaults to the current directory.",
process4.cwd()
).action(async (name, opts) => {
try {
const options8 = parseOptions2(name, opts);
const cwd = validateAndResolveCwd2(options8.cwd);
const config = await getConfigOrExit2(cwd);
const registryIndex = await getRegistryIndex();
if (!options8.component) {
await handleAllComponentsDiff(config, registryIndex);
} else {
await handleSingleComponentDiff(options8.component, config, registryIndex);
}
} catch (error) {
handleError(error);
}
});
function parseOptions2(name, opts) {
return diffOptionsSchema.parse({
component: name,
...opts
});
}
function validateAndResolveCwd2(cwd) {
const resolvedCwd = path6.resolve(cwd);
if (!existsSync4(resolvedCwd)) {
consola4.error(`The path ${resolvedCwd} does not exist. Try again.`);
process4.exit(1);
}
return resolvedCwd;
}
async function getConfigOrExit2(cwd) {
const config = await getConfig(cwd);
if (!config) {
handleConfigIsMissing();
process4.exit(1);
}
return config;
}
async function handleAllComponentsDiff(config, registryIndex) {
const targetDir = config.resolvedPaths.components;
const projectComponents = findProjectComponents(registryIndex, targetDir);
const componentsWithUpdates = await checkForUpdates(projectComponents, config);
if (!componentsWithUpdates.length) {
consola4.info("No updates found.");
process4.exit(0);
}
displayAvailableUpdates(componentsWithUpdates);
process4.exit(0);
}
function findProjectComponents(registryIndex, targetDir) {
return registryIndex.filter((item) => {
return item.files.some((file) => {
const fullPath = path6.resolve(targetDir, item.name, file);
return existsSync4(fullPath);
});
});
}
async function handleSingleComponentDiff(componentName, config, registryIndex) {
const component = registryIndex.find((item) => item.name === componentName);
if (!component) {
consola4.error(`The component ${colors3.green(componentName)} does not exist.`);
process4.exit(1);
}
const changes = await diffComponent(component, config);
if (!changes.length) {
consola4.info(`No updates found for ${componentName}.`);
process4.exit(0);
}
displayComponentChanges(changes);
}
async function checkForUpdates(components, config) {
const componentsWithUpdates = [];
for (const component of components) {
const changes = await diffComponent(component, config);
if (changes.length) {
componentsWithUpdates.push({
name: component.name,
changes
});
}
}
return componentsWithUpdates;
}
function displayAvailableUpdates(componentsWithUpdates) {
consola4.info("The following components have updates available:");
for (const component of componentsWithUpdates) {
consola4.info(`- ${component.name}`);
for (const change of component.changes) {
consola4.info(` - ${change.filePath}`);
}
}
consola4.log("");
consola4.info(`Run ${colors3.green("diff <component>")} to see the changes.`);
}
function displayComponentChanges(changes) {
for (const change of changes) {
consola4.info(`- ${change.filePath}`);
printDiff(change.patch);
consola4.log("");
}
}
async function diffComponent(component, config) {
const payload = await fetchTree(config.styleSystem, [component]);
const baseColor = await getRegistryBaseColor(config.baseColor);
const changes = [];
for (const item of payload) {
const targetDir = await getItemTargetPath(config, item);
if (!targetDir) {
continue;
}
await processItemFiles(item, targetDir, config, baseColor, changes);
}
return changes;
}
async function processItemFiles(item, targetDir, config, baseColor, changes) {
for (const file of item.files) {
const filePath = path6.resolve(targetDir, item.name, file.name);
if (!existsSync4(filePath)) {
continue;
}
const fileContent = await fs4.readFile(filePath, "utf8");
const registryContent = await transform({
filename: file.name,
raw: file.content,
config,
baseColor
});
const patch = diffLines(fileContent, registryContent);
if (patch.length > 1) {
changes.push({
file: file.name,
filePath,
patch
});
}
}
}
function printDiff(diff3) {
diff3.forEach((part) => {
if (part) {
if (part.added) {
process4.stdout.write(colors3.green(part.value));
return;
}
if (part.removed) {
process4.stdout.write(colors3.red(part.value));
return;
}
process4.stdout.write(part.value);
}
});
}
// src/commands/init.ts
import { existsSync as existsSync6, promises as fs8 } from "node:fs";
import process5 from "node:process";
import path14 from "pathe";
import { Command as Command3 } from "commander";
import { template } from "lodash-es";
import ora2 from "ora";
import prompts2 from "prompts";
import { consola as consola5 } from "consola";
import { colors as colors4 } from "consola/utils";
// ../../node_modules/.pnpm/prettier@3.5.0/node_modules/prettier/index.mjs
import { createRequire as __prettierCreateRequire } from "module";
import { fileURLToPath as __prettierFileUrlToPath } from "url";
import { dirname as __prettierDirname } from "path";
import process22 from "process";
import os from "os";
import tty from "tty";
import path9 from "path";
import { fileURLToPath, pathToFileURL } from "url";
import path42 from "path";
import * as path32 from "path";
import fs5 from "fs/promises";
import path22 from "path";
import * as path7 from "path";
import path8 from "path";
import fs22 from "fs/promises";
import fs32 from "fs/promises";
import { pathToFileURL as pathToFileURL2 } from "url";
import fs42 from "fs/promises";
import path72 from "path";
import { pathToFileURL as pathToFileURL4 } from "url";
import assert3 from "assert";
import { statSync, realpathSync } from "fs";
import process32 from "process";
import { URL as URL2, fileURLToPath as fileURLToPath4, pathToFileURL as pathToFileURL3 } from "url";
import path62 from "path";
import { builtinModules } from "module";
import { fileURLToPath as fileURLToPath3 } from "url";
import fs52 from "fs";
import path52 from "path";
import { fileURLToPath as fileURLToPath2 } from "url";
import v8 from "v8";
import assert2 from "assert";
import { format, inspect } from "util";
import { createRequire } from "module";
import path10 from "path";
import url from "url";
import fs6 from "fs";
import assert4 from "assert";
import assert5 from "assert";
import path12 from "path";
import { pathToFileURL as pathToFileURL5 } from "url";
import path11 from "path";
// ../../node_modules/.pnpm/prettier@3.5.0/node_modules/prettier/doc.mjs
var doc_exports = {};
__export(doc_exports, {
builders: () => builders,
default: () => public_default,
printer: () => printer,
utils: () => utils
});
var __defProp = Object.defineProperty;
var __export2 = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var public_exports = {};
__export2(public_exports, {
builders: () => builders,
printer: () => printer,
utils: () => utils
});
var DOC_TYPE_STRING = "string";
var DOC_TYPE_ARRAY = "array";
var DOC_TYPE_CURSOR = "cursor";
var DOC_TYPE_INDENT = "indent";
var DOC_TYPE_ALIGN = "align";
var DOC_TYPE_TRIM = "trim";
var DOC_TYPE_GROUP = "group";
var DOC_TYPE_FILL = "fill";
var DOC_TYPE_IF_BREAK = "if-break";
var DOC_TYPE_INDENT_IF_BREAK = "indent-if-break";
var DOC_TYPE_LINE_SUFFIX = "line-suffix";
var DOC_TYPE_LINE_SUFFIX_BOUNDARY = "line-suffix-boundary";
var DOC_TYPE_LINE = "line";
var DOC_TYPE_LABEL = "label";
var DOC_TYPE_BREAK_PARENT = "break-parent";
var VALID_OBJECT_DOC_TYPES = /* @__PURE__ */ new Set([
DOC_TYPE_CURSOR,
DOC_TYPE_INDENT,
DOC_TYPE_ALIGN,
DOC_TYPE_TRIM,
DOC_TYPE_GROUP,
DOC_TYPE_FILL,
DOC_TYPE_IF_BREAK,
DOC_TYPE_INDENT_IF_BREAK,
DOC_TYPE_LINE_SUFFIX,
DOC_TYPE_LINE_SUFFIX_BOUNDARY,
DOC_TYPE_LINE,
DOC_TYPE_LABEL,
DOC_TYPE_BREAK_PARENT
]);
var at = (isOptionalObject, object, index) => {
if (isOptionalObject && (object === void 0 || object === null)) {
return;
}
if (Array.isArray(object) || typeof object === "string") {
return object[index < 0 ? object.length + index : index];
}
return object.at(index);
};
var at_default = at;
function getDocType(doc) {
if (typeof doc === "string") {
return DOC_TYPE_STRING;
}
if (Array.isArray(doc)) {
return DOC_TYPE_ARRAY;
}
if (!doc) {
return;
}
const { type: type2 } = doc;
if (VALID_OBJECT_DOC_TYPES.has(type2)) {
return type2;
}
}
var get_doc_type_default = getDocType;
var disjunctionListFormat = (list) => new Intl.ListFormat("en-US", { type: "disjunction" }).format(list);
function getDocErrorMessage(doc) {
const type2 = doc === null ? "null" : typeof doc;
if (type2 !== "string" && type2 !== "object") {
return `Unexpected doc '${type2}',
Expected it to be 'string' or 'object'.`;
}
if (get_doc_type_default(doc)) {
throw new Error("doc is valid.");
}
const objectType = Object.prototype.toString.call(doc);
if (objectType !== "[object Object]") {
return `Unexpected doc '${objectType}'.`;
}
const EXPECTED_TYPE_VALUES = disjunctionListFormat(
[...VALID_OBJECT_DOC_TYPES].map((type22) => `'${type22}'`)
);
return `Unexpected doc.type '${doc.type}'.
Expected it to be ${EXPECTED_TYPE_VALUES}.`;
}
var InvalidDocError = class extends Error {
name = "InvalidDocError";
constructor(doc) {
super(getDocErrorMessage(doc));
this.doc = doc;
}
};
var invalid_doc_error_default = InvalidDocError;
var traverseDocOnExitStackMarker = {};
function traverseDoc(doc, onEnter, onExit, shouldTraverseConditionalGroups) {
const docsStack = [doc];
while (docsStack.length > 0) {
const doc2 = docsStack.pop();
if (doc2 === traverseDocOnExitStackMarker) {
onExit(docsStack.pop());
continue;
}
if (onExit) {
docsStack.push(doc2, traverseDocOnExitStackMarker);
}
const docType = get_doc_type_default(doc2);
if (!docType) {
throw new invalid_doc_error_default(doc2);
}
if ((onEnter == null ? void 0 : onEnter(doc2)) === false) {
continue;
}
switch (docType) {
case DOC_TYPE_ARRAY:
case DOC_TYPE_FILL: {
const parts = docType === DOC_TYPE_ARRAY ? doc2 : doc2.parts;
for (let ic = parts.length, i2 = ic - 1; i2 >= 0; --i2) {
docsStack.push(parts[i2]);
}
break;
}
case DOC_TYPE_IF_BREAK:
docsStack.push(doc2.flatContents, doc2.breakContents);
break;
case DOC_TYPE_GROUP:
if (shouldTraverseConditionalGroups && doc2.expandedStates) {
for (let ic = doc2.expandedStates.length, i2 = ic - 1; i2 >= 0; --i2) {
docsStack.push(doc2.expandedStates[i2]);
}
} else {
docsStack.push(doc2.contents);
}
break;
case DOC_TYPE_ALIGN:
case DOC_TYPE_INDENT:
case DOC_TYPE_INDENT_IF_BREAK:
case DOC_TYPE_LABEL:
case DOC_TYPE_LINE_SUFFIX:
docsStack.push(doc2.contents);
break;
case DOC_TYPE_STRING:
case DOC_TYPE_CURSOR:
case DOC_TYPE_TRIM:
case DOC_TYPE_LINE_SUFFIX_BOUNDARY:
case DOC_TYPE_LINE:
case DOC_TYPE_BREAK_PARENT:
break;
default:
throw new invalid_doc_error_default(doc2);
}
}
}
var traverse_doc_default = traverseDoc;
function mapDoc(doc, cb) {
if (typeof doc === "string") {
return cb(doc);
}
const mapped = /* @__PURE__ */ new Map();
return rec(doc);
function rec(doc2) {
if (mapped.has(doc2)) {
return mapped.get(doc2);
}
const result = process23(doc2);
mapped.set(doc2, result);
return result;
}
function process23(doc2) {
switch (get_doc_type_default(doc2)) {
case DOC_TYPE_ARRAY:
return cb(doc2.map(rec));
case DOC_TYPE_FILL:
return cb({ ...doc2, parts: doc2.parts.map(rec) });
case DOC_TYPE_IF_BREAK:
return cb({
...doc2,
breakContents: rec(doc2.breakContents),
flatContents: rec(doc2.flatContents)
});
case DOC_TYPE_GROUP: {
let { expandedStates, contents } = doc2;
if (expandedStates) {
expandedStates = expandedStates.map(rec);
contents = expandedStates[0];
} else {
contents = rec(contents);
}
return cb({ ...doc2, contents, expandedStates });
}
case DOC_TYPE_ALIGN:
case DOC_TYPE_INDENT:
case DOC_TYPE_INDENT_IF_BREAK:
case DOC_TYPE_LABEL:
case DOC_TYPE_LINE_SUFFIX:
return cb({ ...doc2, contents: rec(doc2.contents) });
case DOC_TYPE_STRING:
case DOC_TYPE_CURSOR:
case DOC_TYPE_TRIM:
case DOC_TYPE_LINE_SUFFIX_BOUNDARY:
case DOC_TYPE_LINE:
case DOC_TYPE_BREAK_PARENT:
return cb(doc2);
default:
throw new invalid_doc_error_default(doc2);
}
}
}
function findInDoc(doc, fn, defaultValue) {
let result = defaultValue;
let shouldSkipFurtherProcessing = false;
function findInDocOnEnterFn(doc2) {
if (shouldSkipFurtherProcessing) {
return false;
}
const maybeResult = fn(doc2);
if (maybeResult !== void 0) {
shouldSkipFurtherProcessing = true;
result = maybeResult;
}
}
traverse_doc_default(doc, findInDocOnEnterFn);
return result;
}
function willBreakFn(doc) {
if (doc.type === DOC_TYPE_GROUP && doc.break) {
return true;
}
if (doc.type === DOC_TYPE_LINE && doc.hard) {
return true;
}
if (doc.type === DOC_TYPE_BREAK_PARENT) {
return true;
}
}
function willBreak(doc) {
return findInDoc(doc, willBreakFn, false);
}
function breakParentGroup(groupStack) {
if (groupStack.length > 0) {
const parentGroup = at_default(
/* isOptionalObject */
false,
groupStack,
-1
);
if (!parentGroup.expandedStates && !parentGroup.break) {
parentGroup.break = "propagated";
}
}
return null;
}
function propagateBreaks(doc) {
const alreadyVisitedSet = /* @__PURE__ */ new Set();
const groupStack = [];
function propagateBreaksOnEnterFn(doc2) {
if (doc2.type === DOC_TYPE_BREAK_PARENT) {
breakParentGroup(groupStack);
}
if (doc2.type === DOC_TYPE_GROUP) {
groupStack.push(doc2);
if (alreadyVisitedSet.has(doc2)) {
return false;
}
alreadyVisitedSet.add(doc2);
}
}
function propagateBreaksOnExitFn(doc2) {
if (doc2.type === DOC_TYPE_GROUP) {
const group2 = groupStack.pop();
if (group2.break) {
breakParentGroup(groupStack);
}
}
}
traverse_doc_default(
doc,
propagateBreaksOnEnterFn,
propagateBreaksOnExitFn,
/* shouldTraverseConditionalGroups */
true
);
}
function removeLinesFn(doc) {
if (doc.type === DOC_TYPE_LINE && !doc.hard) {
return doc.soft ? "" : " ";
}
if (doc.type === DOC_TYPE_IF_BREAK) {
return doc.flatContents;
}
return doc;
}
function removeLines(doc) {
return mapDoc(doc, removeLinesFn);
}
function stripTrailingHardlineFromParts(parts) {
parts = [...parts];
while (parts.length >= 2 && at_default(
/* isOptionalObject */
false,
parts,
-2
).type === DOC_TYPE_LINE && at_default(
/* isOptionalObject */
false,
parts,
-1
).type === DOC_TYPE_BREAK_PARENT) {
parts.length -= 2;
}
if (parts.length > 0) {
const lastPart = stripTrailingHardlineFromDoc(at_default(
/* isOptionalObject */
false,
parts,
-1
));
parts[parts.length - 1] = lastPart;
}
return parts;
}
function stripTrailingHardlineFromDoc(doc) {
switch (get_doc_type_default(doc)) {
case DOC_TYPE_INDENT:
case DOC_TYPE_INDENT_IF_BREAK:
case DOC_TYPE_GROUP:
case DOC_TYPE_LINE_SUFFIX:
case DOC_TYPE_LABEL: {
const contents = stripTrailingHardlineFromDoc(doc.contents);
return { ...doc, contents };
}
case DOC_TYPE_IF_BREAK:
return {
...doc,
breakContents: stripTrailingHardlineFromDoc(doc.breakContents),
flatContents: stripTrailingHardlineFromDoc(doc.flatContents)
};
case DOC_TYPE_FILL:
return { ...doc, parts: stripTrailingHardlineFromParts(doc.parts) };
case DOC_TYPE_ARRAY:
return stripTrailingHardlineFromParts(doc);
case DOC_TYPE_STRING:
return doc.replace(/[\n\r]*$/u, "");
case DOC_TYPE_ALIGN:
case DOC_TYPE_CURSOR:
case DOC_TYPE_TRIM:
case