@clubedge/create-clubedge-app 0.14.0 → 0.15.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/CHANGELOG.md +14 -0
- package/README.md +140 -77
- package/dist/cli/args.js +29 -11
- package/dist/cli/ui.js +19 -8
- package/dist/core/env.js +4 -0
- package/dist/core/health.js +161 -0
- package/dist/core/merge.js +8 -0
- package/dist/core/releases.js +59 -0
- package/dist/core/source.js +3 -1
- package/dist/index.js +9 -0
- package/dist/inspect.js +125 -0
- package/dist/modify.js +49 -28
- package/package.json +3 -3
- package/template/README.md +179 -51
- package/template/apps/start/package.json +1 -1
- package/template/apps/start/src/nitro/plugins/jobs.ts +2 -2
- package/template/apps/start/src/server/jobs.test.ts +27 -0
- package/template/apps/start/src/server/jobs.ts +20 -8
- package/template/apps/start/src/server/observability.test.ts +23 -0
- package/template/apps/start/src/server/observability.ts +10 -2
- package/template/apps/start/src/server/variants/observability.sentry.ts +10 -2
- package/template/apps/web/package.json +1 -1
- package/template/apps/web/src/server/jobs.ts +20 -8
- package/template/apps/web/src/server/observability.ts +10 -2
- package/template/apps/web/src/server/variants/observability.sentry.ts +10 -2
- package/template/clubedge.template.json +3 -0
- package/template/package.json +1 -1
- package/template/packages/auth/package.json +1 -1
- package/template/packages/auth-better-auth/package.json +1 -1
- package/template/packages/auth-supabase/package.json +1 -1
- package/template/packages/cache/package.json +1 -1
- package/template/packages/cache-redis/package.json +1 -1
- package/template/packages/core/package.json +1 -1
- package/template/packages/db/package.json +1 -1
- package/template/packages/email/package.json +1 -1
- package/template/packages/email-resend/package.json +1 -1
- package/template/packages/email-smtp/package.json +1 -1
- package/template/packages/jobs/package.json +1 -1
- package/template/packages/jobs-pg-boss/package.json +1 -1
- package/template/packages/local-db/package.json +1 -1
- package/template/packages/observability/package.json +1 -1
- package/template/packages/observability-otel/package.json +1 -1
- package/template/packages/observability-sentry/package.json +1 -1
- package/template/packages/payments/package.json +1 -1
- package/template/packages/payments-stripe/package.json +1 -1
- package/template/packages/storage/package.json +1 -1
- package/template/packages/storage-s3/package.json +1 -1
- package/template/packages/storage-supabase/package.json +1 -1
- package/template/packages/ui/package.json +1 -1
- package/template.lock.json +4 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `create-clubedge-app` are documented here.
|
|
4
4
|
|
|
5
|
+
## 0.15.0
|
|
6
|
+
|
|
7
|
+
- Add `status`: a project's Starter release, framework, modules, and Git state, whether a newer Starter release exists (from npm, still working offline), and the command to run next.
|
|
8
|
+
- Add `doctor`: checks Node.js and pnpm against the project's versions, installed dependencies, the lockfile, and the env file against the example, then runs `pnpm check:services` (`--no-services` skips it). It exits with an error when a check fails.
|
|
9
|
+
- `add` and `remove` take several modules (`add email resend payments stripe`, `remove storage payments`) and apply them as one change, checking requirements after every change.
|
|
10
|
+
- After a change with conflicts, list each file with its number of conflict blocks.
|
|
11
|
+
- `upgrade` lists the Starter releases it crosses, with the sections of their release notes.
|
|
12
|
+
- Fix a finished command exiting with an error when Windows briefly locked the downloaded Starter's temporary folder.
|
|
13
|
+
- CI: test generated projects on macOS too; the release workflow waits up to 15 minutes for npm.
|
|
14
|
+
|
|
15
|
+
## 0.14.1
|
|
16
|
+
|
|
17
|
+
- Default to Starter `v0.13.1`. In projects with background jobs or observability, a configuration error such as a missing `DATABASE_URL` no longer stops the server at startup; pages that need no database keep working, and the error is reported once.
|
|
18
|
+
|
|
5
19
|
## 0.14.0
|
|
6
20
|
|
|
7
21
|
- Default to Starter `v0.13.0`, which adds observability (`--observability otel|sentry`): request tracing and server error reporting through OpenTelemetry, to any OTLP collector, or Sentry, behind provider-neutral hooks in `@clubedge/core`. `--observability` needs no CLI code: it comes from the Starter's manifest.
|
package/README.md
CHANGED
|
@@ -1,76 +1,57 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
1
3
|
# create-clubedge-app
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
[](LICENSE)
|
|
5
|
+
**Create a production-ready Next.js or TanStack Start app with one command, and keep it up to date.**
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
Pick only the modules you need: auth, storage, email, payments, jobs, observability, deployment.<br>
|
|
8
|
+
Add, remove, or upgrade them later without losing your own changes.
|
|
7
9
|
|
|
8
|
-
|
|
10
|
+
[](https://www.npmjs.com/package/@clubedge/create-clubedge-app)
|
|
11
|
+
[](https://www.npmjs.com/package/@clubedge/create-clubedge-app)
|
|
12
|
+
[](https://github.com/Clubedge/create-clubedge-app/actions/workflows/ci.yml)
|
|
13
|
+
[](https://github.com/Clubedge/create-clubedge-app/releases)
|
|
14
|
+
[](LICENSE)
|
|
9
15
|
|
|
10
|
-
|
|
16
|
+
[Website](https://starter.clubedge.live) ·
|
|
17
|
+
[Clubedge Starter](https://github.com/Clubedge/clubedge-starter) ·
|
|
18
|
+
[Changelog](CHANGELOG.md) ·
|
|
19
|
+
[Roadmap](ROADMAP.md) ·
|
|
20
|
+
[Contributing](CONTRIBUTING.md)
|
|
11
21
|
|
|
12
|
-
|
|
22
|
+
</div>
|
|
13
23
|
|
|
14
|
-
```
|
|
15
|
-
create-clubedge-app
|
|
16
|
-
|
|
|
17
|
-
v
|
|
18
|
-
Clubedge Starter v0.13.0
|
|
19
|
-
commit 62fb8d1b1e13ed8e8e134bd1e53f2bfdde2c6a50
|
|
24
|
+
```sh
|
|
25
|
+
pnpm dlx @clubedge/create-clubedge-app my-app
|
|
20
26
|
```
|
|
21
27
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
| CLI release | Default Starter release | Meaning |
|
|
25
|
-
| --- | --- | --- |
|
|
26
|
-
| `create-clubedge-app@0.14.0` | `clubedge-starter@v0.13.0` | The CLI's required, tested default |
|
|
28
|
+
## Why create-clubedge-app
|
|
27
29
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
The `v0.13.0` tag is expected to resolve to commit
|
|
31
|
-
`62fb8d1b1e13ed8e8e134bd1e53f2bfdde2c6a50`. The CLI verifies this before
|
|
32
|
-
scaffolding with the default reference and fails rather than silently using a
|
|
33
|
-
moved tag.
|
|
30
|
+
Copying a starter is easy; living with it is not. You delete the services you don't use by hand, and once you've changed the code, every later improvement to the starter has to be copied over by hand too.
|
|
34
31
|
|
|
35
|
-
|
|
32
|
+
create-clubedge-app generates a project from a tested release of [Clubedge Starter](https://github.com/Clubedge/clubedge-starter) with only the modules you choose. A module you leave out is removed completely: its package, its provider SDK, its environment variables, its documentation, and its lockfile entries. The project records exactly what it was generated from, so later the CLI can add a module, remove one, or upgrade to a newer Starter release by merging the change into your code. Files you never touched are updated; your edits are kept.
|
|
36
33
|
|
|
37
|
-
|
|
34
|
+
Every CLI release is pinned to one Starter release and verified against it, so the same command always produces the same project.
|
|
38
35
|
|
|
39
|
-
|
|
40
|
-
- pnpm 10.9.0 or newer. The generated project is a pnpm workspace, so dependencies are installed with pnpm even when you start the CLI with `npx`; the CLI falls back to `corepack pnpm` when `pnpm` is not on your path.
|
|
41
|
-
- Git, when using the default Git initialization.
|
|
42
|
-
- Internet access to install dependencies. The default Starter release ships inside the CLI package, so GitHub is only contacted for `--ref`.
|
|
36
|
+
## Quick start
|
|
43
37
|
|
|
44
|
-
|
|
38
|
+
You need Node.js 22.12 or newer and pnpm 10.9.0 or newer. Git is used for the default repository initialization.
|
|
45
39
|
|
|
46
40
|
```sh
|
|
47
41
|
pnpm dlx @clubedge/create-clubedge-app my-app
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
Or run it with npm:
|
|
51
|
-
|
|
52
|
-
```sh
|
|
53
|
-
npx @clubedge/create-clubedge-app my-app
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
After scaffolding:
|
|
57
|
-
|
|
58
|
-
```sh
|
|
59
42
|
cd my-app
|
|
60
43
|
pnpm dev
|
|
61
44
|
```
|
|
62
45
|
|
|
63
|
-
|
|
46
|
+
Or start it with npm: `npx @clubedge/create-clubedge-app my-app`. The generated project is a pnpm workspace, so dependencies are installed with pnpm either way; the CLI falls back to `corepack pnpm` when `pnpm` is not on your path. Without a destination, the CLI asks where to create the project.
|
|
64
47
|
|
|
65
|
-
|
|
48
|
+
The generated project includes `apps/web/.env.local`, created from the example and pointing at the local services you chose. Its `SETUP.md` describes every variable and provider. The root route is a landing page named after your project, and the dashboard is at `/dashboard`.
|
|
66
49
|
|
|
67
|
-
|
|
68
|
-
pnpm dlx @clubedge/create-clubedge-app
|
|
69
|
-
```
|
|
50
|
+
The default Starter release ships inside the CLI package, so GitHub is only contacted when you pass `--ref`. Internet access is needed to install dependencies.
|
|
70
51
|
|
|
71
|
-
|
|
52
|
+
## Choosing a framework
|
|
72
53
|
|
|
73
|
-
The Starter ships the same application for two React frameworks. Next.js is the default; pick TanStack Start with `--framework`, or choose interactively
|
|
54
|
+
The Starter ships the same application for two React frameworks. Next.js is the default; pick TanStack Start with `--framework`, or choose interactively:
|
|
74
55
|
|
|
75
56
|
```sh
|
|
76
57
|
pnpm dlx @clubedge/create-clubedge-app my-app --framework tanstack-start
|
|
@@ -83,9 +64,9 @@ pnpm dlx @clubedge/create-clubedge-app my-app --framework tanstack-start
|
|
|
83
64
|
|
|
84
65
|
Either way, the app lives in `apps/web` and uses the same shared packages, so the project layout, root scripts, and Docker commands are identical.
|
|
85
66
|
|
|
86
|
-
|
|
67
|
+
## Choosing modules
|
|
87
68
|
|
|
88
|
-
Authentication, file storage, caching, email, payments, background jobs, observability, local infrastructure, and deployment are modules. Each has a default, and anything you leave out is removed completely
|
|
69
|
+
Authentication, file storage, caching, email, payments, background jobs, observability, local infrastructure, and deployment are modules. Each has a default, and anything you leave out is removed completely. The Starter's `clubedge.template.json` defines the modules, so a module a newer Starter adds gets its `--<module>` flag without a CLI change; `--help` lists the modules of the Starter this CLI release creates.
|
|
89
70
|
|
|
90
71
|
| Flag | Options | Default |
|
|
91
72
|
| ----------- | ------------------------------------------ | ---------- |
|
|
@@ -101,35 +82,40 @@ Authentication, file storage, caching, email, payments, background jobs, observa
|
|
|
101
82
|
|
|
102
83
|
```sh
|
|
103
84
|
# Only the monorepo, UI, database, and tooling
|
|
104
|
-
pnpm dlx @clubedge/create-clubedge-app my-app --auth none --storage none --cache memory
|
|
85
|
+
pnpm dlx @clubedge/create-clubedge-app my-app --auth none --storage none --cache memory --email none
|
|
86
|
+
|
|
87
|
+
# A SaaS starting point: your own auth, payments, and background jobs, no Docker needed
|
|
88
|
+
pnpm dlx @clubedge/create-clubedge-app my-app --auth better-auth --payments stripe --jobs pg-boss --infra local
|
|
105
89
|
```
|
|
106
90
|
|
|
107
|
-
Interactive runs ask whether to customize these after the framework question.
|
|
91
|
+
Interactive runs ask whether to customize these after the framework question.
|
|
108
92
|
|
|
109
93
|
## Options
|
|
110
94
|
|
|
111
95
|
```text
|
|
112
|
-
Usage:
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
--
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
--
|
|
120
|
-
|
|
121
|
-
--
|
|
122
|
-
|
|
123
|
-
--
|
|
124
|
-
--
|
|
125
|
-
|
|
126
|
-
-
|
|
96
|
+
Usage:
|
|
97
|
+
pnpm dlx @clubedge/create-clubedge-app [project-directory] [options]
|
|
98
|
+
pnpm dlx @clubedge/create-clubedge-app add [module option]... (inside a project)
|
|
99
|
+
pnpm dlx @clubedge/create-clubedge-app remove [module]... (inside a project)
|
|
100
|
+
pnpm dlx @clubedge/create-clubedge-app upgrade [--ref <tag>] (inside a project)
|
|
101
|
+
|
|
102
|
+
Options:
|
|
103
|
+
--framework <id> App framework, such as next or tanstack-start
|
|
104
|
+
--<module> <option> A module option, such as --auth none; the Starter lists its modules
|
|
105
|
+
--ref <ref> Download this Starter tag, branch, or commit from GitHub instead
|
|
106
|
+
(upgrade: the Starter to upgrade to)
|
|
107
|
+
--template-dir <path> Scaffold from a local Starter checkout (for Starter development)
|
|
108
|
+
--dry-run Show what would be created or changed without writing anything
|
|
109
|
+
--force add/remove: change a project with uncommitted changes or without Git
|
|
110
|
+
-y, --yes Accept defaults and never prompt (default directory: my-app)
|
|
111
|
+
--no-install Skip dependency installation
|
|
112
|
+
--no-git Skip Git repository initialization
|
|
113
|
+
-h, --help Show this help
|
|
114
|
+
-v, --version Show the CLI version
|
|
127
115
|
```
|
|
128
116
|
|
|
129
117
|
The target directory must be empty or not exist. The CLI never deletes or overwrites existing files, and if scaffolding fails it removes whatever it wrote, so a failed run leaves nothing behind.
|
|
130
118
|
|
|
131
|
-
Every generated project records its CLI version, Starter repository, Starter ref, Starter commit, framework, and modules in `package.json` and `README.md`.
|
|
132
|
-
|
|
133
119
|
```sh
|
|
134
120
|
# Preview the files and edits without writing anything
|
|
135
121
|
pnpm dlx @clubedge/create-clubedge-app my-app --dry-run
|
|
@@ -141,7 +127,7 @@ pnpm dlx @clubedge/create-clubedge-app my-app --yes --no-git --framework tanstac
|
|
|
141
127
|
pnpm dlx @clubedge/create-clubedge-app my-app --ref main
|
|
142
128
|
|
|
143
129
|
# Reproduce a specific Starter release or commit
|
|
144
|
-
pnpm dlx @clubedge/create-clubedge-app my-app --ref v0.13.
|
|
130
|
+
pnpm dlx @clubedge/create-clubedge-app my-app --ref v0.13.1
|
|
145
131
|
pnpm dlx @clubedge/create-clubedge-app my-app --ref <commit-sha>
|
|
146
132
|
|
|
147
133
|
# Test local Starter changes before releasing them
|
|
@@ -150,15 +136,17 @@ pnpm dlx @clubedge/create-clubedge-app my-app --template-dir ../clubedge-starter
|
|
|
150
136
|
|
|
151
137
|
## Change an existing project
|
|
152
138
|
|
|
153
|
-
Inside a project created by the CLI, `add` and `remove` change
|
|
139
|
+
Inside a project created by the CLI, `add` and `remove` change modules, and `upgrade` moves the project to a newer Starter release. Projects from Starter v0.8.0 on have a `clubedge` script, so `pnpm clubedge add cache redis` works too. Without a module or option, `add` and `remove` ask for them:
|
|
154
140
|
|
|
155
141
|
```sh
|
|
156
142
|
pnpm clubedge add # choose a module and option from a list
|
|
157
143
|
pnpm dlx @clubedge/create-clubedge-app add cache redis # or switch: add auth better-auth
|
|
158
144
|
pnpm dlx @clubedge/create-clubedge-app remove storage
|
|
145
|
+
pnpm clubedge add email resend payments stripe # several modules as one change
|
|
146
|
+
pnpm clubedge remove storage payments
|
|
159
147
|
pnpm dlx @clubedge/create-clubedge-app add infra local --dry-run
|
|
160
148
|
pnpm dlx @clubedge/create-clubedge-app@latest upgrade # to the newest CLI's Starter release
|
|
161
|
-
pnpm dlx @clubedge/create-clubedge-app upgrade --ref v0.13.
|
|
149
|
+
pnpm dlx @clubedge/create-clubedge-app upgrade --ref v0.13.1 # or a specific tag, branch, or commit
|
|
162
150
|
```
|
|
163
151
|
|
|
164
152
|
The CLI renders the project twice, from the Starter commit and modules recorded in your `package.json` and from the new state, and merges the difference into your project. The new state has other modules for `add` and `remove`, and the newer Starter with the same modules for `upgrade`. Modules a newer Starter introduces start as `none` where possible, so an upgrade never adds a service on its own.
|
|
@@ -169,8 +157,50 @@ The CLI renders the project twice, from the Starter commit and modules recorded
|
|
|
169
157
|
- `apps/web/.env.local` keeps your values. Values still at their generated defaults follow the new selection, and new variables are added.
|
|
170
158
|
- `pnpm-lock.yaml` is replaced if you never changed your dependencies; otherwise `pnpm install` reconciles it.
|
|
171
159
|
|
|
160
|
+
Several modules in one command are applied as one change, and their requirements are checked together, so `add auth supabase storage supabase` works even though Supabase Storage needs Supabase Auth. When lines conflict, the CLI lists each file with its number of conflict blocks. Before an upgrade, it lists the Starter releases it crosses with the sections of their release notes, such as `v0.13.0 Observability, Tests, Also`.
|
|
161
|
+
|
|
172
162
|
The project must be a Git repository without uncommitted changes, so you can review the result with `git diff` and undo it. Pass `--force` to skip this check. Add `--no-install` to skip `pnpm install`. Afterward, run `pnpm db:migrate` and `pnpm check:services` if the change added tables or services.
|
|
173
163
|
|
|
164
|
+
## Check a project
|
|
165
|
+
|
|
166
|
+
Two read-only commands help you keep a project healthy:
|
|
167
|
+
|
|
168
|
+
```sh
|
|
169
|
+
pnpm clubedge status # Starter release, modules, Git state, and whether a newer Starter exists
|
|
170
|
+
pnpm clubedge doctor # Node.js, pnpm, dependencies, lockfile, env file, and pnpm check:services
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
`status` ends with the command to run next, such as `pnpm clubedge upgrade` when a newer Starter release is available; it asks npm for the newest CLI and still works offline. `doctor` checks that Node.js and pnpm meet the project's versions, that dependencies are installed, that `pnpm-lock.yaml` matches every `package.json`, and that `apps/web/.env.local` has every variable in `.env.example`, then runs `pnpm check:services` (skip it with `--no-services`). It exits with an error when a check fails, so it also works in CI.
|
|
174
|
+
|
|
175
|
+
## Version relationship
|
|
176
|
+
|
|
177
|
+
Each CLI release is tested against one specific Starter release:
|
|
178
|
+
|
|
179
|
+
```text
|
|
180
|
+
create-clubedge-app v0.15.0
|
|
181
|
+
|
|
|
182
|
+
v
|
|
183
|
+
Clubedge Starter v0.13.1
|
|
184
|
+
commit 28bfbf98c85ae500ace6a062dd10d67746e1a330
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
The current relationship is:
|
|
188
|
+
|
|
189
|
+
| CLI release | Default Starter release | Meaning |
|
|
190
|
+
| --- | --- | --- |
|
|
191
|
+
| `create-clubedge-app@0.15.0` | `clubedge-starter@v0.13.1` | The CLI's required, tested default |
|
|
192
|
+
|
|
193
|
+
This means the same CLI version always scaffolds the same Starter revision by default. The CLI does not silently follow Starter `main`.
|
|
194
|
+
|
|
195
|
+
The `v0.13.1` tag is expected to resolve to commit
|
|
196
|
+
`28bfbf98c85ae500ace6a062dd10d67746e1a330`. The CLI verifies this before
|
|
197
|
+
scaffolding with the default reference and fails rather than silently using a
|
|
198
|
+
moved tag.
|
|
199
|
+
|
|
200
|
+
When the Starter changes, its maintainers first publish a new versioned release, such as `v0.13.1`. The CLI is then updated to use that release, all generated-project checks must pass, and a new CLI version is published. This keeps Starter and CLI releases independently versioned while preserving a tested compatibility relationship.
|
|
201
|
+
|
|
202
|
+
Every generated project records its CLI version, Starter repository, Starter ref, Starter commit, framework, and modules in `package.json` and `README.md`.
|
|
203
|
+
|
|
174
204
|
## How it works
|
|
175
205
|
|
|
176
206
|
Each CLI release bundles one Starter release. When the release is built, `scripts/bundle-template.mjs` clones the pinned Starter tag, verifies that it resolves to the pinned commit, and copies its tracked files into the package (`template/` and `template.lock.json`). Running the CLI then needs no GitHub access for the default Starter.
|
|
@@ -182,11 +212,24 @@ The CLI first builds a plan (the files to copy and the edits to make), which `--
|
|
|
182
212
|
```text
|
|
183
213
|
src/
|
|
184
214
|
cli/ argument parsing and terminal output
|
|
185
|
-
core/ manifest, template sources, customizations, planning, and execution
|
|
215
|
+
core/ manifest, template sources, customizations, planning, merging, and execution
|
|
186
216
|
steps/ Git initialization and dependency installation
|
|
187
217
|
utils/ file listing and copying, processes, and naming
|
|
188
218
|
```
|
|
189
219
|
|
|
220
|
+
## Documentation
|
|
221
|
+
|
|
222
|
+
| I want to | Read |
|
|
223
|
+
| --- | --- |
|
|
224
|
+
| Configure a generated project | Its `SETUP.md`, also in the [Starter repository](https://github.com/Clubedge/clubedge-starter/blob/main/SETUP.md) |
|
|
225
|
+
| Change modules or upgrade a project | [Change an existing project](#change-an-existing-project) |
|
|
226
|
+
| See where a project stands, or why it does not run | [Check a project](#check-a-project) |
|
|
227
|
+
| Reproduce an exact Starter version | [Version relationship](#version-relationship) |
|
|
228
|
+
| See what changed in each release | [CHANGELOG.md](CHANGELOG.md) |
|
|
229
|
+
| See what is planned next | [ROADMAP.md](ROADMAP.md) |
|
|
230
|
+
| Contribute code | [CONTRIBUTING.md](CONTRIBUTING.md) |
|
|
231
|
+
| Report a security problem | [SECURITY.md](SECURITY.md) |
|
|
232
|
+
|
|
190
233
|
## Development
|
|
191
234
|
|
|
192
235
|
```sh
|
|
@@ -200,7 +243,7 @@ node ./bin/create.mjs my-app --template-dir ../clubedge-starter --dry-run
|
|
|
200
243
|
|
|
201
244
|
Without a bundled template, a local build downloads the pinned Starter release from GitHub and verifies its commit. Run `pnpm bundle-template` to bundle it, or `pnpm bundle-template --from ../clubedge-starter` to bundle a local checkout.
|
|
202
245
|
|
|
203
|
-
CI packs the CLI with `npm pack`, scaffolds
|
|
246
|
+
CI packs the CLI with `npm pack`, scaffolds clean projects from the packed tarball, installs their dependencies, runs linting, typechecking, unit tests, browser checks, and a production build, then starts each generated app and checks the landing page, sign-up page, dashboard, health endpoint, logo, and favicon. It also adds and removes modules in an existing project and upgrades a project from an older Starter. A scheduled, non-blocking compatibility job checks Starter `main`.
|
|
204
247
|
|
|
205
248
|
## Release workflow
|
|
206
249
|
|
|
@@ -209,7 +252,7 @@ CI packs the CLI with `npm pack`, scaffolds a clean project from the packed tarb
|
|
|
209
252
|
1. Make and validate changes in `clubedge-starter`.
|
|
210
253
|
2. Run lint, typecheck, unit tests, browser tests, and production build.
|
|
211
254
|
3. Update the Starter package versions.
|
|
212
|
-
4. Commit `main`, create a release tag such as `v0.13.
|
|
255
|
+
4. Commit `main`, create a release tag such as `v0.13.1`, and publish the Starter release.
|
|
213
256
|
|
|
214
257
|
### CLI maintainers
|
|
215
258
|
|
|
@@ -221,9 +264,29 @@ CI packs the CLI with `npm pack`, scaffolds a clean project from the packed tarb
|
|
|
221
264
|
|
|
222
265
|
The required CI job always tests the pinned default. The scheduled compatibility job tests Starter `main` early, but unreleased Starter changes must not change the stable CLI default.
|
|
223
266
|
|
|
224
|
-
##
|
|
267
|
+
## Roadmap
|
|
268
|
+
|
|
269
|
+
Each phase ends with a Starter release and a CLI release pinned to it. The full plan is in [ROADMAP.md](ROADMAP.md).
|
|
225
270
|
|
|
226
|
-
|
|
271
|
+
| CLI release | Starter release | Theme |
|
|
272
|
+
| --- | --- | --- |
|
|
273
|
+
| 0.5.0 to 0.9.0 | v0.5.0 to v0.8.0 | Optional modules, local services, `add`, `remove`, and `upgrade` |
|
|
274
|
+
| 0.10.0 | v0.9.0 | Module flags from the Starter's manifest, and email |
|
|
275
|
+
| 0.11.0 | v0.10.0 | Deployment |
|
|
276
|
+
| 0.12.0 | v0.11.0 | Payments |
|
|
277
|
+
| 0.13.0 | v0.12.0 | Background jobs |
|
|
278
|
+
| 0.14.0 | v0.13.0 | Observability |
|
|
279
|
+
| 0.15.0 | v0.13.1 | `status` and `doctor`, several modules in one change, conflict and upgrade summaries, macOS CI |
|
|
280
|
+
| next | | Show the Starter's version of a conflicted file next to yours |
|
|
281
|
+
|
|
282
|
+
## Community
|
|
283
|
+
|
|
284
|
+
- **[Issues](https://github.com/Clubedge/create-clubedge-app/issues)** for problems creating, changing, or upgrading a project.
|
|
285
|
+
- **[Clubedge Starter issues](https://github.com/Clubedge/clubedge-starter/issues)** for problems in the generated application itself.
|
|
286
|
+
- **[Pull requests](https://github.com/Clubedge/create-clubedge-app/pulls)** are welcome; start with [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
287
|
+
- **Security problems** go through the private process in [SECURITY.md](SECURITY.md), not public issues.
|
|
288
|
+
|
|
289
|
+
Everyone taking part is expected to follow the [code of conduct](CODE_OF_CONDUCT.md).
|
|
227
290
|
|
|
228
291
|
## License
|
|
229
292
|
|
package/dist/cli/args.js
CHANGED
|
@@ -12,6 +12,7 @@ const OPTIONS = {
|
|
|
12
12
|
yes: { type: "boolean", short: "y", default: false },
|
|
13
13
|
"dry-run": { type: "boolean", default: false },
|
|
14
14
|
force: { type: "boolean", default: false },
|
|
15
|
+
services: { type: "boolean", default: true },
|
|
15
16
|
help: { type: "boolean", short: "h", default: false },
|
|
16
17
|
version: { type: "boolean", short: "v", default: false },
|
|
17
18
|
};
|
|
@@ -78,9 +79,9 @@ export function parseCliArgs(argv) {
|
|
|
78
79
|
throw new UsageError("Only one project directory can be provided.");
|
|
79
80
|
}
|
|
80
81
|
if (command.name !== "create" && (values.framework !== undefined || Object.keys(modules).length)) {
|
|
81
|
-
throw new UsageError("--framework and module flags only apply when creating a project; use add or remove to change
|
|
82
|
+
throw new UsageError("--framework and module flags only apply when creating a project; use add or remove to change modules.");
|
|
82
83
|
}
|
|
83
|
-
if (
|
|
84
|
+
if (command.name !== "create" && command.name !== "upgrade" && values.ref !== undefined) {
|
|
84
85
|
throw new UsageError("--ref only applies when creating or upgrading a project.");
|
|
85
86
|
}
|
|
86
87
|
if (values.framework !== undefined && !values.framework.trim()) {
|
|
@@ -104,25 +105,42 @@ export function parseCliArgs(argv) {
|
|
|
104
105
|
yes: values.yes,
|
|
105
106
|
dryRun: values["dry-run"],
|
|
106
107
|
force: values.force,
|
|
108
|
+
services: values.services,
|
|
107
109
|
help: values.help,
|
|
108
110
|
version: values.version,
|
|
109
111
|
};
|
|
110
112
|
}
|
|
113
|
+
function assertDistinct(modules) {
|
|
114
|
+
const repeated = modules.find((module, index) => modules.indexOf(module) !== index);
|
|
115
|
+
if (repeated)
|
|
116
|
+
throw new UsageError(`The module "${repeated}" is named more than once.`);
|
|
117
|
+
}
|
|
111
118
|
/**
|
|
112
|
-
* `add <module> <option
|
|
113
|
-
* else is the directory of a new project. Create a project
|
|
119
|
+
* `add <module> <option>...`, `remove <module>...`, and `upgrade` change an existing project, and `status`
|
|
120
|
+
* and `doctor` inspect one; anything else is the directory of a new project. Create a project
|
|
121
|
+
* literally named "add" with `./add`.
|
|
114
122
|
*/
|
|
115
123
|
function parseCommand(positionals) {
|
|
116
|
-
const [name,
|
|
124
|
+
const [name, ...rest] = positionals;
|
|
125
|
+
const module = rest[0];
|
|
117
126
|
if (name === "add") {
|
|
118
|
-
if (
|
|
119
|
-
throw new UsageError("Usage: add [module
|
|
120
|
-
|
|
127
|
+
if (rest.length > 1 && rest.length % 2 === 1) {
|
|
128
|
+
throw new UsageError("Usage: add [module option]..., for example: add cache redis, or add email resend payments stripe");
|
|
129
|
+
}
|
|
130
|
+
const changes = rest.length === 1
|
|
131
|
+
? [{ module: rest[0] }]
|
|
132
|
+
: Array.from({ length: rest.length / 2 }, (_, i) => ({ module: rest[2 * i], option: rest[2 * i + 1] }));
|
|
133
|
+
assertDistinct(changes.map((change) => change.module));
|
|
134
|
+
return { name, changes };
|
|
121
135
|
}
|
|
122
136
|
if (name === "remove") {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
137
|
+
assertDistinct(rest);
|
|
138
|
+
return { name, modules: rest };
|
|
139
|
+
}
|
|
140
|
+
if (name === "status" || name === "doctor") {
|
|
141
|
+
if (module !== undefined)
|
|
142
|
+
throw new UsageError(`Usage: ${name}, run inside a project.`);
|
|
143
|
+
return { name };
|
|
126
144
|
}
|
|
127
145
|
if (name === "upgrade") {
|
|
128
146
|
if (module !== undefined)
|
package/dist/cli/ui.js
CHANGED
|
@@ -86,17 +86,24 @@ This CLI release scaffolds Starter ${starterPin.starterRef} (commit ${starterPin
|
|
|
86
86
|
|
|
87
87
|
Usage:
|
|
88
88
|
pnpm dlx @clubedge/create-clubedge-app [project-directory] [options]
|
|
89
|
-
pnpm dlx @clubedge/create-clubedge-app add [module
|
|
90
|
-
pnpm dlx @clubedge/create-clubedge-app remove [module]
|
|
89
|
+
pnpm dlx @clubedge/create-clubedge-app add [module option]... (inside a project)
|
|
90
|
+
pnpm dlx @clubedge/create-clubedge-app remove [module]... (inside a project)
|
|
91
91
|
pnpm dlx @clubedge/create-clubedge-app upgrade [--ref <tag>] (inside a project)
|
|
92
|
+
pnpm dlx @clubedge/create-clubedge-app status (inside a project)
|
|
93
|
+
pnpm dlx @clubedge/create-clubedge-app doctor (inside a project)
|
|
92
94
|
|
|
93
|
-
Inside a project with the clubedge script, use pnpm clubedge add, remove,
|
|
94
|
-
upgrade. Without a module or option, add and remove ask for them.
|
|
95
|
+
Inside a project with the clubedge script, use pnpm clubedge add, remove,
|
|
96
|
+
upgrade, status, or doctor. Without a module or option, add and remove ask for them.
|
|
95
97
|
|
|
96
|
-
add and remove change
|
|
97
|
-
to a newer Starter (this CLI's release unless --ref
|
|
98
|
-
|
|
99
|
-
|
|
98
|
+
add and remove change modules of an existing project, several at once as one
|
|
99
|
+
change, and upgrade moves it to a newer Starter (this CLI's release unless --ref
|
|
100
|
+
is given) and lists the Starter releases it crosses. The change is merged into
|
|
101
|
+
your code; lines you changed that it also changes get conflict markers. Commit
|
|
102
|
+
first so you can review the result with git diff.
|
|
103
|
+
|
|
104
|
+
status shows the project's Starter release, modules, and Git state, and whether a
|
|
105
|
+
newer Starter is available. doctor checks Node.js, pnpm, the dependencies, the
|
|
106
|
+
lockfile, and the env file, then runs pnpm check:services; it changes nothing.
|
|
100
107
|
|
|
101
108
|
Options:
|
|
102
109
|
${selectionHelp(manifest)}
|
|
@@ -105,6 +112,7 @@ ${selectionHelp(manifest)}
|
|
|
105
112
|
--template-dir <path> Scaffold from a local Starter checkout (for Starter development)
|
|
106
113
|
--dry-run Show what would be created or changed without writing anything
|
|
107
114
|
--force add/remove: change a project with uncommitted changes or without Git
|
|
115
|
+
--no-services doctor: skip pnpm check:services
|
|
108
116
|
-y, --yes Accept defaults and never prompt (default directory: my-app)
|
|
109
117
|
--no-install Skip dependency installation
|
|
110
118
|
--no-git Skip Git repository initialization
|
|
@@ -119,8 +127,11 @@ Examples:
|
|
|
119
127
|
pnpm dlx @clubedge/create-clubedge-app my-app --ref main
|
|
120
128
|
pnpm dlx @clubedge/create-clubedge-app my-app --template-dir ../clubedge-starter
|
|
121
129
|
pnpm dlx @clubedge/create-clubedge-app add auth better-auth
|
|
130
|
+
pnpm dlx @clubedge/create-clubedge-app add email resend payments stripe
|
|
122
131
|
pnpm dlx @clubedge/create-clubedge-app remove storage --dry-run
|
|
123
132
|
pnpm dlx @clubedge/create-clubedge-app@latest upgrade
|
|
133
|
+
pnpm clubedge status
|
|
134
|
+
pnpm clubedge doctor --no-services
|
|
124
135
|
|
|
125
136
|
Learn more:
|
|
126
137
|
CLI ${cliUrl}
|
package/dist/core/env.js
CHANGED
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
const LINE = /^\s*([A-Za-z_][A-Za-z0-9_]*)\s*=(.*)$/;
|
|
5
5
|
const COMMENT = /^\s*#/;
|
|
6
6
|
const keyOf = (line) => LINE.exec(line)?.[1];
|
|
7
|
+
/** The variable names an env file sets, in order. */
|
|
8
|
+
export function envKeys(text) {
|
|
9
|
+
return text.split(/\r?\n/).flatMap((line) => keyOf(line) ?? []);
|
|
10
|
+
}
|
|
7
11
|
const valueOf = (line) => LINE.exec(line)[2].replace(/\s+#.*$/, "").trim();
|
|
8
12
|
const find = (lines, key) => lines.findIndex((line) => keyOf(line) === key);
|
|
9
13
|
function values(lines) {
|