bejamas 0.3.0 → 0.3.2

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,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { A as renderSemanticIconSvgWithAttributeString, B as normalizeDesignSystemConfig, C as buildUiUrl, D as SEMANTIC_ICON_NAMES, E as ICON_LIBRARY_COLLECTIONS, F as getDocumentLanguage, H as encodePreset, I as getFontPackageName, L as getFontValue, M as RTL_LANGUAGE_VALUES, N as designSystemConfigSchema, O as getSemanticIconNameFromLucideExport, P as getDocumentDirection, R as getHeadingFontValue, S as BASE_COLORS, T as buildRegistryTheme, U as isPresetCode, V as decodePreset, W as fonts, _ as getConfig, b as highlighter, d as parseJsDocMetadata, g as spinner, j as DEFAULT_DESIGN_SYSTEM_CONFIG, k as getSemanticIconNameFromLucidePath, o as extractFrontmatter, p as resolveUiRoot, v as getWorkspaceConfig, w as resolveRegistryUrl, x as BEJAMAS_COMPONENTS_SCHEMA_URL, y as logger, z as getStyleId } from "./utils-BCEkpKMO.js";
2
+ import { A as getSemanticIconNameFromLucidePath, B as getStyleId, C as buildUiUrl, D as ICON_LIBRARY_COLLECTIONS, E as buildRegistryTheme, F as getDocumentDirection, G as fonts, H as decodePreset, I as getDocumentLanguage, L as getFontPackageName, M as DEFAULT_DESIGN_SYSTEM_CONFIG, N as RTL_LANGUAGE_VALUES, O as SEMANTIC_ICON_NAMES, P as designSystemConfigSchema, R as getFontValue, S as BASE_COLORS, T as ICON_LIBRARIES, U as encodePreset, V as normalizeDesignSystemConfig, W as isPresetCode, _ as getConfig, b as highlighter, d as parseJsDocMetadata, g as spinner, j as renderSemanticIconSvgWithAttributeString, k as getSemanticIconNameFromLucideExport, o as extractFrontmatter, p as resolveUiRoot, v as getWorkspaceConfig, w as resolveRegistryUrl, x as BEJAMAS_COMPONENTS_SCHEMA_URL, y as logger, z as getHeadingFontValue } from "./utils-B0HWwl6F.js";
3
3
  import { Command } from "commander";
4
4
  import { createRequire } from "module";
5
5
  import path, { extname, isAbsolute, join, relative, resolve } from "node:path";
@@ -16,6 +16,7 @@ import dotenv from "dotenv";
16
16
  import { detect } from "@antfu/ni";
17
17
  import { execa } from "execa";
18
18
  import prompts from "prompts";
19
+ import * as tar from "tar";
19
20
  import os$1 from "node:os";
20
21
 
21
22
  //#region src/registry/context.ts
@@ -324,6 +325,8 @@ const CREATE_BLOCK_END = "/* bejamas:create:end */";
324
325
  const SHADCN_TAILWIND_IMPORT = "@import \"shadcn/tailwind.css\";";
325
326
  const BEJAMAS_TAILWIND_IMPORT = "@import \"bejamas/tailwind.css\";";
326
327
  const MANAGED_TAILWIND_IMPORTS = new Set([SHADCN_TAILWIND_IMPORT, BEJAMAS_TAILWIND_IMPORT]);
328
+ const MANAGED_ICON_PACKAGES = new Set(ICON_LIBRARIES.map((library) => library.packageName));
329
+ const FALLBACK_ICON_PACKAGE_VERSION = "latest";
327
330
  const TEMPLATE_APP_UI_IMPORT = "import { appUi } from \"@/i18n/ui\";";
