bejamas 0.2.10 → 0.2.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
- import { S as BASE_COLORS, _ as getWorkspaceConfig, b as logger, d as parseJsDocMetadata, g as getConfig, o as extractFrontmatter, p as resolveUiRoot, v as getProjectInfo, x as highlighter, y as spinner } from "./utils-gYZJgF4G.js";
2
+ import { _ as getWorkspaceConfig, b as highlighter, d as parseJsDocMetadata, g as getConfig, o as extractFrontmatter, p as resolveUiRoot, v as spinner, y as logger } from "./utils-BfJTJvcy.js";
3
3
  import { Command } from "commander";
4
4
  import { createRequire } from "module";
5
5
  import path from "path";
6
- import fsExtra from "fs-extra";
6
+ import fs from "fs-extra";
7
7
  import os from "os";
8
8
  import dotenv from "dotenv";
9
9
  import { detect } from "@antfu/ni";
@@ -14,7 +14,7 @@ import prompts from "prompts";
14
14
  import fg from "fast-glob";
15
15
  import path$1, { extname as extname$1, isAbsolute, join as join$1, relative as relative$1, resolve } from "node:path";
16
16
  import { existsSync, readFileSync, readdirSync } from "node:fs";
17
- import fs from "node:fs/promises";
17
+ import fs$1 from "node:fs/promises";
18
18
 
19
19
  //#region src/utils/errors.ts
20
20
  const MISSING_DIR_OR_EMPTY_PROJECT = "1";
@@ -23,7 +23,7 @@ const MISSING_DIR_OR_EMPTY_PROJECT = "1";
23
23
  //#region src/preflights/preflight-init.ts
