create-bingstack-app 0.1.0 → 0.1.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.
Files changed (2) hide show
  1. package/index.mjs +4 -33
  2. package/package.json +3 -3
package/index.mjs CHANGED
@@ -6,10 +6,7 @@ import fs from 'fs/promises'
6
6
  import path from 'path'
7
7
  import { existsSync } from 'fs'
8
8
 
9
- // ─── Config ────────────────────────────────────────────────────────────────────
10
- // Your GitHub template repo in the format "username/repo"
11
- const TEMPLATE_REPO = 'GITHUB_USERNAME/TEMPLATE_REPO'
12
- // ───────────────────────────────────────────────────────────────────────────────
9
+ const TEMPLATE_REPO = 'binghatch/bingstack-template'
13
10
 
14
11
  const args = process.argv.slice(2)
15
12
  const argProjectName = args.find((a) => !a.startsWith('--'))
@@ -19,7 +16,6 @@ async function main() {
19
16
  console.log()
20
17
  p.intro('create-bingstack-app')
21
18
 
22
- // ── Step 1: Project name ────────────────────────────────────────────────────
23
19
  let projectName = argProjectName
24
20
 
25
21
  if (!projectName) {
@@ -31,7 +27,6 @@ async function main() {
31
27
  if (p.isCancel(projectName)) return cancel()
32
28
  }
33
29
 
34
- // ── Step 2: Protected route name ────────────────────────────────────────────
35
30
  const protectedRoute = await p.text({
36
31
  message: 'Main protected page name (shown after sign-in)',
37
32
  placeholder: 'dashboard',
@@ -40,7 +35,6 @@ async function main() {
40
35
  })
41
36
  if (p.isCancel(protectedRoute)) return cancel()
42
37
 
43
- // ── Step 3: Package manager ─────────────────────────────────────────────────
44
38
  const pkgManager = await p.select({
45
39
  message: 'Package manager',
46
40
  options: [
@@ -52,7 +46,6 @@ async function main() {
52
46
  })
53
47
  if (p.isCancel(pkgManager)) return cancel()
54
48
 
55
- // ── Confirm ─────────────────────────────────────────────────────────────────
56
49
  const targetDir = path.resolve(process.cwd(), projectName)
57
50
 
58
51
  if (existsSync(targetDir)) {
@@ -67,30 +60,21 @@ async function main() {
67
60
  s.stop('Removed')
68
61
  }
69
62
 
70
- // ── Clone template ───────────────────────────────────────────────────────────
71
63
  {
72
64
  const s = p.spinner()
73
65
  s.start('Cloning template...')
74
66
  try {
75
- const templateSource = argTemplate ?? TEMPLATE_REPO
76
- const degit = (await import('degit')).default
77
- const emitter = degit(templateSource, { cache: false, force: true })
78
- await emitter.clone(targetDir)
67
+ const { downloadTemplate } = await import('giget')
68
+ const templateSource = argTemplate ?? `gh:${TEMPLATE_REPO}`
69
+ await downloadTemplate(templateSource, { dir: targetDir, force: true })
79
70
  s.stop('Template cloned')
80
71
  } catch (err) {
81
72
  s.stop('Failed to clone template')
82
73
  p.log.error(String(err.message ?? err))
83
- if (!argTemplate) {
84
- p.log.info(
85
- `Make sure you've set TEMPLATE_REPO in index.mjs to your GitHub "username/repo".\n` +
86
- `Or pass a local path: npx create-bingstack-app --template=../my-template`,
87
- )
88
- }
89
74
  process.exit(1)
90
75
  }
91
76
  }
92
77
 
93
- // ── Apply replacements ───────────────────────────────────────────────────────
94
78
  {
95
79
  const s = p.spinner()
96
80
  s.start('Configuring project...')
@@ -98,7 +82,6 @@ async function main() {
98
82
  s.stop('Project configured')
99
83
  }
100
84
 
101
- // ── Install dependencies ─────────────────────────────────────────────────────
102
85
  {
103
86
  const s = p.spinner()
104
87
  s.start(`Installing dependencies with ${pkgManager}...`)
@@ -106,7 +89,6 @@ async function main() {
106
89
  s.stop('Dependencies installed')
107
90
  }
108
91
 
109
- // ── Done ─────────────────────────────────────────────────────────────────────
110
92
  p.outro(
111
93
  `Done! Next steps:\n\n` +
112
94
  ` cd ${projectName}\n` +
@@ -115,12 +97,9 @@ async function main() {
115
97
  )
116
98
  }
117
99
 
118
- // ── Replacements ────────────────────────────────────────────────────────────────
119
-
120
100
  async function applyReplacements(dir, appName, protectedRoute) {
121
101
  const oldRoute = 'workspace'
122
102
 
123
- // 1. Rename the protected route file if needed
124
103
  if (protectedRoute !== oldRoute) {
125
104
  const oldFile = path.join(dir, `src/routes/_protected/${oldRoute}.tsx`)
126
105
  const newFile = path.join(dir, `src/routes/_protected/${protectedRoute}.tsx`)
@@ -129,11 +108,9 @@ async function applyReplacements(dir, appName, protectedRoute) {
129
108
  }
130
109
  }
131
110
 
132
- // 2. Walk all text files and do string replacements
133
111
  const files = await walkFiles(dir, ['node_modules', '.git', 'dist', '.cache', '.turbo'])
134
112
 
135
113
  for (const file of files) {
136
- // Only process text files
137
114
  if (!isTextFile(file)) continue
138
115
 
139
116
  let content = await fs.readFile(file, 'utf-8').catch(() => null)
@@ -141,15 +118,12 @@ async function applyReplacements(dir, appName, protectedRoute) {
141
118
 
142
119
  const original = content
143
120
 
144
- // Replace package name
145
121
  if (file.endsWith('package.json')) {
146
122
  content = content.replace(/"name":\s*"app"/, `"name": "${appName}"`)
147
123
  }
148
124
 
149
- // Replace page title
150
125
  content = content.replaceAll('TanStack Start Starter', toTitleCase(appName))
151
126
 
152
- // Replace protected route references (case-sensitive variants)
153
127
  if (protectedRoute !== oldRoute) {
154
128
  content = content
155
129
  .replaceAll(`/_protected/${oldRoute}`, `/_protected/${protectedRoute}`)
@@ -165,8 +139,6 @@ async function applyReplacements(dir, appName, protectedRoute) {
165
139
  }
166
140
  }
167
141
 
168
- // ── Helpers ─────────────────────────────────────────────────────────────────────
169
-
170
142
  async function walkFiles(dir, ignore = []) {
171
143
  const results = []
172
144
  const entries = await fs.readdir(dir, { withFileTypes: true })
@@ -192,7 +164,6 @@ const TEXT_EXTENSIONS = new Set([
192
164
  function isTextFile(filePath) {
193
165
  const ext = path.extname(filePath)
194
166
  const base = path.basename(filePath)
195
- // Handle extension-less dotfiles like .env
196
167
  return TEXT_EXTENSIONS.has(ext) || TEXT_EXTENSIONS.has(base)
197
168
  }
198
169
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-bingstack-app",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Create a new Bingstack app with auth, routing, and database pre-configured",
5
5
  "type": "module",
6
6
  "bin": {
@@ -8,8 +8,8 @@
8
8
  },
9
9
  "dependencies": {
10
10
  "@clack/prompts": "^0.9.1",
11
- "degit": "^2.8.4",
12
- "execa": "^9.5.2"
11
+ "execa": "^9.5.2",
12
+ "giget": "^3.1.2"
13
13
  },
14
14
  "engines": {
15
15
  "node": ">=18"