bejamas 0.3.0 → 0.3.1

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
@@ -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
@@ -1141,7 +1142,17 @@ const TEMPLATES = {
1141
1142
  };
1142
1143
  const __filename = fileURLToPath(import.meta.url);
1143
1144
  const __dirname = path$1.dirname(__filename);
1144
- function resolveLocalTemplatesDir() {
1145
+ const TEMPLATE_DIRNAME = {
1146
+ astro: "astro",
1147
+ "astro-monorepo": "monorepo-astro",
1148
+ "astro-with-component-docs-monorepo": "monorepo-astro-with-docs"
1149
+ };
1150
+ const TEMPLATE_EXCLUDED_BASENAMES = new Set(["node_modules", ".astro"]);
1151
+ const DEFAULT_TEMPLATE_REPOSITORY = "bejamas/ui";
1152
+ const DEFAULT_TEMPLATE_REF = "main";
1153
+ function resolveLocalTemplatesDir(env = process.env) {
1154
+ const override = env.BEJAMAS_LOCAL_TEMPLATES_DIR?.trim();
1155
+ if (override) return path$1.resolve(override);
1145
1156
  for (const relativePath of [
1146
1157
  "../../../../templates",
1147
1158
  "../../../templates",
@@ -1153,6 +1164,87 @@ function resolveLocalTemplatesDir() {
1153
1164
  return path$1.resolve(__dirname, "../../../../templates");
1154
1165
  }
1155
1166
  const LOCAL_TEMPLATES_DIR = resolveLocalTemplatesDir();
1167
+ function resolvePackageMetadataPath() {
1168
+ for (const relativePath of ["../package.json", "../../package.json"]) {
1169
+ const candidate = path$1.resolve(__dirname, relativePath);
1170
+ if (fs.existsSync(candidate)) return candidate;
1171
+ }
1172
+ return path$1.resolve(__dirname, "../package.json");
1173
+ }
1174
+ function readPackageMetadata() {
1175
+ try {
1176
+ return fs.readJsonSync(resolvePackageMetadataPath());
1177
+ } catch {
1178
+ return {};
1179
+ }
1180
+ }
1181
+ const BEJAMAS_PACKAGE_METADATA = readPackageMetadata();
1182
+ function shouldCopyTemplateEntry(source) {
1183
+ return !TEMPLATE_EXCLUDED_BASENAMES.has(path$1.basename(source));
1184
+ }
1185
+ async function copyTemplateIntoProject(templateSource, projectPath) {
1186
+ await fs.copy(templateSource, projectPath, { filter: shouldCopyTemplateEntry });
1187
+ }
1188
+ function resolveRemoteTemplateRefs(metadata = BEJAMAS_PACKAGE_METADATA, env = process.env) {
1189
+ const refs = [
1190
+ env.BEJAMAS_TEMPLATE_REF?.trim(),
1191
+ metadata.gitHead?.trim(),
1192
+ metadata.version && !metadata.version.includes("-") ? `bejamas@${metadata.version}` : void 0,
1193
+ DEFAULT_TEMPLATE_REF
1194
+ ].filter((ref) => Boolean(ref));
1195
+ return [...new Set(refs)];
1196
+ }
1197
+ function buildTemplateArchiveUrl(ref, repository = DEFAULT_TEMPLATE_REPOSITORY) {
1198
+ return `https://api.github.com/repos/${repository}/tarball/${encodeURIComponent(ref)}`;
1199
+ }
1200
+ function getGitHubRequestHeaders(env = process.env) {
1201
+ const headers = { "User-Agent": `bejamas/${BEJAMAS_PACKAGE_METADATA.version ?? "dev"}` };
1202
+ const token = env.BEJAMAS_GITHUB_TOKEN?.trim() || env.GITHUB_TOKEN?.trim();
1203
+ if (token) headers.Authorization = `Bearer ${token}`;
1204
+ return headers;
1205
+ }
1206
+ async function downloadTemplateArchive(ref, targetDir) {
1207
+ const archiveUrl = buildTemplateArchiveUrl(ref);
1208
+ const archivePath = path$1.join(targetDir, "repo.tar.gz");
1209
+ const response = await fetch(archiveUrl, {
1210
+ headers: getGitHubRequestHeaders(),
1211
+ signal: AbortSignal.timeout(3e4)
1212
+ });
1213
+ if (!response.ok) throw new Error(`GitHub returned ${response.status} ${response.statusText} for ${ref}.`);
1214
+ await fs.ensureDir(targetDir);
1215
+ await fs.outputFile(archivePath, Buffer.from(await response.arrayBuffer()));
1216
+ await tar.x({
1217
+ cwd: targetDir,
1218
+ file: archivePath,
1219
+ strict: true
1220
+ });
1221
+ const extractedRoot = (await fs.readdir(targetDir)).filter((entry) => entry !== "repo.tar.gz").find((entry) => fs.statSync(path$1.join(targetDir, entry)).isDirectory());
1222
+ if (!extractedRoot) throw new Error(`Downloaded archive for ${ref} did not extract correctly.`);
1223
+ return path$1.join(targetDir, extractedRoot);
1224
+ }
1225
+ async function copyTemplateFromGitHub(templateDirName, projectPath) {
1226
+ const refs = resolveRemoteTemplateRefs();
1227
+ const failures = [];
1228
+ for (const ref of refs) {
1229
+ const tempDir = path$1.join(os.tmpdir(), `bejamas-template-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`);
1230
+ try {
1231
+ const extractedRoot = await downloadTemplateArchive(ref, tempDir);
1232
+ const templateSource = path$1.join(extractedRoot, "templates", templateDirName);
1233
+ if (!await fs.pathExists(templateSource)) throw new Error(`Template templates/${templateDirName} was not found.`);
1234
+ await copyTemplateIntoProject(templateSource, projectPath);
1235
+ return ref;
1236
+ } catch (error) {
1237
+ failures.push(`${ref}: ${error instanceof Error ? error.message : String(error)}`);
1238
+ } finally {
1239
+ await fs.remove(tempDir);
1240
+ }
1241
+ }
1242
+ throw new Error([
1243
+ `Unable to download templates/${templateDirName} from GitHub.`,
1244
+ `Tried refs: ${refs.join(", ")}.`,
1245
+ failures.join("\n")
1246
+ ].join("\n"));
1247
+ }
1156
1248
  async function applyLocalPackageOverrides(projectPath) {
1157
1249
  const bejamasPackageOverride = process.env.BEJAMAS_PACKAGE_OVERRIDE;
1158
1250
  if (!bejamasPackageOverride) return;
@@ -1244,23 +1336,17 @@ async function createProject(options) {
1244
1336
  }
1245
1337
  async function createProjectFromTemplate(projectPath, options) {
1246
1338
  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
1339
  try {
1253
1340
  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
- } });
1341
+ const templateDirName = TEMPLATE_DIRNAME[options.templateKey];
1342
+ const templateSource = path$1.resolve(LOCAL_TEMPLATES_DIR, templateDirName);
1343
+ if (await fs.pathExists(templateSource)) await copyTemplateIntoProject(templateSource, projectPath);
1344
+ else {
1345
+ createSpinner.text = `Downloading the ${highlighter.info(options.templateKey)} template from GitHub.`;
1346
+ await copyTemplateFromGitHub(templateDirName, projectPath);
1347
+ }
1261
1348
  await removeEmptyTemplateI18nDirs(projectPath);
1262
1349
  await applyLocalPackageOverrides(projectPath);
1263
- await fs.remove(templatePath);
1264
1350
  await execa(options.packageManager, ["install"], { cwd: projectPath });
1265
1351
  try {
1266
1352
  const { stdout } = await execa("git", ["rev-parse", "--is-inside-work-tree"], { cwd: projectPath });