24
24
  async function preFlightInit(options) {
25
25
  const errors = {};
26
- if (!fsExtra.existsSync(options.cwd) || !fsExtra.existsSync(path.resolve(options.cwd, "package.json"))) {
26
+ if (!fs.existsSync(options.cwd) || !fs.existsSync(path.resolve(options.cwd, "package.json"))) {
27
27
  errors[MISSING_DIR_OR_EMPTY_PROJECT] = true;
28
28
  return {
29
29
  errors,
@@ -61,12 +61,6 @@ async function getPackageManager(targetDir, { withFallback } = { withFallback: f
61
61
  if (userAgent.startsWith("bun")) return "bun";
62
62
  return "npm";
63
63
  }
64
- async function getPackageRunner(cwd) {
65
- const packageManager = await getPackageManager(cwd);
66
- if (packageManager === "pnpm") return "pnpm dlx";
67
- if (packageManager === "bun") return "bunx";
68
- return "npx";
69
- }
70
64
 
71
65
  //#endregion
72
66
  //#region src/registry/errors.ts
@@ -205,7 +199,7 @@ async function createProject(options) {
205
199
  const packageManager = await getPackageManager(options.cwd, { withFallback: true });
206
200
  const projectPath = `${options.cwd}/${projectName}`;
207
201
  try {
208
- await fsExtra.access(options.cwd, fsExtra.constants.W_OK);
202
+ await fs.access(options.cwd, fs.constants.W_OK);
209
203
  } catch (error) {
210
204
  logger.break();
211
205
  logger.error(`The path ${highlighter.info(options.cwd)} is not writable.`);
@@ -213,7 +207,7 @@ async function createProject(options) {
213
207
  logger.break();
214
208
  process.exit(1);
215
209
  }
216
- if (fsExtra.existsSync(path.resolve(options.cwd, projectName, "package.json"))) {
210
+ if (fs.existsSync(path.resolve(options.cwd, projectName, "package.json"))) {
217
211
  logger.break();
218
212
  logger.error(`A project with the name ${highlighter.info(projectName)} already exists.`);
219
213
  logger.error(`Please choose a different name and try again.`);
@@ -241,7 +235,7 @@ async function createProjectFromTemplate(projectPath, options) {
241
235
  try {
242
236
  dotenv.config({ quiet: true });
243
237
  const templatePath = path.join(os.tmpdir(), `bejamas-template-${Date.now()}`);
244
- await fsExtra.ensureDir(templatePath);
238
+ await fs.ensureDir(templatePath);
245
239
  const authToken = process.env.GITHUB_TOKEN || process.env.GH_TOKEN;
246
240
  const usedAuth = Boolean(authToken);
247
241
  const headers = { "User-Agent": "bejamas-cli" };
@@ -253,7 +247,7 @@ async function createProjectFromTemplate(projectPath, options) {
253
247
  throw new Error(`Failed to download template: ${response.status} ${response.statusText}`);
254
248
  }
255
249
  const tarPath = path.resolve(templatePath, "template.tar.gz");
256
- await fsExtra.writeFile(tarPath, Buffer.from(await response.arrayBuffer()));
250
+ await fs.writeFile(tarPath, Buffer.from(await response.arrayBuffer()));
257
251
  const tarSubpath = TEMPLATE_TAR_SUBPATH[options.templateKey];
258
252
  const leafName = tarSubpath.split("/").pop();
259
253
  await execa("tar", [
@@ -265,8 +259,8 @@ async function createProjectFromTemplate(projectPath, options) {
265
259
  tarSubpath
266
260
  ]);
267
261
  const extractedPath = path.resolve(templatePath, leafName);
268
- await fsExtra.move(extractedPath, projectPath);
269
- await fsExtra.remove(templatePath);
262
+ await fs.move(extractedPath, projectPath);
263
+ await fs.remove(templatePath);
270
264
  await execa(options.packageManager, ["install"], { cwd: projectPath });
271
265
  try {
272
266
  const { stdout } = await execa("git", ["rev-parse", "--is-inside-work-tree"], { cwd: projectPath });
@@ -287,9 +281,39 @@ async function createProjectFromTemplate(projectPath, options) {
287
281
  }
288
282
  }
289
283
 
284
+ //#endregion
285
+ //#region src/utils/shadcn-cli.ts
286
+ const require = createRequire(import.meta.url);
287
+ const PINNED_SHADCN_VERSION = "3.8.5";
288
+ const PINNED_SHADCN_PACKAGE = `shadcn@${PINNED_SHADCN_VERSION}`;
289
+ function resolveBundledShadcnEntrypoint() {
290
+ try {
291
+ return require.resolve("shadcn");
292
+ } catch {
293
+ return null;
294
+ }
295
+ }
296
+ function buildPinnedShadcnInvocation(shadcnArgs, bundledEntrypoint = resolveBundledShadcnEntrypoint()) {
297
+ if (bundledEntrypoint) return {
298
+ cmd: process.execPath,
299
+ args: [bundledEntrypoint, ...shadcnArgs],
300
+ source: "bundled"
301
+ };
302
+ return {
303
+ cmd: "npx",
304
+ args: [
305
+ "-y",
306
+ PINNED_SHADCN_PACKAGE,
307
+ ...shadcnArgs
308
+ ],
309
+ source: "fallback"
310
+ };
311
+ }
312
+
290
313
  //#endregion
291
314
  //#region src/commands/init.ts
292
315
  const DEFAULT_REGISTRY_URL$1 = "https://ui.bejamas.com/r";
316
+ const DEFAULT_COMPONENTS_BASE_COLOR = "neutral";
293
317
  const initOptionsSchema = z.object({
294
318
  cwd: z.string(),
295
319
  components: z.array(z.string()).optional(),
@@ -304,12 +328,16 @@ const initOptionsSchema = z.object({
304
328
  if (val) return TEMPLATES[val];
305
329
  return true;
306
330
  }, { message: "Invalid template. Please use 'next' or 'next-monorepo'." }),
307
- baseColor: z.string().optional().refine((val) => {
308
- if (val) return BASE_COLORS.find((color) => color.name === val);
309
- return true;
310
- }, { message: `Invalid base color. Please use '${BASE_COLORS.map((color) => color.name).join("', '")}'` }),
331
+ baseColor: z.string().optional(),
311
332
  baseStyle: z.boolean()
312
333
  });
334
+ function buildShadcnInitArgs(baseColor = DEFAULT_COMPONENTS_BASE_COLOR) {
335
+ return [
336
+ "init",
337
+ "--base-color",
338
+ baseColor
339
+ ];
340
+ }
313
341
  const init = new Command().name("init").description("initialize your project and install dependencies").argument("[components...]", "names, url or local path to component").option("-t, --template <template>", "the template to use. (next, next-monorepo)").option("-b, --base-color <base-color>", "the base color to use. (neutral, gray, zinc, stone, slate)", void 0).option("-y, --yes", "skip confirmation prompt.", true).option("-d, --defaults,", "use default configuration.", false).option("-f, --force", "force overwrite of existing configuration.", false).option("-c, --cwd <cwd>", "the working directory. defaults to the current directory.", process.cwd()).option("-s, --silent", "mute output.", false).option("--src-dir", "use the src directory when creating a new project.", false).option("--no-src-dir", "do not use the src directory when creating a new project.").option("--css-variables", "use css variables for theming.", true).option("--no-css-variables", "do not use css variables for theming.").option("--no-base-style", "do not install the base shadcn style.").action(async (_components, opts) => {
314
342
  try {
315
343
  await runInit(opts);
@@ -323,16 +351,14 @@ const init = new Command().name("init").description("initialize your project and
323
351
  async function runInit(options) {
324
352
  let newProjectTemplate;
325
353
  if (!options.skipPreflight) {
326
- const preflight = await preFlightInit(options);
327
- if (preflight.errors[MISSING_DIR_OR_EMPTY_PROJECT]) {
354
+ if ((await preFlightInit(options)).errors[MISSING_DIR_OR_EMPTY_PROJECT]) {
328
355
  const { projectPath, template } = await createProject(options);
329
356
  if (!projectPath) process.exit(1);
330
357
  options.cwd = projectPath;
331
358
  options.isNewProject = true;
332
359
  newProjectTemplate = template;
333
360
  }
334
- preflight.projectInfo;
335
- } else await getProjectInfo(options.cwd);
361
+ }
336
362
  if (newProjectTemplate) {
337
363
  options.cwd = path.resolve(options.cwd, {
338
364
  "astro-monorepo": "apps/web",
@@ -342,29 +368,13 @@ async function runInit(options) {
342
368
  logger.log(`${highlighter.success("Success!")} Project initialization completed.\nYou may now add components.`);
343
369
  return await getConfig(options.cwd);
344
370
  }
345
- const shadcnBin = process.platform === "win32" ? "shadcn.cmd" : "shadcn";
346
- const localShadcnPath = path.resolve(options.cwd, "node_modules", ".bin", shadcnBin);
347
371
  try {
348
372
  const env = {
349
373
  ...process.env,
350
374
  REGISTRY_URL: process.env.REGISTRY_URL || DEFAULT_REGISTRY_URL$1
351
375
  };
352
- if (await fsExtra.pathExists(localShadcnPath)) await execa(localShadcnPath, [
353
- "init",
354
- "--base-color",
355
- "neutral"
356
- ], {
357
- stdio: "inherit",
358
- cwd: options.cwd,
359
- env
360
- });
361
- else await execa("npx", [
362
- "-y",
363
- "shadcn@latest",
364
- "init",
365
- "--base-color",
366
- "neutral"
367
- ], {
376
+ const invocation = buildPinnedShadcnInvocation(buildShadcnInitArgs(options.baseColor ?? DEFAULT_COMPONENTS_BASE_COLOR));
377
+ await execa(invocation.cmd, invocation.args, {
368
378
  stdio: "inherit",
369
379
  cwd: options.cwd,
370
380
  env
@@ -523,7 +533,7 @@ async function generateDocs({ cwd, outDir, verbose }) {
523
533
  if (process.env.BEJAMAS_DOCS_CWD) logger.info(`Docs CWD: ${process.env.BEJAMAS_DOCS_CWD}`);
524
534
  if (process.env.BEJAMAS_DOCS_OUT_DIR) logger.info(`Docs out: ${process.env.BEJAMAS_DOCS_OUT_DIR}`);
525
535
  }
526
- const mod = await import("./generate-mdx-C1y987mC.js");
536
+ const mod = await import("./generate-mdx-BejBMCLk.js");
527
537
  if (typeof mod.runDocsGenerator === "function") await mod.runDocsGenerator();
528
538
  else throw new Error("Failed to load docs generator. Export 'runDocsGenerator' not found.");
529
539
  } catch (err) {
@@ -754,10 +764,10 @@ async function fixAstroImports(cwd, isVerbose) {
754
764
  dot: false
755
765
  });
756
766
  for (const filePath of astroFiles) {
757
- const original = await fs.readFile(filePath, "utf8");
767
+ const original = await fs$1.readFile(filePath, "utf8");
758
768
  const rewritten = rewriteAstroImports(original, config);
759
769
  if (rewritten === original) continue;
760
- await fs.writeFile(filePath, rewritten, "utf8");
770
+ await fs$1.writeFile(filePath, rewritten, "utf8");
761
771
  if (isVerbose) logger.info(`[bejamas-ui] fixed imports in ${path$1.relative(cwd, filePath)}`);
762
772
  }
763
773
  }
@@ -810,7 +820,7 @@ function getSubfolderFromPaths(files) {
810
820
  */
811
821
  async function pathExists(filePath) {
812
822
  try {
813
- await fs.access(filePath);
823
+ await fs$1.access(filePath);
814
824
  return true;
815
825
  } catch {
816
826
  return false;
@@ -851,7 +861,7 @@ async function reorganizeComponents(components, uiDir, registryUrl, verbose) {
851
861
  if (!await pathExists(flatPath)) continue;
852
862
  if (await pathExists(targetPath)) {
853
863
  try {
854
- await fs.unlink(flatPath);
864
+ await fs$1.unlink(flatPath);
855
865
  result.skippedFiles.push(`${subfolder}/${filename}`);
856
866
  if (verbose) logger.info(`[bejamas-ui] Removed flat duplicate: ${filename} (${subfolder}/${filename} exists)`);
857
867
  } catch {
@@ -859,8 +869,8 @@ async function reorganizeComponents(components, uiDir, registryUrl, verbose) {
859
869
  }
860
870
  continue;
861
871
  }
862
- await fs.mkdir(targetDir, { recursive: true });
863
- await fs.rename(flatPath, targetPath);
872
+ await fs$1.mkdir(targetDir, { recursive: true });
873
+ await fs$1.rename(flatPath, targetPath);
864
874
  movedCount++;
865
875
  result.totalMoved++;
866
876
  result.movedFiles.push(`${subfolder}/${filename}`);
@@ -1069,37 +1079,16 @@ function parseShadcnOutput(stdout, stderr) {
1069
1079
  return result;
1070
1080
  }
1071
1081
  async function addComponents(packages, forwardedOptions, isVerbose, isSilent, subfolderMapResult) {
1072
- const runner = await getPackageRunner(process.cwd());
1073
1082
  const env = {
1074
1083
  ...process.env,
1075
1084
  REGISTRY_URL: process.env.REGISTRY_URL || DEFAULT_REGISTRY_URL
1076
1085
  };
1077
- const autoFlags = [];
1078
- if (!forwardedOptions.includes("--yes")) autoFlags.push("--yes");
1079
- const baseArgs = [
1080
- "shadcn@latest",
1081
- "add",
1082
- ...packages,
1083
- ...autoFlags,
1084
- ...forwardedOptions
1085
- ];
1086
- let cmd = "npx";
1087
- let args = ["-y", ...baseArgs];
1088
- if (runner === "bunx") {
1089
- cmd = "bunx";
1090
- args = baseArgs;
1091
- } else if (runner === "pnpm dlx") {
1092
- cmd = "pnpm";
1093
- args = ["dlx", ...baseArgs];
1094
- } else if (runner === "npx") {
1095
- cmd = "npx";
1096
- args = ["-y", ...baseArgs];
1097
- }
1098
- if (isVerbose) logger.info(`[bejamas-ui] ${cmd} ${args.join(" ")}`);
1086
+ const invocation = buildPinnedShadcnInvocation(buildShadcnAddArgs(packages, forwardedOptions));
1087
+ if (isVerbose) logger.info(`[bejamas-ui] ${invocation.cmd} ${invocation.args.join(" ")}`);
1099
1088
  const registrySpinner = spinner("Checking registry.", { silent: isSilent });
1100
1089
  registrySpinner.start();
1101
1090
  try {
1102
- const result = await execa(cmd, args, {
1091
+ const result = await execa(invocation.cmd, invocation.args, {
1103
1092
  env,
1104
1093
  input: "n\nn\nn\nn\nn\nn\nn\nn\nn\nn\n",
1105
1094
  stdout: "pipe",
@@ -1126,7 +1115,17 @@ async function addComponents(packages, forwardedOptions, isVerbose, isSilent, su
1126
1115
  process.exit(1);
1127
1116
  }
1128
1117
  }
1129
- const add = new Command().name("add").description("Add components via shadcn@latest using registry URLs").argument("[components...]", "Component package names to add").option("-y, --yes", "skip confirmation prompt.", false).option("-o, --overwrite", "overwrite existing files.", false).option("-c, --cwd <cwd>", "the working directory. defaults to the current directory.", process.cwd()).option("-a, --all", "add all available components", false).option("-p, --path <path>", "the path to add the component to.").option("-s, --silent", "mute output.", false).option("--src-dir", "use the src directory when creating a new project.", false).option("--no-src-dir", "do not use the src directory when creating a new project.").action(async function action(packages, _opts, cmd) {
1118
+ function buildShadcnAddArgs(packages, forwardedOptions) {
1119
+ const autoFlags = [];
1120
+ if (!forwardedOptions.includes("--yes")) autoFlags.push("--yes");
1121
+ return [
1122
+ "add",
1123
+ ...packages,
1124
+ ...autoFlags,
1125
+ ...forwardedOptions
1126
+ ];
1127
+ }
1128
+ const add = new Command().name("add").description("Add components via the pinned shadcn registry flow").argument("[components...]", "Component package names to add").option("-y, --yes", "skip confirmation prompt.", false).option("-o, --overwrite", "overwrite existing files.", false).option("-c, --cwd <cwd>", "the working directory. defaults to the current directory.", process.cwd()).option("-a, --all", "add all available components", false).option("-p, --path <path>", "the path to add the component to.").option("-s, --silent", "mute output.", false).option("--src-dir", "use the src directory when creating a new project.", false).option("--no-src-dir", "do not use the src directory when creating a new project.").action(async function action(packages, _opts, cmd) {
1130
1129
  const root = cmd?.parent;
1131
1130
  const verbose = Boolean(root?.opts?.().verbose);
1132
1131
  const forwardedOptions = extractOptionsForShadcn(process.argv.slice(2), cmd);