create-macostack 0.6.3 → 0.6.4
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/bin/create-macostack.ts +39 -30
- package/package.json +1 -1
package/bin/create-macostack.ts
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
multiselect,
|
|
7
7
|
note,
|
|
8
8
|
outro,
|
|
9
|
+
password,
|
|
9
10
|
select,
|
|
10
11
|
spinner,
|
|
11
12
|
text,
|
|
@@ -134,6 +135,7 @@ Flags:
|
|
|
134
135
|
Auth (templates are private):
|
|
135
136
|
export GITHUB_TOKEN=github_pat_… or gh auth login
|
|
136
137
|
(fine-grained token, Contents: Read-only is enough)
|
|
138
|
+
No token configured? I'll ask for one when it's needed.
|
|
137
139
|
`);
|
|
138
140
|
process.exit(0);
|
|
139
141
|
}
|
|
@@ -158,9 +160,40 @@ const answered = <T>(value: T | symbol): T => {
|
|
|
158
160
|
const githubToken = (): string | null => {
|
|
159
161
|
const fromEnv = Bun.env.GITHUB_TOKEN ?? Bun.env.GH_TOKEN;
|
|
160
162
|
if (fromEnv) return fromEnv;
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
163
|
+
try {
|
|
164
|
+
const gh = Bun.spawnSync(["gh", "auth", "token"], { stdout: "pipe", stderr: "pipe" });
|
|
165
|
+
const token = gh.exitCode === 0 ? gh.stdout.toString().trim() : "";
|
|
166
|
+
return token || null;
|
|
167
|
+
} catch {
|
|
168
|
+
return null; // gh isn't installed
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
// Resolve a GitHub token, or ask for one when nothing is configured. In --yes
|
|
173
|
+
// mode there's nobody to ask, so it bails with instructions instead.
|
|
174
|
+
const requireGithubToken = async (purpose: string): Promise<string> => {
|
|
175
|
+
const found = githubToken();
|
|
176
|
+
if (found) return found;
|
|
177
|
+
if (flags.yes) {
|
|
178
|
+
bail(
|
|
179
|
+
`I need GitHub access to ${purpose} (the repos are private).\n` +
|
|
180
|
+
" Easiest: gh auth login\n" +
|
|
181
|
+
" Or: export GITHUB_TOKEN=github_pat_… (Contents: Read-only)",
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
note(
|
|
185
|
+
`I need GitHub access to ${purpose} (the repos are private).\n` +
|
|
186
|
+
"A fine-grained token with Contents: Read-only is enough.\n" +
|
|
187
|
+
"Tip: gh auth login (or export GITHUB_TOKEN=…) skips this question next time.",
|
|
188
|
+
"GitHub access",
|
|
189
|
+
);
|
|
190
|
+
const typed = answered(
|
|
191
|
+
await password({
|
|
192
|
+
message: "Paste your GitHub token (input is hidden)",
|
|
193
|
+
validate: (v) => (v?.trim() ? undefined : "I need a token to continue"),
|
|
194
|
+
}),
|
|
195
|
+
);
|
|
196
|
+
return typed.trim();
|
|
164
197
|
};
|
|
165
198
|
|
|
166
199
|
const isEmptyDir = (dir: string) =>
|
|
@@ -500,29 +533,13 @@ if (present.length > 0) {
|
|
|
500
533
|
process.exit(0);
|
|
501
534
|
}
|
|
502
535
|
if (action === "docs-update") {
|
|
503
|
-
const syncToken =
|
|
504
|
-
if (!syncToken) {
|
|
505
|
-
bail(
|
|
506
|
-
"I need GitHub access to fetch the docs system (the repo is private).\n" +
|
|
507
|
-
" Easiest: gh auth login\n" +
|
|
508
|
-
" Or: export GITHUB_TOKEN=github_pat_… (Contents: Read-only)",
|
|
509
|
-
);
|
|
510
|
-
throw ""; // unreachable
|
|
511
|
-
}
|
|
536
|
+
const syncToken = await requireGithubToken("fetch the docs system");
|
|
512
537
|
await updateDocs(syncToken, targetRoot);
|
|
513
538
|
outro(`${appName} is up to date ✨`);
|
|
514
539
|
process.exit(0);
|
|
515
540
|
}
|
|
516
541
|
if (action === "docs") {
|
|
517
|
-
const docsToken =
|
|
518
|
-
if (!docsToken) {
|
|
519
|
-
bail(
|
|
520
|
-
"I need GitHub access to download the docs system (the repo is private).\n" +
|
|
521
|
-
" Easiest: gh auth login\n" +
|
|
522
|
-
" Or: export GITHUB_TOKEN=github_pat_… (Contents: Read-only)",
|
|
523
|
-
);
|
|
524
|
-
throw ""; // unreachable
|
|
525
|
-
}
|
|
542
|
+
const docsToken = await requireGithubToken("download the docs system");
|
|
526
543
|
const ok = await scaffoldDocs(docsToken, targetRoot, appName, null);
|
|
527
544
|
if (ok) {
|
|
528
545
|
note(
|
|
@@ -571,15 +588,7 @@ if (!selected) {
|
|
|
571
588
|
// 3. GitHub access — checked before anything is created.
|
|
572
589
|
const owner = flags.owner ?? DEFAULT_OWNER;
|
|
573
590
|
const ref = flags.ref ?? DEFAULT_REF;
|
|
574
|
-
const token =
|
|
575
|
-
if (!token) {
|
|
576
|
-
bail(
|
|
577
|
-
"I need GitHub access to download the templates (they're private).\n" +
|
|
578
|
-
" Easiest: gh auth login\n" +
|
|
579
|
-
" Or: export GITHUB_TOKEN=github_pat_… (Contents: Read-only)",
|
|
580
|
-
);
|
|
581
|
-
throw ""; // unreachable
|
|
582
|
-
}
|
|
591
|
+
const token = await requireGithubToken("download the templates");
|
|
583
592
|
for (const p of selected) {
|
|
584
593
|
p.repo = (p.id === "server" ? flags["server-repo"] : flags["client-repo"]) ?? p.repo;
|
|
585
594
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-macostack",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.4",
|
|
4
4
|
"description": "Scaffold a production-ready full-stack app from the macostack templates: Bun + Hono + Postgres backend and TanStack web app, each as its own git repo.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|