328
331
  const TEMPLATE_I18N_SOURCES = {
329
332
  astro: `const RTL_LANGUAGES = ["ar", "fa", "he"] as const;
@@ -754,6 +757,46 @@ async function patchCssFileManagedTailwindImport(filepath) {
754
757
  const next = transformManagedTailwindImportCss(await fs.readFile(filepath, "utf8"));
755
758
  await fs.writeFile(filepath, next, "utf8");
756
759
  }
760
+ function getSelectedIconPackageName(config) {
761
+ return ICON_LIBRARIES.find((library) => library.name === config.iconLibrary)?.packageName;
762
+ }
763
+ async function patchPackageJsonIconDependency(filepath, config) {
764
+ const selectedIconPackage = getSelectedIconPackageName(config);
765
+ if (!selectedIconPackage) return;
766
+ const packageJson = await fs.readJson(filepath);
767
+ let targetField = null;
768
+ let changed = false;
769
+ for (const field of ["dependencies", "devDependencies"]) {
770
+ const dependencies = packageJson[field];
771
+ if (!dependencies) continue;
772
+ for (const iconPackage of MANAGED_ICON_PACKAGES) {
773
+ if (!dependencies[iconPackage]) continue;
774
+ targetField ??= field;
775
+ if (iconPackage === selectedIconPackage) continue;
776
+ delete dependencies[iconPackage];
777
+ changed = true;
778
+ }
779
+ }
780
+ if (!targetField) return;
781
+ if (!(packageJson.dependencies?.[selectedIconPackage] || packageJson.devDependencies?.[selectedIconPackage])) {
782
+ packageJson[targetField] ??= {};
783
+ packageJson[targetField][selectedIconPackage] = FALLBACK_ICON_PACKAGE_VERSION;
784
+ changed = true;
785
+ }
786
+ if (changed) await fs.writeJson(filepath, packageJson, { spaces: 2 });
787
+ }
788
+ async function syncPackageIconDependencies(projectPath, config) {
789
+ const packageJsonFiles = await fg("**/package.json", {
790
+ cwd: projectPath,
791
+ absolute: true,
792
+ ignore: [
793
+ "**/node_modules/**",
794
+ "**/dist/**",
795
+ "**/.astro/**"
796
+ ]
797
+ });
798
+ await Promise.all(packageJsonFiles.map((filepath) => patchPackageJsonIconDependency(filepath, config)));
799
+ }
757
800
  async function syncManagedTailwindCss(projectPath) {
758
801
  const componentJsonFiles = await fg("**/components.json", {
759
802
  cwd: projectPath,
@@ -839,6 +882,7 @@ async function applyDesignSystemToProject(projectPath, config, options = {}) {
839
882
  }
840
883
  }
841
884
  await Promise.all(Array.from(cssFiles).map((filepath) => patchCssFileWithTheme(filepath, config, options.themeVars)));
885
+ await syncPackageIconDependencies(projectPath, config);
842
886
  await Promise.all([path.resolve(projectPath, "src/i18n/ui.ts"), path.resolve(projectPath, "apps/web/src/i18n/ui.ts")].map((filepath) => patchTemplateI18nFile(filepath, config)));
843
887
  await Promise.all([path.resolve(projectPath, "src/layouts/Layout.astro"), path.resolve(projectPath, "apps/web/src/layouts/Layout.astro")].map((filepath) => patchLayoutFile(filepath, config)));
844
888
  await Promise.all([path.resolve(projectPath, "src/pages/index.astro"), path.resolve(projectPath, "apps/web/src/pages/index.astro")].map((filepath) => patchStarterPageFile(filepath, config)));
@@ -1141,7 +1185,17 @@ const TEMPLATES = {
1141
1185
  };
1142
1186
  const __filename = fileURLToPath(import.meta.url);
1143
1187
  const __dirname = path$1.dirname(__filename);
1144
- function resolveLocalTemplatesDir() {
1188
+ const TEMPLATE_DIRNAME = {
1189
+ astro: "astro",
1190
+ "astro-monorepo": "monorepo-astro",
1191
+ "astro-with-component-docs-monorepo": "monorepo-astro-with-docs"
1192
+ };
1193
+ const TEMPLATE_EXCLUDED_BASENAMES = new Set(["node_modules", ".astro"]);
1194
+ const DEFAULT_TEMPLATE_REPOSITORY = "bejamas/ui";
1195
+ const DEFAULT_TEMPLATE_REF = "main";
1196
+ function resolveLocalTemplatesDir(env = process.env) {
1197
+ const override = env.BEJAMAS_LOCAL_TEMPLATES_DIR?.trim();
1198
+ if (override) return path$1.resolve(override);
1145
1199
  for (const relativePath of [
1146
1200
  "../../../../templates",
1147
1201
  "../../../templates",
@@ -1153,6 +1207,87 @@ function resolveLocalTemplatesDir() {
1153
1207
  return path$1.resolve(__dirname, "../../../../templates");
1154
1208
  }
1155
1209
  const LOCAL_TEMPLATES_DIR = resolveLocalTemplatesDir();
1210
+ function resolvePackageMetadataPath() {
1211
+ for (const relativePath of ["../package.json", "../../package.json"]) {
1212
+ const candidate = path$1.resolve(__dirname, relativePath);
1213
+ if (fs.existsSync(candidate)) return candidate;
1214
+ }
1215
+ return path$1.resolve(__dirname, "../package.json");
1216
+ }
1217
+ function readPackageMetadata() {
1218
+ try {
1219
+ return fs.readJsonSync(resolvePackageMetadataPath());
1220
+ } catch {
1221
+ return {};
1222
+ }
1223
+ }
1224
+ const BEJAMAS_PACKAGE_METADATA = readPackageMetadata();
1225
+ function shouldCopyTemplateEntry(source) {
1226
+ return !TEMPLATE_EXCLUDED_BASENAMES.has(path$1.basename(source));
1227
+ }
1228
+ async function copyTemplateIntoProject(templateSource, projectPath) {
1229
+ await fs.copy(templateSource, projectPath, { filter: shouldCopyTemplateEntry });
1230
+ }
1231
+ function resolveRemoteTemplateRefs(metadata = BEJAMAS_PACKAGE_METADATA, env = process.env) {
1232
+ const refs = [
1233
+ env.BEJAMAS_TEMPLATE_REF?.trim(),
1234
+ metadata.gitHead?.trim(),
1235
+ metadata.version && !metadata.version.includes("-") ? `bejamas@${metadata.version}` : void 0,
1236
+ DEFAULT_TEMPLATE_REF
1237
+ ].filter((ref) => Boolean(ref));
1238
+ return [...new Set(refs)];
1239
+ }
1240
+ function buildTemplateArchiveUrl(ref, repository = DEFAULT_TEMPLATE_REPOSITORY) {
1241
+ return `https://api.github.com/repos/${repository}/tarball/${encodeURIComponent(ref)}`;
1242
+ }
1243
+ function getGitHubRequestHeaders(env = process.env) {
1244
+ const headers = { "User-Agent": `bejamas/${BEJAMAS_PACKAGE_METADATA.version ?? "dev"}` };
1245
+ const token = env.BEJAMAS_GITHUB_TOKEN?.trim() || env.GITHUB_TOKEN?.trim();
1246
+ if (token) headers.Authorization = `Bearer ${token}`;
1247
+ return headers;
1248
+ }
1249
+ async function downloadTemplateArchive(ref, targetDir) {
1250
+ const archiveUrl = buildTemplateArchiveUrl(ref);
1251
+ const archivePath = path$1.join(targetDir, "repo.tar.gz");
1252
+ const response = await fetch(archiveUrl, {
1253
+ headers: getGitHubRequestHeaders(),
1254
+ signal: AbortSignal.timeout(3e4)
1255
+ });
1256
+ if (!response.ok) throw new Error(`GitHub returned ${response.status} ${response.statusText} for ${ref}.`);
1257
+ await fs.ensureDir(targetDir);
1258
+ await fs.outputFile(archivePath, Buffer.from(await response.arrayBuffer()));
1259
+ await tar.x({
1260
+ cwd: targetDir,
1261
+ file: archivePath,
1262
+ strict: true
1263
+ });
1264
+ const extractedRoot = (await fs.readdir(targetDir)).filter((entry) => entry !== "repo.tar.gz").find((entry) => fs.statSync(path$1.join(targetDir, entry)).isDirectory());
1265
+ if (!extractedRoot) throw new Error(`Downloaded archive for ${ref} did not extract correctly.`);
1266
+ return path$1.join(targetDir, extractedRoot);
1267
+ }
1268
+ async function copyTemplateFromGitHub(templateDirName, projectPath) {
1269
+ const refs = resolveRemoteTemplateRefs();
1270
+ const failures = [];
1271
+ for (const ref of refs) {
1272
+ const tempDir = path$1.join(os.tmpdir(), `bejamas-template-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`);
1273
+ try {
1274
+ const extractedRoot = await downloadTemplateArchive(ref, tempDir);
1275
+ const templateSource = path$1.join(extractedRoot, "templates", templateDirName);
1276
+ if (!await fs.pathExists(templateSource)) throw new Error(`Template templates/${templateDirName} was not found.`);
1277
+ await copyTemplateIntoProject(templateSource, projectPath);
1278
+ return ref;
1279
+ } catch (error) {
1280
+ failures.push(`${ref}: ${error instanceof Error ? error.message : String(error)}`);
1281
+ } finally {
1282
+ await fs.remove(tempDir);
1283
+ }
1284
+ }
1285
+ throw new Error([
1286
+ `Unable to download templates/${templateDirName} from GitHub.`,
1287
+ `Tried refs: ${refs.join(", ")}.`,
1288
+ failures.join("\n")
1289
+ ].join("\n"));
1290
+ }
1156
1291
  async function applyLocalPackageOverrides(projectPath) {
1157
1292
  const bejamasPackageOverride = process.env.BEJAMAS_PACKAGE_OVERRIDE;
1158
1293
  if (!bejamasPackageOverride) return;
@@ -1244,23 +1379,17 @@ async function createProject(options) {
1244
1379
  }
1245
1380
  async function createProjectFromTemplate(projectPath, options) {
1246
1381
  const createSpinner = spinner(`Creating a new project from template. This may take a few minutes.`).start();
1247
- const TEMPLATE_DIRNAME = {
1248
- astro: "astro",
1249
- "astro-monorepo": "monorepo-astro",
1250
- "astro-with-component-docs-monorepo": "monorepo-astro-with-docs"
1251
- };
1252
1382
  try {
1253
1383
  dotenv.config({ quiet: true });
1254
- const templatePath = path$1.join(os.tmpdir(), `bejamas-template-${Date.now()}`);
1255
- const templateSource = path$1.resolve(LOCAL_TEMPLATES_DIR, TEMPLATE_DIRNAME[options.templateKey]);
1256
- if (!await fs.pathExists(templateSource)) throw new Error(`Local template not found: ${templateSource}`);
1257
- await fs.copy(templateSource, projectPath, { filter: (source) => {
1258
- const basename = path$1.basename(source);
1259
- return basename !== "node_modules" && basename !== ".astro";
1260
- } });
1384
+ const templateDirName = TEMPLATE_DIRNAME[options.templateKey];
1385
+ const templateSource = path$1.resolve(LOCAL_TEMPLATES_DIR, templateDirName);
1386
+ if (await fs.pathExists(templateSource)) await copyTemplateIntoProject(templateSource, projectPath);
1387
+ else {
1388
+ createSpinner.text = `Downloading the ${highlighter.info(options.templateKey)} template from GitHub.`;
1389
+ await copyTemplateFromGitHub(templateDirName, projectPath);
1390
+ }
1261
1391
  await removeEmptyTemplateI18nDirs(projectPath);
1262
1392
  await applyLocalPackageOverrides(projectPath);
1263
- await fs.remove(templatePath);
1264
1393
  await execa(options.packageManager, ["install"], { cwd: projectPath });
1265
1394
  try {
1266
1395
  const { stdout } = await execa("git", ["rev-parse", "--is-inside-work-tree"], { cwd: projectPath });
@@ -1705,6 +1834,7 @@ async function runInit(options) {
1705
1834
  REGISTRY_URL: resolveRegistryUrl()
1706
1835
  };
1707
1836
  const initUrl = buildInitUrl(designConfig, options.themeRef);
1837
+ const themeVars = options.themeRef ? await fetchInitThemeVars(initUrl) ?? void 0 : void 0;
1708
1838
  const shouldReinstall = shouldReinstallExistingComponents(options);
1709
1839
  const reinstallComponents = shouldReinstall ? await getInstalledUiComponents(options.cwd) : [];
1710
1840
  const forwardedOptions = ensureShadcnReinstallFlag(options.forwardedOptions ?? [], shouldReinstall);
@@ -1726,6 +1856,7 @@ async function runInit(options) {
1726
1856
  await syncAstroManagedFontCss(options.cwd, managedFont.cssVariable);
1727
1857
  await cleanupAstroFontPackages(options.cwd);
1728
1858
  }
1859
+ await applyDesignSystemToProject(options.cwd, designConfig, { themeVars });
1729
1860
  if (reinstallComponents.length > 0) {
1730
1861
  const config = await getConfig(options.cwd);
1731
1862
  const uiDir = config?.resolvedPaths.ui ?? "";
@@ -1912,7 +2043,7 @@ async function generateDocs({ cwd, outDir, verbose }) {
1912
2043
  if (process.env.BEJAMAS_DOCS_CWD) logger.info(`Docs CWD: ${process.env.BEJAMAS_DOCS_CWD}`);
1913
2044
  if (process.env.BEJAMAS_DOCS_OUT_DIR) logger.info(`Docs out: ${process.env.BEJAMAS_DOCS_OUT_DIR}`);
1914
2045
  }
1915
- const mod = await import("./generate-mdx-PPNpe9_J.js");
2046
+ const mod = await import("./generate-mdx-_F9W0nYJ.js");
1916
2047
  if (typeof mod.runDocsGenerator === "function") await mod.runDocsGenerator();
1917
2048
  else throw new Error("Failed to load docs generator. Export 'runDocsGenerator' not found.");
1918
2049
  } catch (err) {
@@ -2184,6 +2315,13 @@ function formatSkippedFilesHeading(count, overwriteUsed) {
2184
2315
  if (overwriteUsed) return `Skipped ${count} ${noun}: (files might be identical)`;
2185
2316
  return `Skipped ${count} ${noun}: (files might be identical, use --overwrite to overwrite)`;
2186
2317
  }
2318
+ function ensureTrailingNewline(output) {
2319
+ return output.endsWith("\n") ? output : `${output}\n`;
2320
+ }
2321
+ function writeCapturedShadcnOutput(stdout, stderr) {
2322
+ if (stdout) process.stdout.write(ensureTrailingNewline(stdout));
2323
+ if (stderr) process.stderr.write(ensureTrailingNewline(stderr));
2324
+ }
2187
2325
  async function buildSubfolderMap(components, uiDir, registryUrl, style) {
2188
2326
  const filenameToSubfolders = /* @__PURE__ */ new Map();
2189
2327
  let requiresReorganization = false;
@@ -2335,17 +2473,14 @@ async function addComponents(cwd, packages, forwardedOptions, isVerbose, isSilen
2335
2473
  logger.info(`[bejamas-ui] Raw stdout: ${stdout}`);
2336
2474
  logger.info(`[bejamas-ui] Raw stderr: ${stderr}`);
2337
2475
  }
2338
- if (inspectionMode) {
2339
- if (stdout) process.stdout.write(stdout.endsWith("\n") ? stdout : `${stdout}\n`);
2340
- if (stderr) process.stderr.write(stderr.endsWith("\n") ? stderr : `${stderr}\n`);
2341
- }
2476
+ if (inspectionMode) writeCapturedShadcnOutput(stdout, stderr);
2342
2477
  const parsed = inspectionMode ? {
2343
2478
  created: [],
2344
2479
  updated: [],
2345
2480
  skipped: []
2346
2481
  } : parseShadcnOutput(stdout, stderr);
2347
2482
  if (result.exitCode !== 0) {
2348
- if (result.stderr) logger.error(result.stderr);
2483
+ if (!inspectionMode) writeCapturedShadcnOutput(stdout, stderr);
2349
2484
  process.exit(result.exitCode);
2350
2485
  }
2351
2486
  return parsed;