create-bodhi-js 0.6.0 → 0.7.0

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.
Files changed (2) hide show
  1. package/dist/index.js +69 -15
  2. package/package.json +5 -2
package/dist/index.js CHANGED
@@ -26,7 +26,9 @@ var TEMPLATE_FILES = [
26
26
  "CONTRIBUTING.md",
27
27
  "src/App.tsx",
28
28
  ".github/SECURITY.md",
29
- ".github/ISSUE_TEMPLATE/config.yml"
29
+ ".github/ISSUE_TEMPLATE/config.yml",
30
+ ".github/workflows/ci.yml",
31
+ ".github/workflows/deploy-pages.yml"
30
32
  ];
31
33
  async function processTemplates(targetDir, vars) {
32
34
  for (const file of TEMPLATE_FILES) {
@@ -36,7 +38,11 @@ async function processTemplates(targetDir, vars) {
36
38
  const template = Handlebars.compile(content);
37
39
  const rendered = template(vars);
38
40
  await fs.writeFile(filePath, rendered, "utf-8");
39
- } catch {
41
+ } catch (error) {
42
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") {
43
+ continue;
44
+ }
45
+ throw new Error(`Failed to process template ${file}: ${error}`);
40
46
  }
41
47
  }
42
48
  }
@@ -45,6 +51,9 @@ async function processTemplates(targetDir, vars) {
45
51
  import { exec } from "child_process";
46
52
  import { promisify } from "util";
47
53
  var execAsync = promisify(exec);
54
+ function isLocalPath(templateUrl) {
55
+ return templateUrl.startsWith("/") || templateUrl.startsWith("./") || templateUrl.startsWith("../");
56
+ }
48
57
  async function scaffold(options) {
49
58
  const {
50
59
  projectName,
@@ -54,7 +63,9 @@ async function scaffold(options) {
54
63
  basePath,
55
64
  pathSegmentsToKeep,
56
65
  install,
57
- git
66
+ git,
67
+ devClientId,
68
+ prodClientId
58
69
  } = options;
59
70
  const targetDir = path2.resolve(process.cwd(), projectName);
60
71
  try {
@@ -65,10 +76,15 @@ async function scaffold(options) {
65
76
  throw err;
66
77
  }
67
78
  }
68
- await downloadTemplate(templateUrl, {
69
- dir: targetDir,
70
- offline: false
71
- });
79
+ if (isLocalPath(templateUrl)) {
80
+ await fs2.cp(templateUrl, targetDir, { recursive: true });
81
+ } else {
82
+ await downloadTemplate(templateUrl, {
83
+ dir: targetDir,
84
+ offline: false,
85
+ force: true
86
+ });
87
+ }
72
88
  const templateSubdir = path2.join(targetDir, "template");
73
89
  try {
74
90
  await fs2.access(templateSubdir);
@@ -93,7 +109,9 @@ async function scaffold(options) {
93
109
  githubOrg,
94
110
  githubPages,
95
111
  basePath,
96
- pathSegmentsToKeep
112
+ pathSegmentsToKeep,
113
+ devClientId,
114
+ prodClientId
97
115
  });
98
116
  if (!githubPages) {
99
117
  const filesToDelete = [
@@ -107,16 +125,23 @@ async function scaffold(options) {
107
125
  }
108
126
  }
109
127
  }
110
- const metaFiles = ["template.json", "test-template.sh", "TECH.md"];
128
+ const metaFiles = ["template.json", "test-template.sh", "TECH.md", ".env.local"];
111
129
  for (const file of metaFiles) {
112
130
  try {
113
131
  await fs2.unlink(path2.join(targetDir, file));
114
132
  } catch {
115
133
  }
116
134
  }
135
+ try {
136
+ await fs2.rm(path2.join(targetDir, "template"), { recursive: true, force: true });
137
+ } catch {
138
+ }
117
139
  if (git) {
118
140
  try {
119
141
  await execAsync("git init", { cwd: targetDir });
142
+ if (install) {
143
+ await execAsync("npm install", { cwd: targetDir });
144
+ }
120
145
  await execAsync("git add .", { cwd: targetDir });
121
146
  await execAsync('git commit -m "chore: initial commit from create-bodhi-js"', {
122
147
  cwd: targetDir
@@ -124,19 +149,29 @@ async function scaffold(options) {
124
149
  } catch {
125
150
  console.warn("Warning: Git initialization failed");
126
151
  }
127
- }
128
- if (install) {
152
+ } else if (install) {
129
153
  await execAsync("npm install", { cwd: targetDir });
130
154
  }
155
+ if (devClientId) {
156
+ const envContent = `VITE_BODHI_APP_CLIENT_ID=${devClientId}
157
+ VITE_BODHI_AUTH_SERVER_URL=https://main-id.getbodhi.app/realms/bodhi
158
+ `;
159
+ await fs2.writeFile(path2.join(targetDir, ".env.local"), envContent, "utf-8");
160
+ }
131
161
  }
132
162
 
133
163
  // src/templates.ts
164
+ import { existsSync } from "fs";
165
+ import { resolve } from "path";
134
166
  var TEMPLATES = {
135
167
  react: "gh:BodhiSearch/template-bodhi-react-vite"
136
168
  // Future templates
137
169
  // svelte: 'gh:BodhiSearch/template-bodhi-svelte-vite',
138
170
  // vue: 'gh:BodhiSearch/template-bodhi-vue-vite',
139
171
  };
172
+ function isLocalPath2(name) {
173
+ return name.startsWith("/") || name.startsWith("./") || name.startsWith("../");
174
+ }
140
175
  function resolveTemplate(name) {
141
176
  if (TEMPLATES[name]) {
142
177
  return TEMPLATES[name];
@@ -144,18 +179,33 @@ function resolveTemplate(name) {
144
179
  if (name.includes(":")) {
145
180
  return name;
146
181
  }
182
+ if (isLocalPath2(name)) {
183
+ const absolutePath = name.startsWith("/") ? name : resolve(process.cwd(), name);
184
+ if (!existsSync(absolutePath)) {
185
+ throw new Error(`Template path does not exist: ${absolutePath}`);
186
+ }
187
+ return absolutePath;
188
+ }
147
189
  throw new Error(
148
190
  `Unknown template: ${name}
149
191
 
150
192
  Available templates:
151
- ${Object.keys(TEMPLATES).map((t) => ` - ${t}`).join("\n")}
193
+ ${Object.keys(TEMPLATES).map((t) => ` - ${t}`).join(
194
+ "\n"
195
+ )}
152
196
 
153
- Or use a custom template: gh:user/repo`
197
+ Or use a custom template: gh:user/repo
198
+ Or use a local path: /path/to/template`
154
199
  );
155
200
  }
156
201
 
157
202
  // src/cli.ts
158
203
  async function create(projectName, options) {
204
+ if (options.ci) {
205
+ process.env.CI = "true";
206
+ process.env.NO_COLOR = "1";
207
+ delete process.env.FORCE_COLOR;
208
+ }
159
209
  console.log();
160
210
  p.intro(pc.bgCyan(pc.black(" create-bodhi-js ")));
161
211
  let targetDir = projectName;
@@ -222,6 +272,8 @@ async function create(projectName, options) {
222
272
  }
223
273
  basePath = `/${targetDir}/`;
224
274
  pathSegmentsToKeep = 1;
275
+ } else {
276
+ githubOrg = "YOUR_ORG";
225
277
  }
226
278
  const spinner2 = p.spinner();
227
279
  spinner2.start("Scaffolding project...");
@@ -234,7 +286,9 @@ async function create(projectName, options) {
234
286
  basePath,
235
287
  pathSegmentsToKeep,
236
288
  install: options.install,
237
- git: options.git
289
+ git: options.git,
290
+ devClientId: options.devClientId,
291
+ prodClientId: options.prodClientId
238
292
  });
239
293
  spinner2.stop("Project scaffolded successfully!");
240
294
  p.note(
@@ -251,7 +305,7 @@ async function create(projectName, options) {
251
305
 
252
306
  // src/index.ts
253
307
  var program = new Command();
254
- program.name("create-bodhi-js").description("Scaffold Bodhi-powered applications").version("0.1.0").argument("[project-name]", "Name of the project").option("-t, --template <name>", "Template to use (react, svelte, vue)", "react").option("--no-install", "Skip dependency installation").option("--no-git", "Skip git initialization").option("--github-pages", "Enable GitHub Pages deployment setup").option("--github-org <org>", "GitHub repository owner (user/org)").action(async (projectName, options) => {
308
+ program.name("create-bodhi-js").description("Scaffold Bodhi-powered applications").version("0.1.0").argument("[project-name]", "Name of the project").option("-t, --template <name>", "Template name or local path", "react").option("--no-install", "Skip dependency installation").option("--no-git", "Skip git initialization").option("--github-pages", "Enable GitHub Pages deployment setup").option("--no-github-pages", "Disable GitHub Pages deployment setup").option("--github-org <org>", "GitHub repository owner (user/org)").option("--dev-client-id <id>", "Development client ID (for .env.local and CI)").option("--prod-client-id <id>", "Production client ID (for GitHub Pages deploy)").option("--ci", "Run in CI mode (disable animations)").action(async (projectName, options) => {
255
309
  await create(projectName, options);
256
310
  });
257
311
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-bodhi-js",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "Scaffold Bodhi-powered applications with React, TypeScript, Vite, and more",
5
5
  "type": "module",
6
6
  "bin": {
@@ -20,7 +20,8 @@
20
20
  "lint:fix": "eslint . --fix",
21
21
  "check": "npm run lint && npm run typecheck",
22
22
  "check:fix": "npm run lint:fix && npm run typecheck",
23
- "test": "echo \"Tests coming soon\" && exit 0",
23
+ "test": "playwright test",
24
+ "test:headed": "playwright test --headed",
24
25
  "prepublishOnly": "npm run build"
25
26
  },
26
27
  "keywords": [
@@ -53,7 +54,9 @@
53
54
  },
54
55
  "devDependencies": {
55
56
  "@eslint/js": "^9.39.1",
57
+ "@playwright/test": "^1.57.0",
56
58
  "@types/node": "^25.0.3",
59
+ "dotenv": "^17.2.3",
57
60
  "eslint": "^9.39.1",
58
61
  "eslint-config-prettier": "^10.1.8",
59
62
  "eslint-plugin-prettier": "^5.5.4",