@cerberus-design/styled-system
Version:
Cerberus Design System Panda-CSS styled-system.
518 lines (513 loc) • 24.4 kB
JavaScript
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/cli-main.ts
var cli_main_exports = {};
__export(cli_main_exports, {
main: () => main
});
module.exports = __toCommonJS(cli_main_exports);
var import_config = require("@pandacss/config");
var import_logger = require("@pandacss/logger");
var import_node = require("@pandacss/node");
var import_shared = require("@pandacss/shared");
var import_cac = require("cac");
var import_path = require("path");
// package.json
var version = "0.53.0";
// src/interactive.ts
var p = __toESM(require("@clack/prompts"));
var interactive = async () => {
p.intro(`panda v${version}`);
const initFlags = await p.group(
{
usePostcss: () => p.select({
message: "Would you like to use PostCSS ?",
initialValue: "yes",
options: [
{ value: "yes", label: "Yes" },
{ value: "no", label: "No" }
]
}),
useMjsExtension: () => p.select({
message: "Use the mjs extension ?",
initialValue: "yes",
options: [
{ value: "yes", label: "Yes" },
{ value: "no", label: "No" }
]
}),
jsxOptions: () => p.group({
styleProps: () => p.select({
message: "Would you like to use JSX Style Props ?",
initialValue: "yes",
options: [
{ value: "yes", label: "Yes" },
{ value: "no", label: "No" }
]
}),
jsxFramework: () => p.select({
message: "What JSX framework?",
initialValue: "react",
options: [
{ value: "react", label: "React" },
{ value: "vue", label: "Vue" },
{ value: "solid", label: "Solid" },
{ value: "qwik", label: "Qwik" }
]
})
}),
whatSyntax: () => p.select({
message: "What css syntax would you like to use?",
initialValue: "object",
options: [
{ value: "object-literal", label: "Object" },
{ value: "template-literal", label: "Template literal" }
]
}),
withStrictTokens: () => p.select({
message: "Use strict tokens to enforce full type-safety?",
initialValue: "no",
options: [
{ value: "yes", label: "Yes" },
{ value: "no", label: "No" }
]
}),
shouldUpdateGitignore: () => p.select({
message: "Update gitignore?",
initialValue: "yes",
options: [
{ value: "yes", label: "Yes" },
{ value: "no", label: "No" }
]
})
},
{
// On Cancel callback that wraps the group
// So if the user cancels one of the prompts in the group this function will be called
onCancel: () => {
p.cancel("Operation cancelled.");
process.exit(0);
}
}
);
p.outro("Let's get started! \u{1F43C}");
return {
postcss: initFlags.usePostcss === "yes",
outExtension: initFlags.useMjsExtension === "yes" ? "mjs" : "js",
jsxFramework: initFlags.jsxOptions.jsxFramework,
syntax: initFlags.whatSyntax,
strictTokens: initFlags.withStrictTokens === "yes",
gitignore: initFlags.shouldUpdateGitignore === "yes"
};
};
// src/cli-main.ts
async function main() {
const cli = (0, import_cac.cac)("panda");
const cwd = process.cwd();
cli.command("init", "Initialize the panda's config file").option("-i, --interactive", "Run in interactive mode", { default: false }).option("-f, --force", "Force overwrite existing config file").option("-p, --postcss", "Emit postcss config file").option("-c, --config <path>", "Path to panda config file").option("--cwd <cwd>", "Current working directory", { default: cwd }).option("--silent", "Suppress all messages except errors").option("--no-gitignore", "Don't update the .gitignore").option("--no-codegen", "Don't run the codegen logic").option("--out-extension <ext>", "The extension of the generated js files (default: 'mjs')").option("--outdir <dir>", "The output directory for the generated files").option("--jsx-framework <framework>", "The jsx framework to use").option("--syntax <syntax>", "The css syntax preference").option("--strict-tokens", "Using strictTokens: true").option("--logfile <file>", "Outputs logs to a file").action(async (initFlags = {}) => {
let options = {};
if (initFlags.interactive) {
options = await interactive();
}
const flags = { ...initFlags, ...options };
const { force, postcss, silent, gitignore, outExtension, jsxFramework, config: configPath, syntax } = flags;
const cwd2 = (0, import_path.resolve)(flags.cwd ?? "");
if (silent) {
import_logger.logger.level = "silent";
}
const stream = (0, import_node.setLogStream)({ cwd: cwd2, logfile: flags.logfile });
import_logger.logger.info("cli", `Panda v${version}
`);
const done = import_logger.logger.time.info("\u2728 Panda initialized");
if (postcss) {
await (0, import_node.setupPostcss)(cwd2);
}
await (0, import_node.setupConfig)(
cwd2,
(0, import_shared.compact)({
force,
outExtension,
jsxFramework,
syntax,
outdir: flags.outdir
})
);
const ctx = await (0, import_node.loadConfigAndCreateContext)({
cwd: cwd2,
configPath,
config: (0, import_shared.compact)({ gitignore, outdir: flags.outdir })
});
if (gitignore) {
(0, import_node.setupGitIgnore)(ctx);
}
if (flags.codegen) {
const { msg, box } = await (0, import_node.codegen)(ctx);
import_logger.logger.log(msg + box);
} else {
import_logger.logger.log(ctx.initMessage());
}
done();
stream.end();
});
cli.command("codegen", "Generate the panda system").option("--silent", "Don't print any logs").option("--clean", "Clean the output directory before generating").option("-c, --config <path>", "Path to panda config file").option("-w, --watch", "Watch files and rebuild").option("-p, --poll", "Use polling instead of filesystem events when watching").option("--cwd <cwd>", "Current working directory", { default: cwd }).option("--cpu-prof", "Generates a `.cpuprofile` to help debug performance issues").option("--logfile <file>", "Outputs logs to a file").action(async (flags) => {
const { silent, clean, config: configPath, watch, poll } = flags;
const cwd2 = (0, import_path.resolve)(flags.cwd ?? "");
const stream = (0, import_node.setLogStream)({ cwd: cwd2, logfile: flags.logfile });
let stopProfiling = () => void 0;
if (flags.cpuProf) {
stopProfiling = await (0, import_node.startProfiling)(cwd2, "codegen", flags.watch);
}
if (silent) {
import_logger.logger.level = "silent";
}
let ctx = await (0, import_node.loadConfigAndCreateContext)({
cwd: cwd2,
config: { clean },
configPath
});
const { msg } = await (0, import_node.codegen)(ctx);
import_logger.logger.log(msg);
if (watch) {
ctx.watchConfig(
async () => {
const affecteds = await ctx.diff.reloadConfigAndRefreshContext((conf) => {
ctx = new import_node.PandaContext(conf);
});
await ctx.hooks["config:change"]?.({ config: ctx.config, changes: affecteds });
await (0, import_node.codegen)(ctx, Array.from(affecteds.artifacts));
import_logger.logger.info("ctx:updated", "config rebuilt \u2705");
},
{ cwd: cwd2, poll }
);
} else {
stream.end();
}
stopProfiling();
});
cli.command(
"cssgen [globOrType]",
"Generate the css from files, or generate the css from the specified type which can be: preflight, tokens, static, global, keyframes"
).option("--silent", "Don't print any logs").option("-m, --minify", "Minify generated code").option("--clean", "Clean the output before generating").option("-c, --config <path>", "Path to panda config file").option("-w, --watch", "Watch files and rebuild").option("--minimal", "Do not include CSS generation for theme tokens, preflight, keyframes, static and global css").option("--lightningcss", "Use `lightningcss` instead of `postcss` for css optimization.").option("--polyfill", "Polyfill CSS @layers at-rules for older browsers.").option("-p, --poll", "Use polling instead of filesystem events when watching").option("-o, --outfile [file]", "Output file for extracted css, default to './styled-system/styles.css'").option("--cwd <cwd>", "Current working directory", { default: cwd }).option("--cpu-prof", "Generates a `.cpuprofile` to help debug performance issues").option("--logfile <file>", "Outputs logs to a file").action(async (maybeGlob, flags = {}) => {
const { silent, config: configPath, outfile, watch, poll, minimal, ...rest } = flags;
const cwd2 = (0, import_path.resolve)(flags.cwd ?? "");
const stream = (0, import_node.setLogStream)({ cwd: cwd2, logfile: flags.logfile });
let stopProfiling = () => void 0;
if (flags.cpuProf) {
stopProfiling = await (0, import_node.startProfiling)(cwd2, "cssgen", flags.watch);
}
const cssArtifact = ["preflight", "tokens", "static", "global", "keyframes"].find(
(type) => type === maybeGlob
);
const glob = cssArtifact ? void 0 : maybeGlob;
if (silent) {
import_logger.logger.level = "silent";
}
const overrideConfig = {
...rest,
...glob ? { include: [glob] } : void 0
};
let ctx = await (0, import_node.loadConfigAndCreateContext)({
cwd: cwd2,
config: overrideConfig,
configPath
});
const options = {
cwd: cwd2,
outfile,
type: cssArtifact,
minimal
};
await (0, import_node.cssgen)(ctx, options);
if (watch) {
ctx.watchConfig(
async () => {
const affecteds = await ctx.diff.reloadConfigAndRefreshContext((conf) => {
ctx = new import_node.PandaContext(conf);
});
await ctx.hooks["config:change"]?.({ config: ctx.config, changes: affecteds });
await (0, import_node.cssgen)(ctx, options);
import_logger.logger.info("ctx:updated", "config rebuilt \u2705");
},
{ cwd: cwd2, poll }
);
ctx.watchFiles(async (event, file) => {
if (event === "unlink") {
ctx.project.removeSourceFile(ctx.runtime.path.abs(cwd2, file));
} else if (event === "change") {
ctx.project.reloadSourceFile(file);
await (0, import_node.cssgen)(ctx, options);
} else if (event === "add") {
ctx.project.createSourceFile(file);
await (0, import_node.cssgen)(ctx, options);
}
});
} else {
stream.end();
stopProfiling();
}
});
cli.command("[files]", "Include file glob", { ignoreOptionDefaultValue: true }).option("-o, --outdir <dir>", "Output directory", { default: "styled-system" }).option("-m, --minify", "Minify generated code").option("-w, --watch", "Watch files and rebuild").option("-p, --poll", "Use polling instead of filesystem events when watching").option("-c, --config <path>", "Path to panda config file").option("--cwd <cwd>", "Current working directory", { default: cwd }).option("--preflight", "Enable css reset").option("--silent", "Suppress all messages except errors").option("-e, --exclude <files>", "Exclude files", { default: [] }).option("--clean", "Clean output directory").option("--hash", "Hash the generated classnames to make them shorter").option("--lightningcss", "Use `lightningcss` instead of `postcss` for css optimization.").option("--polyfill", "Polyfill CSS @layers at-rules for older browsers.").option("--emitTokensOnly", "Whether to only emit the `tokens` directory").option("--cpu-prof", "Generates a `.cpuprofile` to help debug performance issues").option("--logfile <file>", "Outputs logs to a file").action(async (files, flags) => {
const { config: configPath, silent, ...rest } = flags;
const cwd2 = (0, import_path.resolve)(flags.cwd ?? "");
const stream = (0, import_node.setLogStream)({ cwd: cwd2, logfile: flags.logfile });
let stopProfiling = () => void 0;
if (flags.cpuProf) {
stopProfiling = await (0, import_node.startProfiling)(cwd2, "cli", flags.watch);
}
if (silent) {
import_logger.logger.level = "silent";
}
const config = (0, import_shared.compact)({ include: files, ...rest, cwd: cwd2 });
await (0, import_node.generate)(config, configPath);
stopProfiling();
if (!flags.watch) {
stream.end();
}
});
cli.command("studio", "Realtime documentation for your design tokens").option("--build", "Build").option("--preview", "Preview").option("--port <port>", "Port").option("--host", "Host").option("-c, --config <path>", "Path to panda config file").option("--cwd <cwd>", "Current working directory", { default: cwd }).option("--outdir <dir>", "Output directory for static files").option("--base <path>", "Base path of project").action(async (flags) => {
const { build, preview, port, host, outdir, config, base } = flags;
const cwd2 = (0, import_path.resolve)(flags.cwd ?? "");
const ctx = await (0, import_node.loadConfigAndCreateContext)({
cwd: cwd2,
configPath: config
});
const buildOpts = {
configPath: (0, import_config.findConfig)({ cwd: cwd2, file: config }),
outDir: (0, import_path.resolve)(outdir || ctx.studio.outdir),
port,
host,
base
};
let studio;
try {
const studioPath = require.resolve("@pandacss/studio", { paths: [cwd2] });
studio = require(studioPath);
} catch (error) {
import_logger.logger.error("studio", error);
throw new import_shared.PandaError("MISSING_STUDIO", "You need to install '@pandacss/studio' to use this command");
}
if (preview) {
await studio.previewStudio(buildOpts);
} else if (build) {
await studio.buildStudio(buildOpts);
} else {
await studio.serveStudio(buildOpts);
const note = `use ${import_logger.colors.reset(import_logger.colors.bold("--build"))} to build`;
const port2 = `use ${import_logger.colors.reset(import_logger.colors.bold("--port"))} for a different port`;
import_logger.logger.log(import_logger.colors.dim(` ${import_logger.colors.green("\u279C")} ${import_logger.colors.bold("Build")}: ${note}`));
import_logger.logger.log(import_logger.colors.dim(` ${import_logger.colors.green("\u279C")} ${import_logger.colors.bold("Port")}: ${port2}`));
}
});
cli.command("analyze [glob]", "Analyze design token usage in glob").option("--outfile [filepath]", "Output analyze report in JSON").option("--silent", "Don't print any logs").option("--scope <type>", "Select analysis scope (token or recipe)").option("-c, --config <path>", "Path to panda config file").option("--cwd <cwd>", "Current working directory", { default: cwd }).action(async (maybeGlob, flags = {}) => {
const { silent, config: configPath, scope } = flags;
const tokenScope = scope == null || scope === "token";
const recipeScope = scope == null || scope === "recipe";
const cwd2 = (0, import_path.resolve)(flags.cwd);
if (silent) {
import_logger.logger.level = "silent";
}
const ctx = await (0, import_node.loadConfigAndCreateContext)({
cwd: cwd2,
config: maybeGlob ? { include: [maybeGlob] } : void 0,
configPath
});
const result = (0, import_node.analyze)(ctx);
if (flags?.outfile && typeof flags.outfile === "string") {
await result.writeReport(flags.outfile);
import_logger.logger.info("cli", `JSON report saved to ${(0, import_path.resolve)(flags.outfile)}`);
return;
}
if (tokenScope) {
if (!ctx.tokens.isEmpty) {
const tokenAnalysis = result.getTokenReport();
import_logger.logger.info("analyze:tokens", `Token usage report \u{1F3A8}
${tokenAnalysis.formatted}`);
} else {
import_logger.logger.info("analyze:tokens", "No tokens found");
}
}
if (recipeScope) {
if (!ctx.recipes.isEmpty()) {
const recipeAnalysis = result.getRecipeReport();
import_logger.logger.info("analyze:recipes", `Config recipes usage report \u{1F39B}\uFE0F
${recipeAnalysis.formatted}`);
} else {
import_logger.logger.info("analyze:recipes", "No config recipes found");
}
}
});
cli.command("debug [glob]", "Debug design token extraction & css generated from files in glob").option("--silent", "Don't print any logs").option("--dry", "Output debug files in stdout without writing to disk").option("--outdir [dir]", "Output directory for debug files, default to './styled-system/debug'").option("--only-config", "Should only output the config file, default to 'false'").option("-c, --config <path>", "Path to panda config file").option("--cwd <cwd>", "Current working directory", { default: cwd }).option("--cpu-prof", "Generates a `.cpuprofile` to help debug performance issues").option("--logfile <file>", "Outputs logs to a file").action(async (maybeGlob, flags = {}) => {
const { silent, dry = false, outdir: outdirFlag, config: configPath } = flags ?? {};
const cwd2 = (0, import_path.resolve)(flags.cwd);
const stream = (0, import_node.setLogStream)({ cwd: cwd2, logfile: flags.logfile });
let stopProfiling = () => void 0;
if (flags.cpuProf) {
stopProfiling = await (0, import_node.startProfiling)(cwd2, "debug");
}
if (silent) {
import_logger.logger.level = "silent";
}
const ctx = await (0, import_node.loadConfigAndCreateContext)({
cwd: cwd2,
config: maybeGlob ? { include: [maybeGlob] } : void 0,
configPath
});
const outdir = outdirFlag ?? (0, import_path.join)(...ctx.paths.root, "debug");
await (0, import_node.debug)(ctx, { outdir, dry, onlyConfig: flags.onlyConfig });
stopProfiling();
stream.end();
});
cli.command("ship [glob]", "Ship extract result from files in glob").option("--silent", "Don't print any logs").option(
"--o, --outfile [file]",
"Output path for the build info file, default to './styled-system/panda.buildinfo.json'"
).option("-m, --minify", "Minify generated JSON file").option("-c, --config <path>", "Path to panda config file").option("--cwd <cwd>", "Current working directory", { default: cwd }).option("-w, --watch", "Watch files and rebuild").option("-p, --poll", "Use polling instead of filesystem events when watching").action(async (maybeGlob, flags = {}) => {
const { silent, outfile: outfileFlag, minify, config: configPath, watch, poll } = flags;
const cwd2 = (0, import_path.resolve)(flags.cwd);
if (silent) {
import_logger.logger.level = "silent";
}
let ctx = await (0, import_node.loadConfigAndCreateContext)({
cwd: cwd2,
config: maybeGlob ? { include: [maybeGlob] } : void 0,
configPath
});
const outfile = outfileFlag ?? (0, import_path.join)(...ctx.paths.root, "panda.buildinfo.json");
if (minify) {
ctx.config.minify = true;
}
await (0, import_node.buildInfo)(ctx, outfile);
if (watch) {
ctx.watchConfig(
async () => {
const affecteds = await ctx.diff.reloadConfigAndRefreshContext((conf) => {
ctx = new import_node.PandaContext(conf);
});
await ctx.hooks["config:change"]?.({ config: ctx.config, changes: affecteds });
await (0, import_node.buildInfo)(ctx, outfile);
import_logger.logger.info("ctx:updated", "config rebuilt \u2705");
},
{ cwd: cwd2, poll }
);
ctx.watchFiles(async (event, file) => {
if (event === "unlink") {
ctx.project.removeSourceFile(ctx.runtime.path.abs(cwd2, file));
} else if (event === "change") {
ctx.project.reloadSourceFile(file);
await (0, import_node.buildInfo)(ctx, outfile);
} else if (event === "add") {
ctx.project.createSourceFile(file);
await (0, import_node.buildInfo)(ctx, outfile);
}
});
}
});
cli.command("emit-pkg", "Emit package.json with entrypoints").option("--outdir <dir>", "Output directory", { default: "." }).option("--base <source>", "The base directory of the package.json entrypoints").option("--silent", "Don't print any logs").option("--cwd <cwd>", "Current working directory", { default: cwd }).action(async (flags) => {
const { outdir, silent, base } = flags;
if (silent) {
import_logger.logger.level = "silent";
}
const cwd2 = (0, import_path.resolve)(flags.cwd);
const ctx = await (0, import_node.loadConfigAndCreateContext)({
cwd: cwd2,
config: { cwd: cwd2 }
});
const pkgPath = (0, import_path.resolve)(cwd2, outdir, "package.json");
const exists = ctx.runtime.fs.existsSync(pkgPath);
const exports2 = [];
const createDir = (...dir) => {
return [".", base, ...dir].filter(Boolean).join("/");
};
const createEntry = (dir) => ({
types: ctx.file.extDts(createDir(dir, "index")),
require: ctx.file.ext(createDir(dir, "index")),
import: ctx.file.ext(createDir(dir, "index"))
});
exports2.push(
["./css", createEntry("css")],
["./tokens", createEntry("tokens")],
["./types", createEntry("types")]
);
if (!ctx.patterns.isEmpty()) {
exports2.push(["./patterns", createEntry("patterns")]);
}
if (!ctx.recipes.isEmpty()) {
exports2.push(["./recipes", createEntry("recipes")]);
}
if (!ctx.patterns.isEmpty()) {
exports2.push(["./jsx", createEntry("jsx")]);
}
if (ctx.config.themes) {
exports2.push(["./themes", createEntry("themes")]);
}
const stylesDir = createDir("styles.css");
if (!exists) {
const content = {
name: outdir,
description: "This package is auto-generated by Panda CSS",
version: "0.1.0",
type: "module",
keywords: ["pandacss", "styled-system", "codegen"],
license: "ISC",
exports: {
...Object.fromEntries(exports2),
"./styles.css": stylesDir
},
scripts: {
prepare: "panda codegen --clean"
}
};
await ctx.runtime.fs.writeFile(pkgPath, JSON.stringify(content, null, 2));
} else {
const content = JSON.parse(ctx.runtime.fs.readFileSync(pkgPath));
content.exports = {
...content.exports,
...Object.fromEntries(exports2),
"./styles.css": stylesDir
};
await ctx.runtime.fs.writeFile(pkgPath, JSON.stringify(content, null, 2));
}
import_logger.logger.info("cli", `Emit package.json to ${pkgPath}`);
});
cli.help();
cli.version(version);
cli.parse(process.argv, { run: false });
try {
await cli.runMatchedCommand();
} catch (error) {
import_logger.logger.error("cli", error);
if (import_logger.logger.isDebug) {
console.error(error);
}
process.exit(1);
}
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
main
});