create-momentum-app 0.1.7 → 0.1.8

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/index.cjs CHANGED
@@ -29,6 +29,7 @@ var import_picocolors2 = __toESM(require("picocolors"));
29
29
  // apps/create-momentum-app/src/create-project.ts
30
30
  var import_node_path = __toESM(require("node:path"));
31
31
  var import_node_child_process = require("node:child_process");
32
+ var import_promises = require("node:timers/promises");
32
33
  var import_fs_extra = __toESM(require("fs-extra"));
33
34
  var import_picocolors = __toESM(require("picocolors"));
34
35
  var TEMPLATE_EXT = ".tmpl";
@@ -66,8 +67,95 @@ function copyTemplateDir(srcDir, destDir, vars) {
66
67
  }
67
68
  }
68
69
  }
70
+ function isDockerInstalled() {
71
+ try {
72
+ (0, import_node_child_process.execFileSync)("docker", ["--version"], { stdio: "pipe", timeout: 5e3, shell: true });
73
+ return true;
74
+ } catch {
75
+ return false;
76
+ }
77
+ }
78
+ function isDockerRunning() {
79
+ try {
80
+ (0, import_node_child_process.execFileSync)("docker", ["info"], { stdio: "pipe", timeout: 5e3, shell: true });
81
+ return true;
82
+ } catch {
83
+ return false;
84
+ }
85
+ }
86
+ function displayDockerInstallInstructions() {
87
+ console.log(import_picocolors.default.yellow("\n\u26A0\uFE0F Docker is not installed."));
88
+ console.log();
89
+ console.log("To use Docker for PostgreSQL, please install Docker:");
90
+ console.log();
91
+ const platform = process.platform;
92
+ if (platform === "darwin") {
93
+ console.log(
94
+ " macOS: Download Docker Desktop from https://www.docker.com/products/docker-desktop/"
95
+ );
96
+ } else if (platform === "linux") {
97
+ console.log(" Linux: Run the following command:");
98
+ console.log(import_picocolors.default.dim(" curl -fsSL https://get.docker.com | sh"));
99
+ console.log();
100
+ console.log(" Or install via your package manager:");
101
+ console.log(import_picocolors.default.dim(" sudo apt-get install docker.io docker-compose-plugin # Ubuntu/Debian"));
102
+ console.log(import_picocolors.default.dim(" sudo dnf install docker docker-compose-plugin # Fedora/RHEL"));
103
+ } else if (platform === "win32") {
104
+ console.log(
105
+ " Windows: Download Docker Desktop from https://www.docker.com/products/docker-desktop/"
106
+ );
107
+ console.log(" Note: Requires WSL2. See https://docs.docker.com/desktop/windows/install/");
108
+ } else {
109
+ console.log(" Visit https://docs.docker.com/get-docker/");
110
+ }
111
+ console.log();
112
+ console.log(
113
+ "You can still use an external PostgreSQL instance by updating the DATABASE_URL in .env"
114
+ );
115
+ console.log();
116
+ }
117
+ function startPostgresContainer(projectDir) {
118
+ try {
119
+ console.log(import_picocolors.default.dim("Starting PostgreSQL container..."));
120
+ (0, import_node_child_process.execFileSync)("docker", ["compose", "up", "-d"], {
121
+ cwd: projectDir,
122
+ stdio: "inherit",
123
+ shell: true
124
+ });
125
+ } catch (error) {
126
+ throw new Error(`Failed to start Docker container: ${error}`);
127
+ }
128
+ }
129
+ function waitForPostgres(projectDir, timeout = 3e4) {
130
+ return new Promise((resolve) => {
131
+ const startTime = Date.now();
132
+ const interval = 1e3;
133
+ const checkHealth = async () => {
134
+ while (Date.now() - startTime <= timeout) {
135
+ try {
136
+ (0, import_node_child_process.execFileSync)(
137
+ "docker",
138
+ ["compose", "exec", "-T", "postgres", "pg_isready", "-U", "postgres"],
139
+ {
140
+ cwd: projectDir,
141
+ stdio: "pipe",
142
+ timeout: 5e3,
143
+ shell: true
144
+ }
145
+ );
146
+ resolve(true);
147
+ return;
148
+ } catch {
149
+ await (0, import_promises.setTimeout)(interval);
150
+ }
151
+ }
152
+ resolve(false);
153
+ };
154
+ void checkHealth();
155
+ });
156
+ }
69
157
  async function createProject(options) {
70
- const { projectName, flavor, database, install, registry } = options;
158
+ const { projectName, flavor, database, install, docker, registry } = options;
71
159
  const projectDir = import_node_path.default.resolve(process.cwd(), projectName);
72
160
  if (import_fs_extra.default.existsSync(projectDir)) {
73
161
  console.error(import_picocolors.default.red(`
@@ -96,7 +184,42 @@ const pool = (dbAdapter as PostgresAdapterWithRaw).getPool();` : "",
96
184
  dbDevPackage: database === "postgres" ? "" : '"@types/better-sqlite3": "^7.6.13",',
97
185
  envDbVar: database === "postgres" ? "DATABASE_URL=postgresql://postgres:postgres@localhost:5432/momentum" : "DATABASE_PATH=./data/momentum.db",
98
186
  defaultPort: "4200",
99
- externalDependencies: database === "postgres" ? '"pg", "pg-native"' : '"better-sqlite3"'
187
+ externalDependencies: database === "postgres" ? '"pg", "pg-native"' : '"better-sqlite3"',
188
+ prerequisitesDocker: database === "postgres" ? `- **Docker** (for PostgreSQL database)
189
+ - [macOS](https://www.docker.com/products/docker-desktop/)
190
+ - [Linux](https://docs.docker.com/engine/install/)
191
+ - [Windows](https://docs.docker.com/desktop/windows/install/) (requires WSL2)` : "",
192
+ databaseSection: database === "postgres" ? `### PostgreSQL
193
+
194
+ This project uses PostgreSQL via Docker. The database is configured in \`docker-compose.yml\`.
195
+
196
+ **Connection Details:**
197
+ - Host: \`localhost\`
198
+ - Port: \`5432\`
199
+ - Database: \`momentum\`
200
+ - Username: \`postgres\`
201
+ - Password: \`postgres\`
202
+
203
+ **Docker Commands:**
204
+
205
+ \`\`\`bash
206
+ # Start database
207
+ docker compose up -d
208
+
209
+ # Stop database
210
+ docker compose down
211
+
212
+ # Stop and remove data
213
+ docker compose down -v
214
+
215
+ # View logs
216
+ docker compose logs -f postgres
217
+ \`\`\`
218
+
219
+ You can also use an external PostgreSQL instance by updating \`DATABASE_URL\` in \`.env\`.` : `### SQLite
220
+
221
+ This project uses SQLite with the database file at \`./data/momentum.db\`.
222
+ The database is automatically created on first run - no setup required.`
100
223
  };
101
224
  console.log();
102
225
  console.log(import_picocolors.default.cyan(`Creating ${import_picocolors.default.bold(projectName)} with ${flavor} + ${database}...`));
@@ -104,6 +227,51 @@ const pool = (dbAdapter as PostgresAdapterWithRaw).getPool();` : "",
104
227
  import_fs_extra.default.ensureDirSync(projectDir);
105
228
  copyTemplateDir(import_node_path.default.join(templatesDir, "shared"), projectDir, vars);
106
229
  copyTemplateDir(import_node_path.default.join(templatesDir, flavor), projectDir, vars);
230
+ const envExample = import_node_path.default.join(projectDir, ".env.example");
231
+ const envFile = import_node_path.default.join(projectDir, ".env");
232
+ import_fs_extra.default.copyFileSync(envExample, envFile);
233
+ console.log(import_picocolors.default.dim("Created .env file"));
234
+ console.log();
235
+ if (database !== "postgres" || !docker) {
236
+ const dockerComposePath = import_node_path.default.join(projectDir, "docker-compose.yml");
237
+ if (import_fs_extra.default.existsSync(dockerComposePath)) {
238
+ import_fs_extra.default.removeSync(dockerComposePath);
239
+ }
240
+ }
241
+ let dockerSetupSuccess = false;
242
+ if (database === "postgres" && docker) {
243
+ if (!isDockerInstalled()) {
244
+ displayDockerInstallInstructions();
245
+ } else if (!isDockerRunning()) {
246
+ console.log(import_picocolors.default.yellow("\n\u26A0\uFE0F Docker is installed but not running."));
247
+ console.log();
248
+ console.log("Please start Docker Desktop or run:");
249
+ console.log(import_picocolors.default.dim(" sudo systemctl start docker"));
250
+ console.log();
251
+ console.log("Then run:");
252
+ console.log(import_picocolors.default.dim(` cd ${projectName} && docker compose up -d`));
253
+ console.log();
254
+ } else {
255
+ try {
256
+ startPostgresContainer(projectDir);
257
+ const ready = await waitForPostgres(projectDir);
258
+ if (ready) {
259
+ console.log(import_picocolors.default.green("\u2713 PostgreSQL ready at localhost:5432"));
260
+ console.log();
261
+ dockerSetupSuccess = true;
262
+ } else {
263
+ console.log(import_picocolors.default.yellow("\u26A0\uFE0F PostgreSQL container started but not ready yet."));
264
+ console.log(import_picocolors.default.dim(" Check status: docker compose logs -f"));
265
+ console.log();
266
+ }
267
+ } catch (error) {
268
+ console.log(import_picocolors.default.yellow(`
269
+ \u26A0\uFE0F Failed to start PostgreSQL: ${error}`));
270
+ console.log(import_picocolors.default.dim(" Try manually: cd " + projectName + " && docker compose up -d"));
271
+ console.log();
272
+ }
273
+ }
274
+ }
107
275
  if (install) {
108
276
  console.log(import_picocolors.default.dim("Installing dependencies..."));
109
277
  const args = ["install"];
@@ -112,7 +280,8 @@ const pool = (dbAdapter as PostgresAdapterWithRaw).getPool();` : "",
112
280
  }
113
281
  (0, import_node_child_process.execFileSync)("npm", args, {
114
282
  cwd: projectDir,
115
- stdio: "inherit"
283
+ stdio: "inherit",
284
+ shell: true
116
285
  });
117
286
  console.log();
118
287
  }
@@ -124,6 +293,9 @@ const pool = (dbAdapter as PostgresAdapterWithRaw).getPool();` : "",
124
293
  if (!install) {
125
294
  console.log(import_picocolors.default.dim(" npm install"));
126
295
  }
296
+ if (database === "postgres" && docker && !dockerSetupSuccess) {
297
+ console.log(import_picocolors.default.dim(" docker compose up -d"));
298
+ }
127
299
  console.log(import_picocolors.default.dim(" npm run dev"));
128
300
  console.log();
129
301
  console.log(import_picocolors.default.dim(" Open http://localhost:" + vars.defaultPort + "/admin"));
@@ -150,6 +322,8 @@ function parseArgs(argv) {
150
322
  }
151
323
  } else if (arg === "--no-install") {
152
324
  opts.install = false;
325
+ } else if (arg === "--docker") {
326
+ opts.docker = true;
153
327
  } else if (arg === "--registry" && args[i + 1]) {
154
328
  opts.registry = args[++i];
155
329
  } else if (!arg.startsWith("-") && !opts.projectName) {
@@ -199,6 +373,12 @@ async function runCLI() {
199
373
  name: "install",
200
374
  message: "Install dependencies?",
201
375
  initial: true
376
+ },
377
+ {
378
+ type: cliArgs.docker !== void 0 || cliArgs.database !== "postgres" ? null : "confirm",
379
+ name: "docker",
380
+ message: "Set up PostgreSQL with Docker?",
381
+ initial: true
202
382
  }
203
383
  ],
204
384
  {
@@ -208,11 +388,13 @@ async function runCLI() {
208
388
  }
209
389
  }
210
390
  );
391
+ const database = cliArgs.database ?? response.database;
211
392
  const options = {
212
393
  projectName: cliArgs.projectName ?? response.projectName,
213
394
  flavor: cliArgs.flavor ?? response.flavor,
214
- database: cliArgs.database ?? response.database,
395
+ database,
215
396
  install: cliArgs.install ?? response.install ?? true,
397
+ docker: database === "postgres" ? cliArgs.docker ?? response.docker ?? false : false,
216
398
  registry: cliArgs.registry
217
399
  };
218
400
  await createProject(options);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-momentum-app",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "Create a new Momentum CMS application",
5
5
  "license": "MIT",
6
6
  "author": "Momentum CMS Contributors",
@@ -2,12 +2,18 @@
2
2
 
3
3
  A [Momentum CMS](https://github.com/momentum-cms/momentum-cms) application.
4
4
 
5
+ ## Prerequisites
6
+
7
+ - **Node.js** 20 or higher
8
+ {{prerequisitesDocker}}
9
+
10
+ ## Database
11
+
12
+ {{databaseSection}}
13
+
5
14
  ## Getting Started
6
15
 
7
16
  ```bash
8
- # Copy environment variables
9
- cp .env.example .env
10
-
11
17
  # Start the dev server
12
18
  npm run dev
13
19
  ```
@@ -0,0 +1,26 @@
1
+ # Docker Compose configuration for {{projectName}}
2
+ # This file sets up a PostgreSQL database for local development
3
+ # For production, consider using managed database services
4
+
5
+ services:
6
+ postgres:
7
+ image: postgres:16-alpine
8
+ container_name: {{projectName}}-postgres
9
+ restart: unless-stopped
10
+ ports:
11
+ - "5432:5432"
12
+ environment:
13
+ POSTGRES_USER: postgres
14
+ POSTGRES_PASSWORD: postgres
15
+ POSTGRES_DB: momentum
16
+ volumes:
17
+ - {{projectName}}_postgres_data:/var/lib/postgresql/data
18
+ healthcheck:
19
+ test: ["CMD-SHELL", "pg_isready -U postgres"]
20
+ interval: 5s
21
+ timeout: 5s
22
+ retries: 5
23
+
24
+ volumes:
25
+ {{projectName}}_postgres_data:
26
+ driver: local