create-momentum-app 0.1.6 → 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,10 +293,15 @@ 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"));
130
302
  console.log();
303
+ console.log(import_picocolors.default.dim(" Docs: https://github.com/DonaldMurillo/momentum-cms#readme"));
304
+ console.log();
131
305
  }
132
306
 
133
307
  // apps/create-momentum-app/src/cli.ts
@@ -148,6 +322,8 @@ function parseArgs(argv) {
148
322
  }
149
323
  } else if (arg === "--no-install") {
150
324
  opts.install = false;
325
+ } else if (arg === "--docker") {
326
+ opts.docker = true;
151
327
  } else if (arg === "--registry" && args[i + 1]) {
152
328
  opts.registry = args[++i];
153
329
  } else if (!arg.startsWith("-") && !opts.projectName) {
@@ -197,6 +373,12 @@ async function runCLI() {
197
373
  name: "install",
198
374
  message: "Install dependencies?",
199
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
200
382
  }
201
383
  ],
202
384
  {
@@ -206,11 +388,13 @@ async function runCLI() {
206
388
  }
207
389
  }
208
390
  );
391
+ const database = cliArgs.database ?? response.database;
209
392
  const options = {
210
393
  projectName: cliArgs.projectName ?? response.projectName,
211
394
  flavor: cliArgs.flavor ?? response.flavor,
212
- database: cliArgs.database ?? response.database,
395
+ database,
213
396
  install: cliArgs.install ?? response.install ?? true,
397
+ docker: database === "postgres" ? cliArgs.docker ?? response.docker ?? false : false,
214
398
  registry: cliArgs.registry
215
399
  };
216
400
  await createProject(options);
package/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "create-momentum-app",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "description": "Create a new Momentum CMS application",
5
5
  "license": "MIT",
6
6
  "author": "Momentum CMS Contributors",
7
7
  "repository": {
8
8
  "type": "git",
9
- "url": "https://github.com/momentum-cms/momentum-cms.git",
9
+ "url": "https://github.com/DonaldMurillo/momentum-cms.git",
10
10
  "directory": "apps/create-momentum-app"
11
11
  },
12
- "homepage": "https://github.com/momentum-cms/momentum-cms#readme",
12
+ "homepage": "https://github.com/DonaldMurillo/momentum-cms#readme",
13
13
  "bugs": {
14
- "url": "https://github.com/momentum-cms/momentum-cms/issues"
14
+ "url": "https://github.com/DonaldMurillo/momentum-cms/issues"
15
15
  },
16
16
  "keywords": [
17
17
  "cms",
@@ -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