modern-cms 1.1.3 → 1.1.4

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 CHANGED
@@ -25,11 +25,29 @@ A self-hosted, drag-and-drop website CMS: a Next.js (App Router) front end, an E
25
25
 
26
26
  ## Installation
27
27
 
28
+ **npx (no install — always runs the latest version):**
29
+
28
30
  ```bash
29
31
  npx modern-cms
30
32
  ```
31
33
 
32
- (No global install needed — `npx` fetches and runs the latest version each time. If you prefer a global install: `npm install -g modern-cms && modern-cms`.)
34
+ **npm (global install):**
35
+
36
+ ```bash
37
+ npm install -g modern-cms
38
+ modern-cms
39
+ ```
40
+
41
+ **yarn:**
42
+
43
+ ```bash
44
+ # Yarn Classic (v1)
45
+ yarn global add modern-cms
46
+ modern-cms
47
+
48
+ # Yarn Berry (v2+)
49
+ yarn dlx modern-cms
50
+ ```
33
51
 
34
52
  ### What the installer asks
35
53
 
@@ -66,6 +84,10 @@ npm run dev
66
84
 
67
85
  Then open the web app at the URL you chose (default `http://localhost:3000`) and log in at `/admin` with the admin email/password from the wizard.
68
86
 
87
+ > **Prefer yarn for the scaffolded project too?** `yarn install` works fine, and `dev`/`db:migrate`/`db:seed` all run correctly (they use `tsx`, which doesn't type-check). The one caveat: yarn's dependency hoisting can occasionally produce a duplicate `@types/express`, which shows up as spurious TypeScript errors only if you run `npm run build` or `tsc` directly — running `npm install` once resolves it.
88
+ >
89
+ > **Logged in with the wrong password?** The admin user is only created the *first* time `db:seed` runs — editing `.env` afterward doesn't retroactively change it. Run `npm run db:reset-admin && npm run db:seed` to delete and recreate it from the current `.env` values.
90
+
69
91
  ## Project layout
70
92
 
71
93
  The scaffolded project is an npm-workspaces monorepo:
package/bin/modern-cms.js CHANGED
@@ -18,11 +18,17 @@ import {
18
18
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
19
19
  const TEMPLATE_DIR = path.join(__dirname, "..", "template");
20
20
 
21
+ // npm's packlist strips any file literally named ".gitignore" out of the published
22
+ // tarball, so the template ships it as "gitignore" — restore the leading dot on scaffold.
23
+ function destName(name) {
24
+ return name === "gitignore" ? ".gitignore" : name;
25
+ }
26
+
21
27
  function copyDir(src, dest) {
22
28
  fs.mkdirSync(dest, { recursive: true });
23
29
  for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
24
30
  const srcPath = path.join(src, entry.name);
25
- const destPath = path.join(dest, entry.name);
31
+ const destPath = path.join(dest, destName(entry.name));
26
32
  if (entry.isDirectory()) copyDir(srcPath, destPath);
27
33
  else fs.copyFileSync(srcPath, destPath);
28
34
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "modern-cms",
3
- "version": "1.1.3",
3
+ "version": "1.1.4",
4
4
  "description": "Self-hosted, drag-and-drop website CMS (Next.js + Express + Prisma). Interactive installer scaffolds a full project with your choice of PostgreSQL/MySQL and AWS S3/Azure Blob/Cloudinary storage.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -12,14 +12,68 @@ Built as an npm-workspaces monorepo:
12
12
 
13
13
  ---
14
14
 
15
- ## Quick start
15
+ ## Installation
16
16
 
17
- ### Prerequisites
17
+ There are two ways to get a working project: install the published `modern-cms` package (fastest — an interactive wizard scaffolds everything and writes your `.env` files), or clone this repository directly (for contributing to pg-cms itself). Most people want the first one.
18
+
19
+ ### Option A — Install the `modern-cms` package (recommended)
20
+
21
+ Works with npx, npm, or yarn — pick whichever you already use.
22
+
23
+ **npx (no install — always runs the latest version):**
24
+
25
+ ```bash
26
+ npx modern-cms
27
+ ```
28
+
29
+ **npm (global install, then run anytime with just `modern-cms`):**
30
+
31
+ ```bash
32
+ npm install -g modern-cms
33
+ modern-cms
34
+ ```
35
+
36
+ **yarn:**
37
+
38
+ ```bash
39
+ # Yarn Classic (v1)
40
+ yarn global add modern-cms
41
+ modern-cms
42
+
43
+ # Yarn Berry (v2+) — no global install needed
44
+ yarn dlx modern-cms
45
+ ```
46
+
47
+ The wizard asks for your database (PostgreSQL or MySQL, with host/port/name/username/password), the web app port and API port, your file storage provider (AWS S3, Azure Blob Storage, or Cloudinary, with that provider's credentials), and an admin email/password — then scaffolds a full project and writes working `.env` files. It never runs `npm install`, touches your database, or starts anything by itself; it prints the exact next commands.
48
+
49
+ ```bash
50
+ cd <your-project-dir>
51
+
52
+ # npm (recommended — see the yarn note below):
53
+ npm install
54
+ npm run db:migrate # PostgreSQL
55
+ # MySQL installs use schema-push instead, since the bundled migration
56
+ # history is Postgres-specific SQL:
57
+ # npx prisma generate --schema apps/api/prisma/schema.prisma
58
+ # npx prisma db push --schema apps/api/prisma/schema.prisma
59
+ npm run db:seed
60
+ npm run dev
61
+ ```
62
+
63
+ > **Using yarn to install the scaffolded project itself?** `yarn install` works fine, and `npm run dev` / `db:migrate` / `db:seed` all run correctly under a yarn-installed `node_modules` (they invoke `tsx`, which doesn't type-check). The one thing to watch for: yarn's dependency hoisting can occasionally produce a duplicate `@types/express` in the tree, which shows up as spurious TypeScript errors *only* if you run `npm run build` or `tsc` directly. If that happens, running `npm install` once (even alongside your yarn workflow) resolves it — that's yarn's hoisting, not a bug in the project.
64
+
65
+ See [`packages/modern-cms/README.md`](packages/modern-cms/README.md) for the full prompt-by-prompt reference and configuration details.
66
+
67
+ ### Option B — Clone this repository
68
+
69
+ For working on pg-cms itself, not for building a site with it.
70
+
71
+ #### Prerequisites
18
72
 
19
73
  - Node.js 18+
20
74
  - Docker Desktop (for PostgreSQL + MinIO)
21
75
 
22
- ### 1. Start the databases
76
+ #### 1. Start the databases
23
77
 
24
78
  ```bash
25
79
  npm run docker:up
@@ -37,7 +91,7 @@ A one-shot init container creates the `pgcms-media` bucket automatically.
37
91
 
38
92
  > **Port conflicts:** if `docker compose up` fails with "port is already allocated", another container or service owns that port — run `docker ps` to find it, then either stop it or change the host-side port in `docker-compose.yml` **and** the matching URLs in `apps/api/.env`.
39
93
 
40
- ### 2. Environment files
94
+ #### 2. Environment files
41
95
 
42
96
  Two env files are used:
43
97
 
@@ -53,7 +107,7 @@ cp .env.example apps/api/.env # then trim to the API-relevant keys, or keep al
53
107
 
54
108
  **Important:** the password inside `DATABASE_URL` in `apps/api/.env` must match `POSTGRES_PASSWORD` in the root `.env`. Postgres sets its password the *first* time its data volume is created — changing `.env` later does not change the database password.
55
109
 
56
- ### 3. Install, migrate, seed
110
+ #### 3. Install, migrate, seed
57
111
 
58
112
  ```bash
59
113
  npm install
@@ -69,7 +123,7 @@ npx tsx prisma/seed-homepage.ts
69
123
  npx tsx prisma/seed-our-charities.ts
70
124
  ```
71
125
 
72
- ### 4. Run the dev servers
126
+ #### 4. Run the dev servers
73
127
 
74
128
  ```bash
75
129
  npm run dev # API (port 4000) + web (port 3000) together
@@ -78,7 +132,7 @@ npm run dev:api
78
132
  npm run dev:web
79
133
  ```
80
134
 
81
- ### 5. Log in
135
+ #### 5. Log in
82
136
 
83
137
  | URL | What |
84
138
  |---|---|
@@ -161,6 +215,7 @@ Six scene presets usable in the Hero or the dedicated 3D Background component: *
161
215
  | `npm run docker:up` / `npm run docker:down` | Start / stop Postgres + MinIO |
162
216
  | `npm run db:migrate` | Apply Prisma migrations (`prisma migrate dev`) |
163
217
  | `npm run db:seed` | Seed admin user, theme, sample page |
218
+ | `npm run db:reset-admin` | Delete the admin user matching `SEED_ADMIN_EMAIL` so the next `db:seed` recreates it (e.g. after changing the seed password) |
164
219
 
165
220
  ---
166
221
 
@@ -202,9 +257,9 @@ No builder-chrome changes needed — the palette, inspector, and drag-and-drop p
202
257
 
203
258
  **`port is already allocated` from Docker** — another container owns the host port. `docker ps`, then stop it or change the port mapping in `docker-compose.yml` + the URLs in `apps/api/.env`.
204
259
 
205
- **"Invalid email or password"** — credentials are case-sensitive; watch for browser autofill inserting a stale saved password. The current values live in `apps/api/.env`.
260
+ **"Invalid email or password"** — credentials are case-sensitive; watch for browser autofill inserting a stale saved password. The current values live in `apps/api/.env` (`SEED_ADMIN_EMAIL` / `SEED_ADMIN_PASSWORD`, used only the *first* time `db:seed` creates that user — editing `.env` afterward doesn't change an already-created password). If you scaffolded the project with `modern-cms` before v1.1.3 and your password contains `#`, it was silently truncated by `dotenv`'s comment parsing (fixed in 1.1.3 — update and rescaffold, or run `npm run db:reset-admin && npm run db:seed` to delete and recreate the existing admin user from the current `.env` values, without rescaffolding).
206
261
 
207
262
  **Prisma `EPERM ... query_engine ... .dll.node` on Windows** — the running API dev server is holding the engine file. Stop it (`netstat -ano | findstr :4000`, then kill that PID), run the migration, restart.
208
263
 
209
264
  **Dev server "running" but serving stale code** — an orphaned process may still own the port. Verify with `netstat -ano | findstr :3000` (or `:4000`) and kill the listed PID before restarting.
210
- "# Modern-CMS"
265
+
@@ -11,7 +11,8 @@
11
11
  "db:generate": "prisma generate",
12
12
  "db:seed": "tsx prisma/seed.ts",
13
13
  "db:seed:demo-charities": "tsx prisma/seed-our-charities.ts",
14
- "db:seed:templates": "tsx prisma/seed-templates.ts"
14
+ "db:seed:templates": "tsx prisma/seed-templates.ts",
15
+ "db:reset-admin": "tsx prisma/reset-admin.ts"
15
16
  },
16
17
  "dependencies": {
17
18
  "@aws-sdk/client-s3": "^3.665.0",
@@ -3,10 +3,18 @@ import { PrismaClient } from "@prisma/client";
3
3
 
4
4
  const prisma = new PrismaClient();
5
5
 
6
+ // Matches whatever seed.ts actually used to create the user — a hardcoded fallback
7
+ // here would silently no-op for anyone who set a custom SEED_ADMIN_EMAIL (which the
8
+ // modern-cms installer always prompts for).
6
9
  async function main() {
7
- const email = "admin@example.com";
8
- await prisma.user.deleteMany({ where: { email } });
9
- console.log("Deleted existing admin user");
10
+ const email = process.env.SEED_ADMIN_EMAIL ?? "admin@example.com";
11
+ const { count } = await prisma.user.deleteMany({ where: { email } });
12
+ if (count === 0) {
13
+ console.log(`No user found for ${email} — nothing to delete.`);
14
+ } else {
15
+ console.log(`Deleted existing admin user: ${email}`);
16
+ }
17
+ console.log('Run "npm run db:seed" (from the repo root) to recreate it with the current SEED_ADMIN_EMAIL/SEED_ADMIN_PASSWORD in .env.');
10
18
  }
11
19
 
12
20
  main()
@@ -0,0 +1,9 @@
1
+ node_modules/
2
+ dist/
3
+ .next/
4
+ .env
5
+ .env.local
6
+ *.log
7
+ .DS_Store
8
+ minio-data/
9
+ postgres-data/
@@ -18,7 +18,8 @@
18
18
  "docker:up": "docker compose up -d",
19
19
  "docker:down": "docker compose down",
20
20
  "db:migrate": "npm run db:migrate -w apps/api",
21
- "db:seed": "npm run db:seed -w apps/api"
21
+ "db:seed": "npm run db:seed -w apps/api",
22
+ "db:reset-admin": "npm run db:reset-admin -w apps/api"
22
23
  },
23
24
  "devDependencies": {
24
25
  "@types/react": "^19.2.17",
@@ -0,0 +1,15 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "lib": ["ES2022"],
5
+ "module": "ESNext",
6
+ "moduleResolution": "Bundler",
7
+ "esModuleInterop": true,
8
+ "skipLibCheck": true,
9
+ "forceConsistentCasingInFileNames": true,
10
+ "strict": true,
11
+ "resolveJsonModule": true,
12
+ "isolatedModules": true,
13
+ "declaration": false
14
+ }
15
+ }