@clubedge/create-clubedge-app 0.8.0 → 0.9.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 +7 -0
- package/README.md +11 -10
- package/dist/cli/args.js +4 -6
- package/dist/cli/ui.js +5 -2
- package/dist/index.js +7 -1
- package/dist/modify.js +90 -13
- package/package.json +3 -3
- package/template/README.md +8 -0
- package/template/apps/start/package.json +1 -1
- package/template/apps/web/package.json +1 -1
- package/template/package.json +2 -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/local-db/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 +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `create-clubedge-app` are documented here.
|
|
4
4
|
|
|
5
|
+
## 0.9.0
|
|
6
|
+
|
|
7
|
+
- Default to Starter `v0.8.0`, whose projects have a `clubedge` script: `pnpm clubedge add`, `remove`, and `upgrade`.
|
|
8
|
+
- `add` and `remove` ask for the module and option when they are not given, offering only options the project can use. Without a terminal, missing arguments remain an error.
|
|
9
|
+
- Messages suggest `pnpm clubedge ...` in projects with the `clubedge` script, and the outro after creating a project mentions it.
|
|
10
|
+
- Test the CLI on Windows in CI: its checks and tests, and generated projects with a module change.
|
|
11
|
+
|
|
5
12
|
## 0.8.0
|
|
6
13
|
|
|
7
14
|
- Add `add <module> <option>` and `remove <module>` to change the modules of an existing project. The CLI renders the project's recorded Starter commit with the current and the new selection and merges the difference into the project. Files you never changed are updated, your edits are kept, and lines both sides changed get conflict markers. The local env file keeps your values: only generated values follow the new selection, and new variables are added. A Git repository without uncommitted changes is required unless `--force` is passed, so the result can be reviewed and undone.
|
package/README.md
CHANGED
|
@@ -12,27 +12,27 @@ The CLI downloads a tested Starter release, names the generated project, creates
|
|
|
12
12
|
Each CLI release is tested against one specific Starter release:
|
|
13
13
|
|
|
14
14
|
```text
|
|
15
|
-
create-clubedge-app v0.
|
|
15
|
+
create-clubedge-app v0.9.0
|
|
16
16
|
|
|
|
17
17
|
v
|
|
18
|
-
Clubedge Starter v0.
|
|
19
|
-
commit
|
|
18
|
+
Clubedge Starter v0.8.0
|
|
19
|
+
commit 0b77577a3fe77617c84e250d8b220169b72a297e
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
The current relationship is:
|
|
23
23
|
|
|
24
24
|
| CLI release | Default Starter release | Meaning |
|
|
25
25
|
| --- | --- | --- |
|
|
26
|
-
| `create-clubedge-app@0.
|
|
26
|
+
| `create-clubedge-app@0.9.0` | `clubedge-starter@v0.8.0` | The CLI's required, tested default |
|
|
27
27
|
|
|
28
28
|
This means the same CLI version always scaffolds the same Starter revision by default. The CLI does not silently follow Starter `main`.
|
|
29
29
|
|
|
30
|
-
The `v0.
|
|
31
|
-
`
|
|
30
|
+
The `v0.8.0` tag is expected to resolve to commit
|
|
31
|
+
`0b77577a3fe77617c84e250d8b220169b72a297e`. The CLI verifies this before
|
|
32
32
|
scaffolding with the default reference and fails rather than silently using a
|
|
33
33
|
moved tag.
|
|
34
34
|
|
|
35
|
-
When the Starter changes, its maintainers first publish a new versioned release, such as `v0.
|
|
35
|
+
When the Starter changes, its maintainers first publish a new versioned release, such as `v0.8.0`. 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.
|
|
36
36
|
|
|
37
37
|
## Requirements
|
|
38
38
|
|
|
@@ -136,7 +136,7 @@ pnpm dlx @clubedge/create-clubedge-app my-app --yes --no-git --framework tanstac
|
|
|
136
136
|
pnpm dlx @clubedge/create-clubedge-app my-app --ref main
|
|
137
137
|
|
|
138
138
|
# Reproduce a specific Starter release or commit
|
|
139
|
-
pnpm dlx @clubedge/create-clubedge-app my-app --ref v0.
|
|
139
|
+
pnpm dlx @clubedge/create-clubedge-app my-app --ref v0.8.0
|
|
140
140
|
pnpm dlx @clubedge/create-clubedge-app my-app --ref <commit-sha>
|
|
141
141
|
|
|
142
142
|
# Test local Starter changes before releasing them
|
|
@@ -145,9 +145,10 @@ pnpm dlx @clubedge/create-clubedge-app my-app --template-dir ../clubedge-starter
|
|
|
145
145
|
|
|
146
146
|
## Change an existing project
|
|
147
147
|
|
|
148
|
-
Inside a project created by the CLI, `add` and `remove` change one module at a time, and `upgrade` moves the project to a newer Starter release:
|
|
148
|
+
Inside a project created by the CLI, `add` and `remove` change one module at a time, 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:
|
|
149
149
|
|
|
150
150
|
```sh
|
|
151
|
+
pnpm clubedge add # choose a module and option from a list
|
|
151
152
|
pnpm dlx @clubedge/create-clubedge-app add cache redis # or switch: add auth better-auth
|
|
152
153
|
pnpm dlx @clubedge/create-clubedge-app remove storage
|
|
153
154
|
pnpm dlx @clubedge/create-clubedge-app add infra local --dry-run
|
|
@@ -203,7 +204,7 @@ CI packs the CLI with `npm pack`, scaffolds a clean project from the packed tarb
|
|
|
203
204
|
1. Make and validate changes in `clubedge-starter`.
|
|
204
205
|
2. Run lint, typecheck, unit tests, browser tests, and production build.
|
|
205
206
|
3. Update the Starter package versions.
|
|
206
|
-
4. Commit `main`, create a release tag such as `v0.
|
|
207
|
+
4. Commit `main`, create a release tag such as `v0.8.0`, and publish the Starter release.
|
|
207
208
|
|
|
208
209
|
### CLI maintainers
|
|
209
210
|
|
package/dist/cli/args.js
CHANGED
|
@@ -86,15 +86,13 @@ export function parseCliArgs(argv) {
|
|
|
86
86
|
function parseCommand(positionals) {
|
|
87
87
|
const [name, module, option, ...extra] = positionals;
|
|
88
88
|
if (name === "add") {
|
|
89
|
-
if (
|
|
90
|
-
throw new UsageError("Usage: add
|
|
91
|
-
}
|
|
89
|
+
if (extra.length)
|
|
90
|
+
throw new UsageError("Usage: add [module] [option], for example: add cache redis");
|
|
92
91
|
return { name, module, option };
|
|
93
92
|
}
|
|
94
93
|
if (name === "remove") {
|
|
95
|
-
if (
|
|
96
|
-
throw new UsageError("Usage: remove
|
|
97
|
-
}
|
|
94
|
+
if (option !== undefined)
|
|
95
|
+
throw new UsageError("Usage: remove [module], for example: remove storage");
|
|
98
96
|
return { name, module };
|
|
99
97
|
}
|
|
100
98
|
if (name === "upgrade") {
|
package/dist/cli/ui.js
CHANGED
|
@@ -61,10 +61,13 @@ This CLI release scaffolds Starter ${starterPin.starterRef} (commit ${starterPin
|
|
|
61
61
|
|
|
62
62
|
Usage:
|
|
63
63
|
pnpm dlx @clubedge/create-clubedge-app [project-directory] [options]
|
|
64
|
-
pnpm dlx @clubedge/create-clubedge-app add
|
|
65
|
-
pnpm dlx @clubedge/create-clubedge-app remove
|
|
64
|
+
pnpm dlx @clubedge/create-clubedge-app add [module] [option] (inside a project)
|
|
65
|
+
pnpm dlx @clubedge/create-clubedge-app remove [module] (inside a project)
|
|
66
66
|
pnpm dlx @clubedge/create-clubedge-app upgrade [--ref <tag>] (inside a project)
|
|
67
67
|
|
|
68
|
+
Inside a project with the clubedge script, use pnpm clubedge add, remove, or
|
|
69
|
+
upgrade. Without a module or option, add and remove ask for them.
|
|
70
|
+
|
|
68
71
|
add and remove change one module of an existing project, and upgrade moves it
|
|
69
72
|
to a newer Starter (this CLI's release unless --ref is given). The change is
|
|
70
73
|
merged into your code; lines you changed that it also changes get conflict
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { cancel, confirm, intro, isCancel, log, outro, select, spinner, text } from "@clack/prompts";
|
|
2
|
-
import {
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { join, relative, resolve } from "node:path";
|
|
3
4
|
import process from "node:process";
|
|
4
5
|
import { parseCliArgs, UsageError } from "./cli/args.js";
|
|
5
6
|
import { dim, helpText, showBanner } from "./cli/ui.js";
|
|
@@ -183,8 +184,13 @@ async function createProject(args) {
|
|
|
183
184
|
}
|
|
184
185
|
}
|
|
185
186
|
const directory = relative(process.cwd(), targetDirectory) || ".";
|
|
187
|
+
const scripts = JSON.parse(await readFile(join(targetDirectory, "package.json"), "utf8")).scripts ?? {};
|
|
188
|
+
const later = scripts.clubedge
|
|
189
|
+
? `Change modules later with \`pnpm clubedge add\` or \`pnpm clubedge remove\`, and get Starter updates with \`pnpm clubedge upgrade\`.\n\n`
|
|
190
|
+
: "";
|
|
186
191
|
outro(`Next steps:\n cd ${directory}\n ${pnpmCommand} dev\n\n` +
|
|
187
192
|
`See SETUP.md for database and provider configuration.\n\n` +
|
|
193
|
+
later +
|
|
188
194
|
`${dim("Docs")} ${cliUrl}\n${dim("Clubedge")} ${siteUrl}`);
|
|
189
195
|
}
|
|
190
196
|
export async function main(argv = process.argv.slice(2)) {
|
package/dist/modify.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
// `add`, `remove`, and `upgrade` change an existing project. The project's recorded Starter
|
|
2
2
|
// commit and modules (base) and the new state (target: other modules, or a newer Starter) are
|
|
3
3
|
// rendered in memory, and the difference is merged into the project (see core/update.ts).
|
|
4
|
-
import { confirm, isCancel, log, outro, spinner } from "@clack/prompts";
|
|
4
|
+
import { confirm, isCancel, log, outro, select, spinner } from "@clack/prompts";
|
|
5
|
+
import { readFile } from "node:fs/promises";
|
|
6
|
+
import { join } from "node:path";
|
|
5
7
|
import process from "node:process";
|
|
6
8
|
import { UsageError } from "./cli/args.js";
|
|
7
9
|
import { dim } from "./cli/ui.js";
|
|
@@ -13,6 +15,18 @@ import { applyUpdate, planUpdate } from "./core/update.js";
|
|
|
13
15
|
import { cliVersion, starterPin } from "./package-info.js";
|
|
14
16
|
import { installDependencies, resolvePnpm } from "./steps/install.js";
|
|
15
17
|
import { commandSucceeds, runCapture } from "./utils/process.js";
|
|
18
|
+
/** How to run the CLI in this project: its `clubedge` script when it has one. */
|
|
19
|
+
async function cliCommand(project) {
|
|
20
|
+
try {
|
|
21
|
+
const manifest = JSON.parse(await readFile(join(project.root, "package.json"), "utf8"));
|
|
22
|
+
if (manifest.scripts?.clubedge)
|
|
23
|
+
return "pnpm clubedge";
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
// Fall back to the full command below.
|
|
27
|
+
}
|
|
28
|
+
return "pnpm dlx @clubedge/create-clubedge-app";
|
|
29
|
+
}
|
|
16
30
|
/** The Starter revision the project was generated from. */
|
|
17
31
|
async function projectSource(project, templateDir) {
|
|
18
32
|
if (templateDir)
|
|
@@ -62,8 +76,66 @@ async function assertSafeToChange(project, args, interactive) {
|
|
|
62
76
|
if (isCancel(proceed) || !proceed)
|
|
63
77
|
throw new UsageError("Cancelled; nothing was changed.");
|
|
64
78
|
}
|
|
79
|
+
/** Whether an option's requirements hold for the project's other modules. */
|
|
80
|
+
function available(manifest, project, moduleId, optionId) {
|
|
81
|
+
const option = manifest.modules[moduleId].options[optionId];
|
|
82
|
+
return Object.entries(option.requires).every(([other, allowed]) => allowed.includes(project.modules[other] ?? ""));
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Asks for whatever add or remove was not given: the module, then the option. Without a
|
|
86
|
+
* terminal, the missing arguments are an error. Resolves null when a prompt is cancelled.
|
|
87
|
+
*/
|
|
88
|
+
export async function completeCommand(manifest, project, command, interactive) {
|
|
89
|
+
if (command.name === "add" && command.module && command.option) {
|
|
90
|
+
return { name: "add", module: command.module, option: command.option };
|
|
91
|
+
}
|
|
92
|
+
if (command.name === "remove" && command.module)
|
|
93
|
+
return { name: "remove", module: command.module };
|
|
94
|
+
if (!interactive) {
|
|
95
|
+
throw new UsageError(command.name === "add"
|
|
96
|
+
? "Usage: add <module> <option>, for example: add cache redis. Run it in a terminal to choose from a list."
|
|
97
|
+
: "Usage: remove <module>, for example: remove storage. Run it in a terminal to choose from a list.");
|
|
98
|
+
}
|
|
99
|
+
let moduleId = command.module;
|
|
100
|
+
if (!moduleId) {
|
|
101
|
+
const choices = Object.entries(manifest.modules).filter(([id, module]) => command.name === "add" ? true : Boolean(module.options.none) && project.modules[id] !== "none");
|
|
102
|
+
if (!choices.length)
|
|
103
|
+
throw new UsageError("No module can be removed: every removable module is already none.");
|
|
104
|
+
const value = await select({
|
|
105
|
+
message: command.name === "add" ? "Which module do you want to add or switch?" : "Which module do you want to remove?",
|
|
106
|
+
options: choices.map(([id, module]) => ({
|
|
107
|
+
value: id,
|
|
108
|
+
label: module.name,
|
|
109
|
+
hint: `now: ${module.options[project.modules[id] ?? ""]?.name ?? project.modules[id] ?? "not set"}`,
|
|
110
|
+
})),
|
|
111
|
+
});
|
|
112
|
+
if (isCancel(value))
|
|
113
|
+
return null;
|
|
114
|
+
moduleId = value;
|
|
115
|
+
}
|
|
116
|
+
if (command.name === "remove")
|
|
117
|
+
return { name: "remove", module: moduleId };
|
|
118
|
+
const module = manifest.modules[moduleId];
|
|
119
|
+
if (!module) {
|
|
120
|
+
throw new UsageError(`Unknown module "${moduleId}". Choose one of: ${Object.keys(manifest.modules).join(", ")}.`);
|
|
121
|
+
}
|
|
122
|
+
const options = Object.keys(module.options).filter((id) => id !== project.modules[moduleId] && available(manifest, project, moduleId, id));
|
|
123
|
+
if (!options.length)
|
|
124
|
+
throw new UsageError(`${module.name} has no other option this project can use.`);
|
|
125
|
+
const option = await select({
|
|
126
|
+
message: `${module.name}: which option?`,
|
|
127
|
+
options: options.map((id) => ({
|
|
128
|
+
value: id,
|
|
129
|
+
label: module.options[id].name,
|
|
130
|
+
...(id === module.default ? { hint: "default" } : {}),
|
|
131
|
+
})),
|
|
132
|
+
});
|
|
133
|
+
if (isCancel(option))
|
|
134
|
+
return null;
|
|
135
|
+
return { name: "add", module: moduleId, option };
|
|
136
|
+
}
|
|
65
137
|
/** The selection after add or remove, validated against the Starter's manifest. */
|
|
66
|
-
function changedModules(manifest, project, command) {
|
|
138
|
+
function changedModules(manifest, project, command, cli) {
|
|
67
139
|
const module = manifest.modules[command.module];
|
|
68
140
|
if (!module) {
|
|
69
141
|
throw new UsageError(`Unknown module "${command.module}". Choose one of: ${Object.keys(manifest.modules).join(", ")}.`);
|
|
@@ -78,7 +150,7 @@ function changedModules(manifest, project, command) {
|
|
|
78
150
|
else {
|
|
79
151
|
if (!module.options.none) {
|
|
80
152
|
const others = Object.keys(module.options).filter((id) => id !== project.modules[command.module]);
|
|
81
|
-
throw new UsageError(`${module.name} cannot be removed. Switch it instead, for example: add ${command.module} ${others[0] ?? module.default}`);
|
|
153
|
+
throw new UsageError(`${module.name} cannot be removed. Switch it instead, for example: ${cli} add ${command.module} ${others[0] ?? module.default}`);
|
|
82
154
|
}
|
|
83
155
|
option = "none";
|
|
84
156
|
}
|
|
@@ -89,7 +161,7 @@ function changedModules(manifest, project, command) {
|
|
|
89
161
|
* The project's selection in a newer Starter. Modules the project predates get their "none"
|
|
90
162
|
* option where there is one, so an upgrade never adds a service on its own.
|
|
91
163
|
*/
|
|
92
|
-
export function upgradedModules(manifest, project) {
|
|
164
|
+
export function upgradedModules(manifest, project, cli = "pnpm clubedge") {
|
|
93
165
|
const requested = {};
|
|
94
166
|
const introduced = [];
|
|
95
167
|
for (const [id, module] of Object.entries(manifest.modules)) {
|
|
@@ -99,7 +171,7 @@ export function upgradedModules(manifest, project) {
|
|
|
99
171
|
introduced.push(id);
|
|
100
172
|
}
|
|
101
173
|
else if (!module.options[recorded]) {
|
|
102
|
-
throw new UsageError(`The new Starter no longer offers ${module.name} "${recorded}".
|
|
174
|
+
throw new UsageError(`The new Starter no longer offers ${module.name} "${recorded}". Switch to one of ${Object.keys(module.options).join(", ")} with ${cli} add ${id} <option> before upgrading.`);
|
|
103
175
|
}
|
|
104
176
|
else {
|
|
105
177
|
requested[id] = recorded;
|
|
@@ -154,11 +226,10 @@ function report(plan) {
|
|
|
154
226
|
}
|
|
155
227
|
}
|
|
156
228
|
/** Works out what the command changes; resolves null when the project is already there. */
|
|
157
|
-
async function planChange(project, command, base, target) {
|
|
158
|
-
const baseManifest = await readTemplateManifest(base.root);
|
|
229
|
+
async function planChange(project, command, base, baseManifest, target, cli) {
|
|
159
230
|
const baseSide = { source: asRecorded(base, project), manifest: baseManifest, modules: project.modules, cliVersion: project.cliVersion };
|
|
160
231
|
if (command.name !== "upgrade") {
|
|
161
|
-
const modules = changedModules(baseManifest, project, command);
|
|
232
|
+
const modules = changedModules(baseManifest, project, command, cli);
|
|
162
233
|
const changed = Object.keys(modules).filter((id) => modules[id] !== project.modules[id]);
|
|
163
234
|
if (!changed.length)
|
|
164
235
|
return null;
|
|
@@ -177,11 +248,11 @@ async function planChange(project, command, base, target) {
|
|
|
177
248
|
if (target.commit && target.commit === project.starterCommit)
|
|
178
249
|
return null;
|
|
179
250
|
const targetManifest = await readTemplateManifest(target.root);
|
|
180
|
-
const { modules, introduced, dropped } = upgradedModules(targetManifest, project);
|
|
251
|
+
const { modules, introduced, dropped } = upgradedModules(targetManifest, project, cli);
|
|
181
252
|
const notes = [
|
|
182
253
|
...introduced.map((id) => {
|
|
183
254
|
const module = targetManifest.modules[id];
|
|
184
|
-
return `Starter ${target.ref} adds ${module.name}; the project uses "${modules[id]}". Choose another option with: add ${id} <option>`;
|
|
255
|
+
return `Starter ${target.ref} adds ${module.name}; the project uses "${modules[id]}". Choose another option with: ${cli} add ${id} <option>`;
|
|
185
256
|
}),
|
|
186
257
|
...dropped.map((id) => `Starter ${target.ref} no longer has the ${id} module; its files are merged away like any other change.`),
|
|
187
258
|
];
|
|
@@ -214,14 +285,20 @@ export async function changeProject(args) {
|
|
|
214
285
|
const target = upgrading ? await upgradeSource(args) : null;
|
|
215
286
|
if (target)
|
|
216
287
|
sources.push(target);
|
|
217
|
-
const
|
|
288
|
+
const baseManifest = await readTemplateManifest(base.root);
|
|
289
|
+
progress.stop("Starter ready");
|
|
218
290
|
spinning = false;
|
|
291
|
+
const cli = await cliCommand(project);
|
|
292
|
+
const complete = command.name === "upgrade" ? command : await completeCommand(baseManifest, project, command, interactive);
|
|
293
|
+
if (!complete) {
|
|
294
|
+
outro("Cancelled; nothing was changed.");
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
const change = await planChange(project, complete, base, baseManifest, target, cli);
|
|
219
298
|
if (!change) {
|
|
220
|
-
progress.stop("Starter ready");
|
|
221
299
|
outro(upgrading ? `The project is already on Starter ${project.starterRef}.` : "The project already uses that selection; nothing to change.");
|
|
222
300
|
return;
|
|
223
301
|
}
|
|
224
|
-
progress.stop("Starter ready");
|
|
225
302
|
const plan = await planUpdate(project, change.base, change.target);
|
|
226
303
|
log.message(`${change.summary}\n\n${describe(plan) || "No file changes."}`);
|
|
227
304
|
if (args.dryRun) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clubedge/create-clubedge-app",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Create a Next.js or TanStack Start application from the Clubedge Starter reference implementation.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "pnpm@10.9.0",
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
},
|
|
23
23
|
"clubedge": {
|
|
24
24
|
"starterRepository": "Clubedge/clubedge-starter",
|
|
25
|
-
"starterRef": "v0.
|
|
26
|
-
"starterCommit": "
|
|
25
|
+
"starterRef": "v0.8.0",
|
|
26
|
+
"starterCommit": "0b77577a3fe77617c84e250d8b220169b72a297e"
|
|
27
27
|
},
|
|
28
28
|
"license": "Apache-2.0",
|
|
29
29
|
"repository": {
|
package/template/README.md
CHANGED
|
@@ -169,6 +169,14 @@ Local services:
|
|
|
169
169
|
- `pnpm infra:up`: run only the local database, for example for `pnpm check:services` or browser tests. <!-- clubedge:only infra=local -->
|
|
170
170
|
- `pnpm infra:reset`: delete the local database and files in `.data/` (stop `pnpm dev` first). <!-- clubedge:only infra=local -->
|
|
171
171
|
|
|
172
|
+
Change the project later:
|
|
173
|
+
|
|
174
|
+
- `pnpm clubedge add <module> <option>`: add a module or switch its option, for example `pnpm clubedge add auth better-auth` or `pnpm clubedge add infra local`. Run `pnpm clubedge add` without arguments to choose from a list.
|
|
175
|
+
- `pnpm clubedge remove <module>`: remove a module, for example `pnpm clubedge remove storage`.
|
|
176
|
+
- `pnpm clubedge upgrade`: move the project to the newest Starter release.
|
|
177
|
+
|
|
178
|
+
These commands merge the change into your code instead of overwriting it: files you never touched are updated, your edits are kept, and lines you both changed get conflict markers. Commit first, because they need a clean Git tree so that `git diff` shows the result. Add `--dry-run` to preview a change.
|
|
179
|
+
|
|
172
180
|
<!-- clubedge:if starter-repository -->
|
|
173
181
|
|
|
174
182
|
## Working on this repository
|
package/template/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clubedge-starter-v1",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"private": true,
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"packageManager": "pnpm@10.9.0",
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
"docker:build": "docker build -t clubedge-starter .",
|
|
30
30
|
"docker:start": "docker run --rm -p 3000:3000 --env-file apps/web/.env.local clubedge-starter",
|
|
31
31
|
"check:services": "pnpm --filter @clubedge/web check:services",
|
|
32
|
+
"clubedge": "pnpm dlx @clubedge/create-clubedge-app@latest",
|
|
32
33
|
"infra:up": "docker compose -f docker-compose.dev.yml up -d --wait",
|
|
33
34
|
"infra:down": "docker compose -f docker-compose.dev.yml down",
|
|
34
35
|
"infra:reset": "docker compose -f docker-compose.dev.yml down --volumes",
|
package/template.lock.json
CHANGED