create-blaze 0.1.0 → 0.3.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.
- package/README.md +110 -0
- package/dist/index.js +240 -42
- package/package.json +18 -4
package/README.md
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
<img src="https://s6.imgcdn.dev/Y2Bbiu.png" alt="blazestack" width="200" />
|
|
4
|
+
|
|
5
|
+
<h3>create-blaze</h3>
|
|
6
|
+
<p>Scaffold a new <a href="https://github.com/Alshahriah/blazestack">blazestack</a> project in seconds.</p>
|
|
7
|
+
|
|
8
|
+
[](https://www.npmjs.com/package/create-blaze)
|
|
9
|
+
[](https://www.npmjs.com/package/create-blaze)
|
|
10
|
+
[](https://github.com/Alshahriah/blazestack/blob/main/LICENSE)
|
|
11
|
+
[](https://bun.sh)
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx create-blaze my-app
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
# With a name
|
|
25
|
+
npx create-blaze my-app
|
|
26
|
+
|
|
27
|
+
# Without a name — defaults to my-blazestack-app
|
|
28
|
+
# Auto-increments if the directory already exists
|
|
29
|
+
npx create-blaze
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## What it does
|
|
33
|
+
|
|
34
|
+
1. Downloads the latest blazestack template from GitHub
|
|
35
|
+
2. Copies it to `./<project-name>/`
|
|
36
|
+
3. Renames all package references to match your project name
|
|
37
|
+
4. Prints next steps
|
|
38
|
+
|
|
39
|
+
## Next steps after scaffolding
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
cd my-app
|
|
43
|
+
bun install
|
|
44
|
+
cp apps/api/.dev.vars.example apps/api/.dev.vars
|
|
45
|
+
# Fill in DATABASE_URL, BETTER_AUTH_SECRET, BETTER_AUTH_URL
|
|
46
|
+
|
|
47
|
+
bun db:setup && bun db:generate && bun db:migrate
|
|
48
|
+
|
|
49
|
+
bun dev:api # API → http://localhost:8787
|
|
50
|
+
bun dev:web # Web → http://localhost:5173
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## What's in the scaffold
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
my-app/
|
|
57
|
+
├── apps/
|
|
58
|
+
│ ├── api/ Hono — Better Auth + tRPC (Cloudflare Workers)
|
|
59
|
+
│ ├── web/ React Router v7 SSR (Cloudflare Workers)
|
|
60
|
+
│ └── mobile/ Expo SDK 55 — iOS + Android
|
|
61
|
+
└── packages/
|
|
62
|
+
├── auth/ Better Auth factory
|
|
63
|
+
├── db/ Drizzle ORM + PostgreSQL
|
|
64
|
+
├── env/ Zod-validated env vars
|
|
65
|
+
├── trpc/ Shared tRPC v11 router
|
|
66
|
+
└── ui/ Shared UI components (web + native)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Stack
|
|
70
|
+
|
|
71
|
+
<table>
|
|
72
|
+
<tr>
|
|
73
|
+
<td><img src="https://img.shields.io/badge/Bun-000000?style=flat-square&logo=bun&logoColor=white" /></td>
|
|
74
|
+
<td>Runtime & package manager</td>
|
|
75
|
+
</tr>
|
|
76
|
+
<tr>
|
|
77
|
+
<td><img src="https://img.shields.io/badge/Hono-E36002?style=flat-square&logo=hono&logoColor=white" /></td>
|
|
78
|
+
<td>API on Cloudflare Workers</td>
|
|
79
|
+
</tr>
|
|
80
|
+
<tr>
|
|
81
|
+
<td><img src="https://img.shields.io/badge/React_Router_v7-CA4245?style=flat-square&logo=reactrouter&logoColor=white" /></td>
|
|
82
|
+
<td>SSR web app on Cloudflare Workers</td>
|
|
83
|
+
</tr>
|
|
84
|
+
<tr>
|
|
85
|
+
<td><img src="https://img.shields.io/badge/Expo-000020?style=flat-square&logo=expo&logoColor=white" /></td>
|
|
86
|
+
<td>iOS + Android (SDK 55 / RN 0.84)</td>
|
|
87
|
+
</tr>
|
|
88
|
+
<tr>
|
|
89
|
+
<td><img src="https://img.shields.io/badge/Better_Auth-000000?style=flat-square&logo=auth0&logoColor=white" /></td>
|
|
90
|
+
<td>Authentication & sessions</td>
|
|
91
|
+
</tr>
|
|
92
|
+
<tr>
|
|
93
|
+
<td><img src="https://img.shields.io/badge/Drizzle_ORM-C5F74F?style=flat-square&logo=drizzle&logoColor=black" /></td>
|
|
94
|
+
<td>PostgreSQL ORM + migrations</td>
|
|
95
|
+
</tr>
|
|
96
|
+
<tr>
|
|
97
|
+
<td><img src="https://img.shields.io/badge/tRPC_v11-2596BE?style=flat-square&logo=trpc&logoColor=white" /></td>
|
|
98
|
+
<td>End-to-end type-safe API — no codegen</td>
|
|
99
|
+
</tr>
|
|
100
|
+
<tr>
|
|
101
|
+
<td><img src="https://img.shields.io/badge/Cloudflare_Workers-F38020?style=flat-square&logo=cloudflare&logoColor=white" /></td>
|
|
102
|
+
<td>Deploy target for API + web</td>
|
|
103
|
+
</tr>
|
|
104
|
+
</table>
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Full documentation
|
|
109
|
+
|
|
110
|
+
See the [blazestack repo](https://github.com/Alshahriah/blazestack) for full documentation.
|
package/dist/index.js
CHANGED
|
@@ -14,6 +14,103 @@ import { get } from "node:https";
|
|
|
14
14
|
import { tmpdir } from "node:os";
|
|
15
15
|
import { basename, extname, join } from "node:path";
|
|
16
16
|
|
|
17
|
+
// ../../node_modules/.bun/kleur@4.1.5/node_modules/kleur/index.mjs
|
|
18
|
+
var FORCE_COLOR;
|
|
19
|
+
var NODE_DISABLE_COLORS;
|
|
20
|
+
var NO_COLOR;
|
|
21
|
+
var TERM;
|
|
22
|
+
var isTTY = true;
|
|
23
|
+
if (typeof process !== "undefined") {
|
|
24
|
+
({ FORCE_COLOR, NODE_DISABLE_COLORS, NO_COLOR, TERM } = process.env || {});
|
|
25
|
+
isTTY = process.stdout && process.stdout.isTTY;
|
|
26
|
+
}
|
|
27
|
+
var $ = {
|
|
28
|
+
enabled: !NODE_DISABLE_COLORS && NO_COLOR == null && TERM !== "dumb" && (FORCE_COLOR != null && FORCE_COLOR !== "0" || isTTY),
|
|
29
|
+
reset: init(0, 0),
|
|
30
|
+
bold: init(1, 22),
|
|
31
|
+
dim: init(2, 22),
|
|
32
|
+
italic: init(3, 23),
|
|
33
|
+
underline: init(4, 24),
|
|
34
|
+
inverse: init(7, 27),
|
|
35
|
+
hidden: init(8, 28),
|
|
36
|
+
strikethrough: init(9, 29),
|
|
37
|
+
black: init(30, 39),
|
|
38
|
+
red: init(31, 39),
|
|
39
|
+
green: init(32, 39),
|
|
40
|
+
yellow: init(33, 39),
|
|
41
|
+
blue: init(34, 39),
|
|
42
|
+
magenta: init(35, 39),
|
|
43
|
+
cyan: init(36, 39),
|
|
44
|
+
white: init(37, 39),
|
|
45
|
+
gray: init(90, 39),
|
|
46
|
+
grey: init(90, 39),
|
|
47
|
+
bgBlack: init(40, 49),
|
|
48
|
+
bgRed: init(41, 49),
|
|
49
|
+
bgGreen: init(42, 49),
|
|
50
|
+
bgYellow: init(43, 49),
|
|
51
|
+
bgBlue: init(44, 49),
|
|
52
|
+
bgMagenta: init(45, 49),
|
|
53
|
+
bgCyan: init(46, 49),
|
|
54
|
+
bgWhite: init(47, 49)
|
|
55
|
+
};
|
|
56
|
+
function run(arr, str) {
|
|
57
|
+
let i = 0, tmp, beg = "", end = "";
|
|
58
|
+
for (;i < arr.length; i++) {
|
|
59
|
+
tmp = arr[i];
|
|
60
|
+
beg += tmp.open;
|
|
61
|
+
end += tmp.close;
|
|
62
|
+
if (!!~str.indexOf(tmp.close)) {
|
|
63
|
+
str = str.replace(tmp.rgx, tmp.close + tmp.open);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return beg + str + end;
|
|
67
|
+
}
|
|
68
|
+
function chain(has, keys) {
|
|
69
|
+
let ctx = { has, keys };
|
|
70
|
+
ctx.reset = $.reset.bind(ctx);
|
|
71
|
+
ctx.bold = $.bold.bind(ctx);
|
|
72
|
+
ctx.dim = $.dim.bind(ctx);
|
|
73
|
+
ctx.italic = $.italic.bind(ctx);
|
|
74
|
+
ctx.underline = $.underline.bind(ctx);
|
|
75
|
+
ctx.inverse = $.inverse.bind(ctx);
|
|
76
|
+
ctx.hidden = $.hidden.bind(ctx);
|
|
77
|
+
ctx.strikethrough = $.strikethrough.bind(ctx);
|
|
78
|
+
ctx.black = $.black.bind(ctx);
|
|
79
|
+
ctx.red = $.red.bind(ctx);
|
|
80
|
+
ctx.green = $.green.bind(ctx);
|
|
81
|
+
ctx.yellow = $.yellow.bind(ctx);
|
|
82
|
+
ctx.blue = $.blue.bind(ctx);
|
|
83
|
+
ctx.magenta = $.magenta.bind(ctx);
|
|
84
|
+
ctx.cyan = $.cyan.bind(ctx);
|
|
85
|
+
ctx.white = $.white.bind(ctx);
|
|
86
|
+
ctx.gray = $.gray.bind(ctx);
|
|
87
|
+
ctx.grey = $.grey.bind(ctx);
|
|
88
|
+
ctx.bgBlack = $.bgBlack.bind(ctx);
|
|
89
|
+
ctx.bgRed = $.bgRed.bind(ctx);
|
|
90
|
+
ctx.bgGreen = $.bgGreen.bind(ctx);
|
|
91
|
+
ctx.bgYellow = $.bgYellow.bind(ctx);
|
|
92
|
+
ctx.bgBlue = $.bgBlue.bind(ctx);
|
|
93
|
+
ctx.bgMagenta = $.bgMagenta.bind(ctx);
|
|
94
|
+
ctx.bgCyan = $.bgCyan.bind(ctx);
|
|
95
|
+
ctx.bgWhite = $.bgWhite.bind(ctx);
|
|
96
|
+
return ctx;
|
|
97
|
+
}
|
|
98
|
+
function init(open, close) {
|
|
99
|
+
let blk = {
|
|
100
|
+
open: `\x1B[${open}m`,
|
|
101
|
+
close: `\x1B[${close}m`,
|
|
102
|
+
rgx: new RegExp(`\\x1b\\[${close}m`, "g")
|
|
103
|
+
};
|
|
104
|
+
return function(txt) {
|
|
105
|
+
if (this !== undefined && this.has !== undefined) {
|
|
106
|
+
!!~this.has.indexOf(open) || (this.has.push(open), this.keys.push(blk));
|
|
107
|
+
return txt === undefined ? this : $.enabled ? run(this.keys, txt + "") : txt + "";
|
|
108
|
+
}
|
|
109
|
+
return txt === undefined ? chain([open], [blk]) : $.enabled ? run([blk], txt + "") : txt + "";
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
var kleur_default = $;
|
|
113
|
+
|
|
17
114
|
// ../../node_modules/.bun/tar@7.5.13/node_modules/tar/dist/esm/index.min.js
|
|
18
115
|
import Kr from "events";
|
|
19
116
|
import I from "fs";
|
|
@@ -31,7 +128,7 @@ import qr from "zlib";
|
|
|
31
128
|
import { posix as Zt } from "node:path";
|
|
32
129
|
import { basename as wn } from "node:path";
|
|
33
130
|
import fi from "fs";
|
|
34
|
-
import $ from "fs";
|
|
131
|
+
import $2 from "fs";
|
|
35
132
|
import $s from "path";
|
|
36
133
|
import { win32 as In } from "node:path";
|
|
37
134
|
import sr from "path";
|
|
@@ -1583,7 +1680,7 @@ var de = class extends D {
|
|
|
1583
1680
|
return t === "error" && (this.#t = true), super.emit(t, ...e);
|
|
1584
1681
|
}
|
|
1585
1682
|
[Qi]() {
|
|
1586
|
-
|
|
1683
|
+
$2.lstat(this.absolute, (t, e) => {
|
|
1587
1684
|
if (t)
|
|
1588
1685
|
return this.emit("error", t);
|
|
1589
1686
|
this[ei](e);
|
|
@@ -1625,7 +1722,7 @@ var de = class extends D {
|
|
|
1625
1722
|
this.path.slice(-1) !== "/" && (this.path += "/"), this.stat.size = 0, this[fe](), this.end();
|
|
1626
1723
|
}
|
|
1627
1724
|
[ji]() {
|
|
1628
|
-
|
|
1725
|
+
$2.readlink(this.absolute, (t, e) => {
|
|
1629
1726
|
if (t)
|
|
1630
1727
|
return this.emit("error", t);
|
|
1631
1728
|
this[ts](e);
|
|
@@ -1653,7 +1750,7 @@ var de = class extends D {
|
|
|
1653
1750
|
this[es]();
|
|
1654
1751
|
}
|
|
1655
1752
|
[es]() {
|
|
1656
|
-
|
|
1753
|
+
$2.open(this.absolute, "r", (t, e) => {
|
|
1657
1754
|
if (t)
|
|
1658
1755
|
return this.emit("error", t);
|
|
1659
1756
|
this[is](e);
|
|
@@ -1672,14 +1769,14 @@ var de = class extends D {
|
|
|
1672
1769
|
let { fd: t, buf: e, offset: i, length: r, pos: n } = this;
|
|
1673
1770
|
if (t === undefined || e === undefined)
|
|
1674
1771
|
throw new Error("cannot read file without first opening");
|
|
1675
|
-
|
|
1772
|
+
$2.read(t, e, i, r, n, (o, h) => {
|
|
1676
1773
|
if (o)
|
|
1677
1774
|
return this[pt](() => this.emit("error", o));
|
|
1678
1775
|
this[Ji](h);
|
|
1679
1776
|
});
|
|
1680
1777
|
}
|
|
1681
1778
|
[pt](t = () => {}) {
|
|
1682
|
-
this.fd !== undefined &&
|
|
1779
|
+
this.fd !== undefined && $2.close(this.fd, t);
|
|
1683
1780
|
}
|
|
1684
1781
|
[Ji](t) {
|
|
1685
1782
|
if (t <= 0 && this.remain > 0) {
|
|
@@ -1719,13 +1816,13 @@ var de = class extends D {
|
|
|
1719
1816
|
var si = class extends de {
|
|
1720
1817
|
sync = true;
|
|
1721
1818
|
[Qi]() {
|
|
1722
|
-
this[ei](
|
|
1819
|
+
this[ei]($2.lstatSync(this.absolute));
|
|
1723
1820
|
}
|
|
1724
1821
|
[ji]() {
|
|
1725
|
-
this[ts](
|
|
1822
|
+
this[ts]($2.readlinkSync(this.absolute));
|
|
1726
1823
|
}
|
|
1727
1824
|
[es]() {
|
|
1728
|
-
this[is](
|
|
1825
|
+
this[is]($2.openSync(this.absolute, "r"));
|
|
1729
1826
|
}
|
|
1730
1827
|
[ti]() {
|
|
1731
1828
|
let t = true;
|
|
@@ -1733,7 +1830,7 @@ var si = class extends de {
|
|
|
1733
1830
|
let { fd: e, buf: i, offset: r, length: n, pos: o } = this;
|
|
1734
1831
|
if (e === undefined || i === undefined)
|
|
1735
1832
|
throw new Error("fd and buf must be set in READ method");
|
|
1736
|
-
let h =
|
|
1833
|
+
let h = $2.readSync(e, i, r, n, o);
|
|
1737
1834
|
this[Ji](h), t = false;
|
|
1738
1835
|
} finally {
|
|
1739
1836
|
if (t)
|
|
@@ -1746,7 +1843,7 @@ var si = class extends de {
|
|
|
1746
1843
|
t();
|
|
1747
1844
|
}
|
|
1748
1845
|
[pt](t = () => {}) {
|
|
1749
|
-
this.fd !== undefined &&
|
|
1846
|
+
this.fd !== undefined && $2.closeSync(this.fd), t();
|
|
1750
1847
|
}
|
|
1751
1848
|
};
|
|
1752
1849
|
var ri = class extends D {
|
|
@@ -3165,7 +3262,21 @@ var So = (s3) => {
|
|
|
3165
3262
|
var REPO_OWNER = "Alshahriah";
|
|
3166
3263
|
var REPO_NAME = "blazestack";
|
|
3167
3264
|
var REPO_BRANCH = "main";
|
|
3168
|
-
var
|
|
3265
|
+
var VERSION = "0.3.0";
|
|
3266
|
+
var EXCLUDE = new Set([
|
|
3267
|
+
"node_modules",
|
|
3268
|
+
".git",
|
|
3269
|
+
"bun.lock",
|
|
3270
|
+
"packages/create-blaze",
|
|
3271
|
+
"docs",
|
|
3272
|
+
"assets",
|
|
3273
|
+
".vscode",
|
|
3274
|
+
"scripts",
|
|
3275
|
+
"CODE_OF_CONDUCT.md",
|
|
3276
|
+
"CONTRIBUTING.md",
|
|
3277
|
+
"README.md"
|
|
3278
|
+
]);
|
|
3279
|
+
var EXCLUDE_FILES = new Set([".github/workflows/publish.yml"]);
|
|
3169
3280
|
var TEXT_EXTENSIONS = new Set([
|
|
3170
3281
|
".ts",
|
|
3171
3282
|
".tsx",
|
|
@@ -3212,17 +3323,23 @@ function shouldExclude(relPath) {
|
|
|
3212
3323
|
return true;
|
|
3213
3324
|
if (parts[0] === "packages" && parts[1] === "create-blaze")
|
|
3214
3325
|
return true;
|
|
3326
|
+
const normalized = relPath.replace(/\\/g, "/");
|
|
3327
|
+
if (EXCLUDE_FILES.has(normalized))
|
|
3328
|
+
return true;
|
|
3215
3329
|
return false;
|
|
3216
3330
|
}
|
|
3217
|
-
function copyDir(src, dest, name) {
|
|
3331
|
+
function copyDir(src, dest, name, relBase = "") {
|
|
3218
3332
|
mkdirSync(dest, { recursive: true });
|
|
3219
3333
|
const entries = readdirSync(src);
|
|
3220
3334
|
for (const entry of entries) {
|
|
3221
3335
|
const srcPath = join(src, entry);
|
|
3222
3336
|
const destPath = join(dest, entry);
|
|
3337
|
+
const relPath = relBase ? `${relBase}/${entry}` : entry;
|
|
3338
|
+
if (EXCLUDE_FILES.has(relPath))
|
|
3339
|
+
continue;
|
|
3223
3340
|
const stat = statSync(srcPath);
|
|
3224
3341
|
if (stat.isDirectory()) {
|
|
3225
|
-
copyDir(srcPath, destPath, name);
|
|
3342
|
+
copyDir(srcPath, destPath, name, relPath);
|
|
3226
3343
|
} else {
|
|
3227
3344
|
if (isTextFile(srcPath)) {
|
|
3228
3345
|
const content = readFileSync(srcPath, "utf8");
|
|
@@ -3253,6 +3370,64 @@ function download(url, dest) {
|
|
|
3253
3370
|
request(url);
|
|
3254
3371
|
});
|
|
3255
3372
|
}
|
|
3373
|
+
function generateReadme(name) {
|
|
3374
|
+
return `# ${name}
|
|
3375
|
+
|
|
3376
|
+
Scaffolded with [create-blaze](https://github.com/Alshahriah/blazestack) — a full-stack Bun monorepo with end-to-end type safety.
|
|
3377
|
+
|
|
3378
|
+
## Stack
|
|
3379
|
+
|
|
3380
|
+
- **API** — Hono on Cloudflare Workers
|
|
3381
|
+
- **Web** — React Router v7 SSR on Cloudflare Workers
|
|
3382
|
+
- **Mobile** — Expo SDK 55 (iOS + Android)
|
|
3383
|
+
- **Auth** — Better Auth
|
|
3384
|
+
- **Database** — Drizzle ORM + PostgreSQL
|
|
3385
|
+
- **RPC** — tRPC v11 (no codegen)
|
|
3386
|
+
|
|
3387
|
+
## Getting started
|
|
3388
|
+
|
|
3389
|
+
\`\`\`bash
|
|
3390
|
+
bun install
|
|
3391
|
+
cp apps/api/.dev.vars.example apps/api/.dev.vars
|
|
3392
|
+
# Fill in DATABASE_URL, BETTER_AUTH_SECRET, BETTER_AUTH_URL
|
|
3393
|
+
|
|
3394
|
+
bun db:setup && bun db:generate && bun db:migrate
|
|
3395
|
+
|
|
3396
|
+
bun dev:api # API → http://localhost:8787
|
|
3397
|
+
bun dev:web # Web → http://localhost:5173
|
|
3398
|
+
bun dev:mobile # Mobile (optional)
|
|
3399
|
+
\`\`\`
|
|
3400
|
+
|
|
3401
|
+
## Structure
|
|
3402
|
+
|
|
3403
|
+
\`\`\`
|
|
3404
|
+
${name}/
|
|
3405
|
+
├── apps/
|
|
3406
|
+
│ ├── api/ Hono API — auth + tRPC
|
|
3407
|
+
│ ├── web/ React Router v7 SSR
|
|
3408
|
+
│ └── mobile/ Expo — iOS + Android
|
|
3409
|
+
└── packages/
|
|
3410
|
+
├── auth/ Better Auth factory
|
|
3411
|
+
├── db/ Drizzle schema + migrations
|
|
3412
|
+
├── env/ Zod-validated env vars
|
|
3413
|
+
├── trpc/ Shared tRPC router
|
|
3414
|
+
└── ui/ Shared components (web + native)
|
|
3415
|
+
\`\`\`
|
|
3416
|
+
|
|
3417
|
+
## Commands
|
|
3418
|
+
|
|
3419
|
+
\`\`\`bash
|
|
3420
|
+
bun dev:api # Start API
|
|
3421
|
+
bun dev:web # Start web app
|
|
3422
|
+
bun dev:mobile # Start mobile app
|
|
3423
|
+
bun db:generate # Generate migrations
|
|
3424
|
+
bun db:migrate # Run migrations
|
|
3425
|
+
bun db:studio # Open Drizzle Studio
|
|
3426
|
+
bun lint # Lint check
|
|
3427
|
+
bun lint:fix # Auto-fix lint
|
|
3428
|
+
\`\`\`
|
|
3429
|
+
`;
|
|
3430
|
+
}
|
|
3256
3431
|
function dirExists(p2) {
|
|
3257
3432
|
try {
|
|
3258
3433
|
statSync(p2);
|
|
@@ -3261,13 +3436,26 @@ function dirExists(p2) {
|
|
|
3261
3436
|
return false;
|
|
3262
3437
|
}
|
|
3263
3438
|
}
|
|
3439
|
+
function step(label) {
|
|
3440
|
+
process.stdout.write(` ${kleur_default.cyan("◆")} ${label.padEnd(30)}`);
|
|
3441
|
+
}
|
|
3442
|
+
function stepDone() {
|
|
3443
|
+
process.stdout.write(`${kleur_default.green("✓")}
|
|
3444
|
+
`);
|
|
3445
|
+
}
|
|
3446
|
+
function stepFail() {
|
|
3447
|
+
process.stdout.write(`${kleur_default.red("✗")}
|
|
3448
|
+
`);
|
|
3449
|
+
}
|
|
3264
3450
|
async function main() {
|
|
3265
3451
|
const input = process.argv[2];
|
|
3266
3452
|
const DEFAULT_NAME = "my-blazestack-app";
|
|
3267
3453
|
const rawName = input ?? DEFAULT_NAME;
|
|
3268
3454
|
const baseName = sanitizeName(rawName);
|
|
3269
3455
|
if (!baseName) {
|
|
3270
|
-
console.error(`
|
|
3456
|
+
console.error(kleur_default.red(`
|
|
3457
|
+
Invalid project name: "${rawName}"
|
|
3458
|
+
`));
|
|
3271
3459
|
process.exit(1);
|
|
3272
3460
|
}
|
|
3273
3461
|
let safeName = baseName;
|
|
@@ -3276,27 +3464,29 @@ async function main() {
|
|
|
3276
3464
|
safeName = `${baseName}-${counter}`;
|
|
3277
3465
|
counter++;
|
|
3278
3466
|
}
|
|
3279
|
-
if (safeName !== baseName) {
|
|
3280
|
-
console.log(`
|
|
3281
|
-
"${baseName}" already exists — using "${safeName}" instead.`);
|
|
3282
|
-
}
|
|
3283
3467
|
const targetDir = join(process.cwd(), safeName);
|
|
3284
3468
|
const tarUrl = `https://codeload.github.com/${REPO_OWNER}/${REPO_NAME}/tar.gz/refs/heads/${REPO_BRANCH}`;
|
|
3285
3469
|
const tmpFile = join(tmpdir(), `create-blaze-${Date.now()}.tar.gz`);
|
|
3286
3470
|
const tmpExtract = join(tmpdir(), `create-blaze-${Date.now()}`);
|
|
3287
|
-
console.log(
|
|
3288
|
-
|
|
3289
|
-
|
|
3471
|
+
console.log();
|
|
3472
|
+
console.log(` ${kleur_default.bgCyan().black(` create-blaze v${VERSION} `)}`);
|
|
3473
|
+
console.log();
|
|
3474
|
+
if (safeName !== baseName) {
|
|
3475
|
+
console.log(` ${kleur_default.yellow("!")} ${kleur_default.dim(`"${baseName}" already exists — using "${safeName}" instead.`)}`);
|
|
3476
|
+
console.log();
|
|
3477
|
+
}
|
|
3478
|
+
console.log(` Scaffolding ${kleur_default.cyan().bold(safeName)}...`);
|
|
3479
|
+
console.log();
|
|
3290
3480
|
try {
|
|
3291
|
-
|
|
3481
|
+
step("Downloading template");
|
|
3292
3482
|
await download(tarUrl, tmpFile);
|
|
3293
|
-
|
|
3294
|
-
|
|
3483
|
+
stepDone();
|
|
3484
|
+
step("Extracting");
|
|
3295
3485
|
mkdirSync(tmpExtract, { recursive: true });
|
|
3296
3486
|
await co({ file: tmpFile, cwd: tmpExtract });
|
|
3297
|
-
|
|
3487
|
+
stepDone();
|
|
3488
|
+
step("Setting up project");
|
|
3298
3489
|
const extractedRoot = join(tmpExtract, `${REPO_NAME}-${REPO_BRANCH}`);
|
|
3299
|
-
process.stdout.write(" Scaffolding project...");
|
|
3300
3490
|
mkdirSync(targetDir, { recursive: true });
|
|
3301
3491
|
const entries = readdirSync(extractedRoot);
|
|
3302
3492
|
for (const entry of entries) {
|
|
@@ -3311,10 +3501,10 @@ Creating ${safeName}...
|
|
|
3311
3501
|
for (const pkg of readdirSync(srcPath)) {
|
|
3312
3502
|
if (pkg === "create-blaze")
|
|
3313
3503
|
continue;
|
|
3314
|
-
copyDir(join(srcPath, pkg), join(destPath, pkg), safeName);
|
|
3504
|
+
copyDir(join(srcPath, pkg), join(destPath, pkg), safeName, `packages/${pkg}`);
|
|
3315
3505
|
}
|
|
3316
3506
|
} else {
|
|
3317
|
-
copyDir(srcPath, destPath, safeName);
|
|
3507
|
+
copyDir(srcPath, destPath, safeName, entry);
|
|
3318
3508
|
}
|
|
3319
3509
|
} else {
|
|
3320
3510
|
if (isTextFile(srcPath)) {
|
|
@@ -3325,7 +3515,11 @@ Creating ${safeName}...
|
|
|
3325
3515
|
}
|
|
3326
3516
|
}
|
|
3327
3517
|
}
|
|
3328
|
-
|
|
3518
|
+
stepDone();
|
|
3519
|
+
writeFileSync(join(targetDir, "README.md"), generateReadme(safeName), "utf8");
|
|
3520
|
+
} catch (err) {
|
|
3521
|
+
stepFail();
|
|
3522
|
+
throw err;
|
|
3329
3523
|
} finally {
|
|
3330
3524
|
try {
|
|
3331
3525
|
rmSync(tmpFile, { force: true });
|
|
@@ -3334,20 +3528,24 @@ Creating ${safeName}...
|
|
|
3334
3528
|
rmSync(tmpExtract, { recursive: true, force: true });
|
|
3335
3529
|
} catch {}
|
|
3336
3530
|
}
|
|
3337
|
-
console.log(
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
bun
|
|
3347
|
-
|
|
3531
|
+
console.log();
|
|
3532
|
+
console.log(` ${kleur_default.green().bold("Ready!")} Your project is set up.`);
|
|
3533
|
+
console.log();
|
|
3534
|
+
console.log(` ${kleur_default.dim("Next steps:")}`);
|
|
3535
|
+
console.log();
|
|
3536
|
+
console.log(` ${kleur_default.yellow(`cd ${safeName}`)}`);
|
|
3537
|
+
console.log(` ${kleur_default.yellow("bun install")}`);
|
|
3538
|
+
console.log(` ${kleur_default.yellow("cp apps/api/.dev.vars.example apps/api/.dev.vars")}`);
|
|
3539
|
+
console.log(` ${kleur_default.dim("# add DATABASE_URL + BETTER_AUTH_SECRET to .dev.vars")}`);
|
|
3540
|
+
console.log(` ${kleur_default.yellow("bun db:setup && bun db:generate && bun db:migrate")}`);
|
|
3541
|
+
console.log();
|
|
3542
|
+
console.log(` ${kleur_default.yellow("bun dev:api")} ${kleur_default.dim("─")} ${kleur_default.dim("API")} ${kleur_default.dim("→")} ${kleur_default.cyan("http://localhost:8787")}`);
|
|
3543
|
+
console.log(` ${kleur_default.yellow("bun dev:web")} ${kleur_default.dim("─")} ${kleur_default.dim("Web")} ${kleur_default.dim("→")} ${kleur_default.cyan("http://localhost:5173")}`);
|
|
3544
|
+
console.log();
|
|
3348
3545
|
}
|
|
3349
3546
|
main().catch((err) => {
|
|
3350
3547
|
console.error(`
|
|
3351
|
-
Error
|
|
3548
|
+
${kleur_default.red("Error:")} ${err.message}
|
|
3549
|
+
`);
|
|
3352
3550
|
process.exit(1);
|
|
3353
3551
|
});
|
package/package.json
CHANGED
|
@@ -1,24 +1,38 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-blaze",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Create a new blazestack project",
|
|
5
|
-
"keywords": [
|
|
5
|
+
"keywords": [
|
|
6
|
+
"blazestack",
|
|
7
|
+
"create-blaze",
|
|
8
|
+
"hono",
|
|
9
|
+
"trpc",
|
|
10
|
+
"drizzle",
|
|
11
|
+
"better-auth",
|
|
12
|
+
"expo",
|
|
13
|
+
"cloudflare"
|
|
14
|
+
],
|
|
6
15
|
"homepage": "https://github.com/Alshahriah/blazestack",
|
|
7
16
|
"repository": {
|
|
8
17
|
"type": "git",
|
|
9
|
-
"url": "https://github.com/Alshahriah/blazestack.git",
|
|
18
|
+
"url": "git+https://github.com/Alshahriah/blazestack.git",
|
|
10
19
|
"directory": "packages/create-blaze"
|
|
11
20
|
},
|
|
12
21
|
"license": "MIT",
|
|
13
22
|
"type": "module",
|
|
23
|
+
"files": [
|
|
24
|
+
"dist",
|
|
25
|
+
"README.md"
|
|
26
|
+
],
|
|
14
27
|
"bin": {
|
|
15
|
-
"create-blaze": "
|
|
28
|
+
"create-blaze": "dist/index.js"
|
|
16
29
|
},
|
|
17
30
|
"scripts": {
|
|
18
31
|
"build": "bun build src/index.ts --outdir dist --target node --format esm",
|
|
19
32
|
"dev": "bun run src/index.ts"
|
|
20
33
|
},
|
|
21
34
|
"dependencies": {
|
|
35
|
+
"kleur": "^4.1.5",
|
|
22
36
|
"tar": "^7.4.3"
|
|
23
37
|
},
|
|
24
38
|
"devDependencies": {
|