nibula 1.5.0 → 1.5.2
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/.eleventyignore +1 -4
- package/CHANGELOG.md +51 -0
- package/README.md +11 -23
- package/bin/create.js +6 -8
- package/docs/Backend.md +37 -4
- package/docs/Deploy.md +99 -9
- package/nginx.conf +6 -43
- package/package.json +1 -1
- package/src/backend/example.config.php +13 -3
- package/src/backend/package.json +1 -2
- package/tools/lib/files.js +12 -1
- package/tools/lib/pageActions.js +7 -1
- package/.github/workflows/publish.yml +0 -37
package/.eleventyignore
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,57 @@ All notable changes to Nibula are documented here.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.5.2] - 2026-08-05
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- `nib new` no longer creates an empty `src/frontend/routes` folder. 1.5.1
|
|
12
|
+
removed it from `CREATE_DIRS` but left it in `MANDATORY_COPY`, so it still
|
|
13
|
+
arrived from the template. It is now created on demand when the first page is
|
|
14
|
+
added, and removed again when the last one is deleted.
|
|
15
|
+
|
|
16
|
+
## [1.5.1] - 2026-08-05
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
- `nib new` no longer creates an empty `routes` folder. Page source folders are
|
|
20
|
+
created on demand when a page is added, and removed again when the last page
|
|
21
|
+
in them is deleted — `routes`, `scss/pages` and the JS/TS pages folder alike.
|
|
22
|
+
- Removing a page that doesn't exist reported the skip and then went on to strip
|
|
23
|
+
its entry from `site.json` and `page-components.njk` anyway. It now stops.
|
|
24
|
+
- `example.config.php` was missing the `APP_ENV` key, so PHP projects had no way
|
|
25
|
+
to discover the debug switch from the template. Behaviour was unaffected —
|
|
26
|
+
the code already fell back to `production` — but the key is now visible and
|
|
27
|
+
documented, and the two templates are identical again.
|
|
28
|
+
- The backend's `dev` script set `APP_ENV` as an environment variable, which
|
|
29
|
+
neither backend reads. It ran in production mode and produced no debug output.
|
|
30
|
+
The script is gone; error verbosity is set in `config.js` / `config.php`.
|
|
31
|
+
- `bin/create.js` repeated the `mysql2` version already declared in
|
|
32
|
+
`src/backend/package.json`. It now reads that file, so the two cannot drift.
|
|
33
|
+
- `docs/Deploy.md` pointed at `backend/backend-node.service.example`, removed in
|
|
34
|
+
1.5.0. The systemd unit is written out in full instead.
|
|
35
|
+
- `docs/Deploy.md` gave the backend path as `/var/www/backend/SITE_FOLDER`,
|
|
36
|
+
inverted with respect to the rest of the document.
|
|
37
|
+
|
|
38
|
+
### Changed
|
|
39
|
+
- Nginx setup steps moved from the `nginx.conf` header into `docs/Deploy.md`,
|
|
40
|
+
under "Your own server". The header keeps only the three placeholders that
|
|
41
|
+
appear in the file and a pointer to the docs, so a config copied into
|
|
42
|
+
`/etc/nginx/sites-available/` no longer carries 60 lines of install
|
|
43
|
+
instructions that were already followed.
|
|
44
|
+
- `docs/Deploy.md` troubleshooting is now a table, with a row for a 502 on
|
|
45
|
+
`/api` caused by the Node process not running.
|
|
46
|
+
- `.eleventyignore` reduced to `src/frontend/assets/**`. The `scss`, `js` and
|
|
47
|
+
`src/backend` entries excluded nothing: the first two are not Eleventy
|
|
48
|
+
template formats and the third is outside the input directory. The last one
|
|
49
|
+
was also misleading, since `.eleventy.js` deliberately copies `src/backend`
|
|
50
|
+
into the build.
|
|
51
|
+
- `docs/Backend.md` documents `APP_ENV` in its own section, including the
|
|
52
|
+
`display_errors` behaviour specific to PHP, and states explicitly that it is
|
|
53
|
+
a config key rather than an environment variable.
|
|
54
|
+
|
|
55
|
+
### Notes
|
|
56
|
+
- Existing projects are unaffected: the scaffolding and template changes apply
|
|
57
|
+
only to newly created ones.
|
|
58
|
+
|
|
8
59
|
## [1.5.0] - 2026-08-04
|
|
9
60
|
|
|
10
61
|
### Added
|
package/README.md
CHANGED
|
@@ -76,19 +76,6 @@ cd your-project
|
|
|
76
76
|
nib run
|
|
77
77
|
```
|
|
78
78
|
|
|
79
|
-
## 💻 Commands
|
|
80
|
-
|
|
81
|
-
Run these from anywhere inside a project — except `nib new`, which must be run **outside** a project, in the folder where you want the new one created.
|
|
82
|
-
|
|
83
|
-
| Command | Description |
|
|
84
|
-
|---|---|
|
|
85
|
-
| `nib new <name>` | Create your new project |
|
|
86
|
-
| `nib run` | Start the dev server and build the output folder at runtime |
|
|
87
|
-
| `nib cli` | Open the page-management assistant |
|
|
88
|
-
| `nib build` | Build the output folder |
|
|
89
|
-
| `nib clean` | Remove the output directory |
|
|
90
|
-
| `nib update` | Update Nibula to the latest version (applies from your next project on) |
|
|
91
|
-
|
|
92
79
|
## 📄 Managing pages
|
|
93
80
|
|
|
94
81
|
Instead of creating and wiring up multiple files by hand, let the interactive assistant do it for you. To create, remove, or rename pages and configure the output path, run:
|
|
@@ -99,17 +86,18 @@ nib cli
|
|
|
99
86
|
|
|
100
87
|
See [docs/Assistant CLI.md](docs/Assistant%20CLI.md) for details.
|
|
101
88
|
|
|
102
|
-
##
|
|
103
|
-
|
|
104
|
-
Nibula builds a static site into your `out` folder, which you upload to a web
|
|
105
|
-
server. Which backend you chose affects deployment:
|
|
89
|
+
## 💻 Commands
|
|
106
90
|
|
|
107
|
-
|
|
108
|
-
- **PHP** runs on ordinary shared hosting (Apache/IIS) or a VPS with PHP-FPM — no process to keep alive.
|
|
91
|
+
Run these from anywhere inside a project — except `nib new`, which must be run **outside** a project, in the folder where you want the new one created.
|
|
109
92
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
93
|
+
| Command | Description |
|
|
94
|
+
|---|---|
|
|
95
|
+
| `nib new <name>` | Create your new project |
|
|
96
|
+
| `nib run` | Start the dev server and build the output folder at runtime |
|
|
97
|
+
| `nib cli` | Open the page-management assistant |
|
|
98
|
+
| `nib build` | Build the output folder |
|
|
99
|
+
| `nib clean` | Remove the output directory |
|
|
100
|
+
| `nib update` | Update Nibula to the latest version (applies from your next project on) |
|
|
113
101
|
|
|
114
102
|
## 🙌 Wrapping up
|
|
115
103
|
|
|
@@ -117,4 +105,4 @@ Thanks for giving Nibula a try.
|
|
|
117
105
|
|
|
118
106
|
It's a one-person project, so every bit of feedback counts more than you'd think: if something breaks, if the documentation isn't clear, or if a feature is missing, open an [issue](https://github.com/Rhaastrake/Nibula/issues) — even just to tell me what you built with it.
|
|
119
107
|
|
|
120
|
-
If Nibula was useful to you, leaving a ⭐ on the repository is the easiest way to help other people find it.
|
|
108
|
+
If Nibula was useful to you, leaving a ⭐ on the repository is the easiest way to help other people find it.
|
package/bin/create.js
CHANGED
|
@@ -53,11 +53,11 @@ const BACKEND_CHOICES = [
|
|
|
53
53
|
{ label: 'PHP (Can run everywhere)', value: BACKEND.PHP },
|
|
54
54
|
];
|
|
55
55
|
|
|
56
|
-
// Runtime
|
|
57
|
-
//
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
56
|
+
// Runtime dependencies for the Node backend, read from the backend's own
|
|
57
|
+
// package.json so the two never drift. They are added to the ROOT package.json
|
|
58
|
+
// when Node is chosen, so they land in the root node_modules (never in
|
|
59
|
+
// src/backend).
|
|
60
|
+
const NODE_BACKEND_DEPENDENCIES = require(path.join(templateDir, 'src/backend/package.json')).dependencies;
|
|
61
61
|
|
|
62
62
|
// ── COPY CONFIG ───────────────────────────────────────────────────────────────
|
|
63
63
|
|
|
@@ -74,9 +74,7 @@ const FRONTEND_EXCLUDE = {
|
|
|
74
74
|
[LANGUAGE.TYPESCRIPT]: ['js'],
|
|
75
75
|
};
|
|
76
76
|
|
|
77
|
-
const CREATE_DIRS = [
|
|
78
|
-
'src/frontend/routes',
|
|
79
|
-
];
|
|
77
|
+
const CREATE_DIRS = [];
|
|
80
78
|
|
|
81
79
|
// Backend files that belong to exactly one backend, matched by basename.
|
|
82
80
|
// Everything else (migrations, .htaccess, web.config, README, ...) is shared.
|
package/docs/Backend.md
CHANGED
|
@@ -107,19 +107,32 @@ both, PHP-array vs JS-object syntax.
|
|
|
107
107
|
|
|
108
108
|
```js
|
|
109
109
|
module.exports = {
|
|
110
|
+
// Default key for protected endpoints that don't have a specific key in CUSTOM_ENDPOINT_KEYS
|
|
110
111
|
GENERAL_API_KEY: 'DEFAULT_KEY',
|
|
112
|
+
|
|
113
|
+
// If you want to restrict access to protected endpoints to specific clients, define custom keys per endpoint.
|
|
114
|
+
// For subfolder endpoints, use the relative path ('subfolder/endpoint')
|
|
111
115
|
CUSTOM_ENDPOINT_KEYS: {
|
|
112
|
-
'subfolder/
|
|
116
|
+
'subfolder/example-protected': 'custom-key',
|
|
113
117
|
},
|
|
114
|
-
|
|
118
|
+
|
|
119
|
+
GENERAL_ALLOWED_ORIGINS: [
|
|
120
|
+
'*',
|
|
121
|
+
// 'https://example.com',
|
|
122
|
+
],
|
|
123
|
+
|
|
115
124
|
CUSTOM_ENDPOINT_ORIGINS: {
|
|
116
|
-
'subfolder/
|
|
125
|
+
'subfolder/example-protected': ['https://app.example.com'],
|
|
117
126
|
},
|
|
127
|
+
|
|
128
|
+
// Database configuration
|
|
118
129
|
DB_HOST: '127.0.0.1',
|
|
119
130
|
DB_NAME: 'example_db',
|
|
120
131
|
DB_USER: 'root',
|
|
121
132
|
DB_PASS: '',
|
|
122
|
-
|
|
133
|
+
|
|
134
|
+
// Environment: 'production' hides error details; anything else = debug.
|
|
135
|
+
APP_ENV: 'production',
|
|
123
136
|
};
|
|
124
137
|
```
|
|
125
138
|
|
|
@@ -147,6 +160,26 @@ endpoints).
|
|
|
147
160
|
Resolution order: `CUSTOM_ENDPOINT_ORIGINS[path]` if present, otherwise
|
|
148
161
|
`GENERAL_ALLOWED_ORIGINS`.
|
|
149
162
|
|
|
163
|
+
### Error verbosity
|
|
164
|
+
|
|
165
|
+
`APP_ENV` decides what an unhandled exception tells the client.
|
|
166
|
+
|
|
167
|
+
| Value | Response to a 500 |
|
|
168
|
+
|---|---|
|
|
169
|
+
| `'production'` (default) | `{"status":"error","message":"Internal server error","code":500}` |
|
|
170
|
+
| anything else | the real exception message, plus `stack` (Node) or `file` and `line` (PHP) |
|
|
171
|
+
|
|
172
|
+
On PHP it does one extra thing: `'production'` also turns off `display_errors`
|
|
173
|
+
and `error_reporting`, so a stray warning can't be printed before the JSON and
|
|
174
|
+
corrupt the response body.
|
|
175
|
+
|
|
176
|
+
Set it to something like `'development'` while building, and back to
|
|
177
|
+
`'production'` before you publish. Missing key means `'production'`.
|
|
178
|
+
|
|
179
|
+
> This is a config key, **not** an environment variable. Setting `APP_ENV` in a
|
|
180
|
+
> shell or in a systemd unit has no effect — both backends read it from
|
|
181
|
+
> `config.js` / `config.php` only.
|
|
182
|
+
|
|
150
183
|
## Database
|
|
151
184
|
|
|
152
185
|
Both backends expose a connection singleton reading the same config —
|
package/docs/Deploy.md
CHANGED
|
@@ -62,6 +62,8 @@ automatically.
|
|
|
62
62
|
modules) proxies `/api` to Node and wins if present. Remove it to fall through
|
|
63
63
|
to `ApiToPhp`, which rewrites `/api` to the PHP front controller.
|
|
64
64
|
|
|
65
|
+
---
|
|
66
|
+
|
|
65
67
|
## Your own server (Nginx on a VPS)
|
|
66
68
|
|
|
67
69
|
Nginx doesn't read per-directory config files — the whole site lives in one file.
|
|
@@ -69,6 +71,68 @@ Nibula ships `nginx.conf` in the project root as a ready-to-use site file that
|
|
|
69
71
|
**covers both backends without edits**: `/api` goes to Node, and if Node is
|
|
70
72
|
unreachable the request falls through to PHP automatically.
|
|
71
73
|
|
|
74
|
+
Upload the contents of `out` to `/var/www/SITE_FOLDER`, then follow the steps
|
|
75
|
+
below.
|
|
76
|
+
|
|
77
|
+
### 1. Replace
|
|
78
|
+
|
|
79
|
+
| Placeholder | Where |
|
|
80
|
+
|---|---|
|
|
81
|
+
| `YOUR_DOMAIN` | `server_name`, twice (port 80 and 443) |
|
|
82
|
+
| `SITE_FOLDER` | document root under `/var/www/` |
|
|
83
|
+
| `YOUR_CERTIFICATE` | dir under `/etc/letsencrypt/live/` |
|
|
84
|
+
| `SITE_NAME` | file name in the commands below |
|
|
85
|
+
|
|
86
|
+
### 2. Install (skip if already present)
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
sudo apt update
|
|
90
|
+
sudo apt install -y nginx certbot python3-certbot-nginx
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
If you are using PHP as backend:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
sudo apt install -y php-fpm
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### 3. Certificate
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
sudo certbot certonly --nginx --cert-name SITE_NAME -d YOUR_DOMAIN
|
|
103
|
+
sudo systemctl enable --now certbot.timer # auto-renew every 90 days
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### 4. Install the site
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
# Move to nginx folders
|
|
110
|
+
cd /etc/nginx/sites-available
|
|
111
|
+
|
|
112
|
+
# Create and write a new file
|
|
113
|
+
sudo nano SITE_NAME
|
|
114
|
+
# CTRL + O, ENTER, CTRL + X
|
|
115
|
+
|
|
116
|
+
# Copy the config to sites-enabled
|
|
117
|
+
sudo cp SITE_NAME ../sites-enabled/
|
|
118
|
+
|
|
119
|
+
# Test and reload the nginx configuration
|
|
120
|
+
sudo nginx -t && sudo systemctl reload nginx
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### If it fails
|
|
124
|
+
|
|
125
|
+
| Symptom | Cause |
|
|
126
|
+
|---|---|
|
|
127
|
+
| `cannot load certificate ... Permission denied` | `nginx -t` needs sudo |
|
|
128
|
+
| `cannot load certificate ... No such file` | wrong certificate name |
|
|
129
|
+
| `no alternative certificate subject name` | certificate doesn't cover domain |
|
|
130
|
+
| `unknown directive "http2"` | nginx < 1.25, check with `nginx -v` |
|
|
131
|
+
| NXDOMAIN / timeout during certbot | DNS not pointing here |
|
|
132
|
+
| 500 instead of the 404 page | `404.html` missing |
|
|
133
|
+
| 502 on `/api`, Node deployed | Node process not running |
|
|
134
|
+
| 502 on `/api`, PHP deployed | wrong php-fpm socket path |
|
|
135
|
+
|
|
72
136
|
---
|
|
73
137
|
|
|
74
138
|
## Starting the Node backend on the server
|
|
@@ -77,7 +141,7 @@ After uploading `out`:
|
|
|
77
141
|
|
|
78
142
|
1. Install the backend's runtime deps:
|
|
79
143
|
```bash
|
|
80
|
-
cd /var/www/backend
|
|
144
|
+
cd /var/www/SITE_FOLDER/backend
|
|
81
145
|
npm install
|
|
82
146
|
```
|
|
83
147
|
|
|
@@ -91,24 +155,50 @@ After uploading `out`:
|
|
|
91
155
|
sudo node /var/www/SITE_FOLDER/backend/_core/index.js
|
|
92
156
|
curl http://127.0.0.1:3000/api/example-public
|
|
93
157
|
```
|
|
94
|
-
4. Exit the screen without closing the process with `CTRL + A`, `D`. To resume the screen type `screen -r node-backend`.
|
|
95
158
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
159
|
+
4. Exit the screen without closing the process with `CTRL + A`, `D`. To resume
|
|
160
|
+
the screen type `screen -r node-backend`.
|
|
161
|
+
|
|
162
|
+
5. For production use **systemd**, which also restarts on crash and reboot.
|
|
163
|
+
Create `/etc/systemd/system/backend-node.service`:
|
|
164
|
+
|
|
165
|
+
```ini
|
|
166
|
+
[Unit]
|
|
167
|
+
Description=Nibula Node backend
|
|
168
|
+
After=network.target
|
|
169
|
+
|
|
170
|
+
[Service]
|
|
171
|
+
Type=simple
|
|
172
|
+
User=www-data
|
|
173
|
+
WorkingDirectory=/var/www/SITE_FOLDER/backend
|
|
174
|
+
ExecStart=/usr/bin/node /var/www/SITE_FOLDER/backend/_core/index.js
|
|
175
|
+
Restart=always
|
|
176
|
+
RestartSec=5
|
|
177
|
+
|
|
178
|
+
[Install]
|
|
179
|
+
WantedBy=multi-user.target
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Adjust `WorkingDirectory` and the `node` path (`which node`), then:
|
|
183
|
+
|
|
100
184
|
```bash
|
|
101
185
|
sudo systemctl daemon-reload
|
|
102
186
|
sudo systemctl enable --now backend-node
|
|
103
187
|
sudo systemctl status backend-node
|
|
104
188
|
```
|
|
189
|
+
|
|
105
190
|
(`pm2` works too: `pm2 start _core/index.js --name backend-node`.)
|
|
106
191
|
|
|
107
192
|
### Environment variables
|
|
108
193
|
|
|
194
|
+
Read by the Node backend at startup. Set them in the systemd unit with
|
|
195
|
+
`Environment=KEY=value`.
|
|
196
|
+
|
|
109
197
|
| Variable | Default | Purpose |
|
|
110
198
|
|---|---|---|
|
|
111
|
-
| `PORT` | `3000` | Port Node listens on (match
|
|
199
|
+
| `PORT` | `3000` | Port Node listens on (must match the proxy target in `nginx.conf`) |
|
|
112
200
|
| `HOST` | `127.0.0.1` | Bind address — keep it local; the web server is the public face |
|
|
113
|
-
| `
|
|
114
|
-
|
|
201
|
+
| `DOCUMENT_ROOT` | auto (`SITE_FOLDER/`) | Where `404.html` lives; detected as the folder above `backend/` |
|
|
202
|
+
|
|
203
|
+
Error verbosity is **not** an environment variable: it is the `APP_ENV` key in
|
|
204
|
+
`config.js` / `config.php`. See `docs/Backend.md`.
|
package/nginx.conf
CHANGED
|
@@ -1,49 +1,12 @@
|
|
|
1
1
|
# =============================================================================
|
|
2
|
-
# Nibula —
|
|
2
|
+
# Nibula — nginx site configuration
|
|
3
3
|
# -----------------------------------------------------------------------------
|
|
4
|
-
#
|
|
4
|
+
# Replace the three placeholders below, then follow the setup steps in
|
|
5
|
+
# docs/Deploy.md → "Your own server (Nginx on a VPS)".
|
|
5
6
|
#
|
|
6
|
-
# YOUR_DOMAIN server_name, twice (port 80 and 443)
|
|
7
|
-
# SITE_FOLDER
|
|
8
|
-
# YOUR_CERTIFICATE
|
|
9
|
-
# SITE_NAME commands below file name
|
|
10
|
-
#
|
|
11
|
-
# 2. INSTALL (skip if already present)
|
|
12
|
-
#
|
|
13
|
-
# sudo apt update
|
|
14
|
-
# sudo apt install -y nginx certbot python3-certbot-nginx
|
|
15
|
-
#
|
|
16
|
-
# If you are using PHP as backend:
|
|
17
|
-
# sudo apt install -y php-fpm
|
|
18
|
-
#
|
|
19
|
-
# 3. CERTIFICATE
|
|
20
|
-
#
|
|
21
|
-
# sudo certbot certonly --nginx --cert-name SITE_NAME -d YOUR_DOMAIN
|
|
22
|
-
# sudo systemctl enable --now certbot.timer # auto-renew every 90 days
|
|
23
|
-
#
|
|
24
|
-
# 4. INSTALL THE SITE
|
|
25
|
-
#
|
|
26
|
-
# Move to nginx folders
|
|
27
|
-
# cd /etc/nginx/sites-available
|
|
28
|
-
#
|
|
29
|
-
# Create and write a new file
|
|
30
|
-
# sudo nano SITE_NAME
|
|
31
|
-
# CTRL + O, ENTER, CTRL + X
|
|
32
|
-
#
|
|
33
|
-
# Copy the config to sites-enabled
|
|
34
|
-
# sudo cp SITE_NAME ../sites-enabled/
|
|
35
|
-
#
|
|
36
|
-
# Test and reload the nginx configuration
|
|
37
|
-
# sudo nginx -t && sudo systemctl reload nginx
|
|
38
|
-
#
|
|
39
|
-
# IF IT FAILS
|
|
40
|
-
# cannot load certificate ... Permission denied → nginx -t needs sudo
|
|
41
|
-
# cannot load certificate ... No such file → wrong certificate name
|
|
42
|
-
# no alternative certificate subject name → certificate doesn't cover domain
|
|
43
|
-
# unknown directive "http2" → nginx < 1.25, check with nginx -v
|
|
44
|
-
# 500 instead of the 404 page → 404.html missing
|
|
45
|
-
# NXDOMAIN / timeout during certbot → DNS not pointing here
|
|
46
|
-
# 502 on /api with PHP deployed → wrong php-fpm socket path
|
|
7
|
+
# YOUR_DOMAIN your domain — server_name, twice (port 80 and 443)
|
|
8
|
+
# SITE_FOLDER the folder under /var/www/ holding the site
|
|
9
|
+
# YOUR_CERTIFICATE the directory name under /etc/letsencrypt/live/
|
|
47
10
|
# =============================================================================
|
|
48
11
|
|
|
49
12
|
# HTTP (80) configuration
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nibula",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.2",
|
|
4
4
|
"description": "A beginner-friendly static site generator built on Eleventy that stays close to vanilla HTML, CSS and JS — with a page-management CLI, an optional PHP backend, and SEO files generated for you.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"static-site-generator",
|
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
<?php
|
|
2
2
|
declare(strict_types=1);
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Mirror of src/backend/example.config.js
|
|
6
|
+
*
|
|
7
|
+
* Versioned, secret-free template. On setup, copy this file to config.php and
|
|
8
|
+
* fill in real values. config.php is git-ignored and stays local.
|
|
9
|
+
*/
|
|
10
|
+
|
|
4
11
|
return [
|
|
5
12
|
// Default key for protected endpoints that don't have a specific key in CUSTOM_ENDPOINT_KEYS
|
|
6
13
|
'GENERAL_API_KEY' => 'DEFAULT_KEY',
|
|
7
14
|
|
|
8
|
-
// If you want restrict access to protected endpoints to specific clients,
|
|
15
|
+
// If you want to restrict access to protected endpoints to specific clients, define custom keys per endpoint.
|
|
9
16
|
// For subfolder endpoints, use the relative path ('subfolder/endpoint')
|
|
10
17
|
'CUSTOM_ENDPOINT_KEYS' => [
|
|
11
|
-
'subfolder/example-protected'
|
|
18
|
+
'subfolder/example-protected' => 'custom-key',
|
|
12
19
|
],
|
|
13
20
|
|
|
14
21
|
'GENERAL_ALLOWED_ORIGINS' => [
|
|
@@ -17,7 +24,7 @@ return [
|
|
|
17
24
|
],
|
|
18
25
|
|
|
19
26
|
'CUSTOM_ENDPOINT_ORIGINS' => [
|
|
20
|
-
'subfolder/example-protected'
|
|
27
|
+
'subfolder/example-protected' => ['https://app.example.com'],
|
|
21
28
|
],
|
|
22
29
|
|
|
23
30
|
// Database configuration
|
|
@@ -25,4 +32,7 @@ return [
|
|
|
25
32
|
'DB_NAME' => 'example_db',
|
|
26
33
|
'DB_USER' => 'root',
|
|
27
34
|
'DB_PASS' => '',
|
|
35
|
+
|
|
36
|
+
// Environment: 'production' hides error details; anything else = debug.
|
|
37
|
+
'APP_ENV' => 'production',
|
|
28
38
|
];
|
package/src/backend/package.json
CHANGED
package/tools/lib/files.js
CHANGED
|
@@ -52,6 +52,16 @@ function removeDirectory(target) {
|
|
|
52
52
|
return true;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
function removeDirectoryIfEmpty(target) {
|
|
56
|
+
try {
|
|
57
|
+
if (fs.readdirSync(target).length > 0) return false;
|
|
58
|
+
fs.rmdirSync(target);
|
|
59
|
+
return true;
|
|
60
|
+
} catch (error) {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
55
65
|
module.exports = {
|
|
56
66
|
exists,
|
|
57
67
|
readText,
|
|
@@ -62,4 +72,5 @@ module.exports = {
|
|
|
62
72
|
moveFile,
|
|
63
73
|
removeFile,
|
|
64
74
|
removeDirectory,
|
|
65
|
-
|
|
75
|
+
removeDirectoryIfEmpty,
|
|
76
|
+
};
|
package/tools/lib/pageActions.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
2
|
const settings = require('../config/settings.json');
|
|
3
3
|
const { PATHS } = require('./paths');
|
|
4
|
-
const { exists, readText, writeText, copyFile, moveFile, removeFile, removeDirectory } = require('./files');
|
|
4
|
+
const { exists, readText, writeText, copyFile, moveFile, removeFile, removeDirectory, removeDirectoryIfEmpty } = require('./files');
|
|
5
5
|
const { log } = require('./logger');
|
|
6
6
|
const { formatText } = require('./text');
|
|
7
7
|
const { languageSettings } = require('./project');
|
|
@@ -133,6 +133,12 @@ function removePage(pageName) {
|
|
|
133
133
|
|
|
134
134
|
removePageBlock(pageName);
|
|
135
135
|
removeSiteData(pageName);
|
|
136
|
+
|
|
137
|
+
const sourceDirectories = [source.style, source.script, source.route].map(file => path.dirname(file));
|
|
138
|
+
|
|
139
|
+
for (const directory of sourceDirectories) {
|
|
140
|
+
if (removeDirectoryIfEmpty(directory)) log('page.fileDeleted', { path: directory });
|
|
141
|
+
}
|
|
136
142
|
}
|
|
137
143
|
|
|
138
144
|
module.exports = { addPage, removePage, renamePage };
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
name: Publish to npm
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
release:
|
|
5
|
-
types: [published]
|
|
6
|
-
workflow_dispatch:
|
|
7
|
-
|
|
8
|
-
permissions:
|
|
9
|
-
contents: read
|
|
10
|
-
id-token: write
|
|
11
|
-
|
|
12
|
-
jobs:
|
|
13
|
-
publish:
|
|
14
|
-
runs-on: ubuntu-latest
|
|
15
|
-
steps:
|
|
16
|
-
- uses: actions/checkout@v4
|
|
17
|
-
|
|
18
|
-
- uses: actions/setup-node@v4
|
|
19
|
-
with:
|
|
20
|
-
node-version: 22
|
|
21
|
-
registry-url: https://registry.npmjs.org
|
|
22
|
-
|
|
23
|
-
- name: Check that package.json matches the tag
|
|
24
|
-
if: github.event_name == 'release'
|
|
25
|
-
run: |
|
|
26
|
-
TAG="${GITHUB_REF_NAME#v}"
|
|
27
|
-
PKG=$(node -p "require('./package.json').version")
|
|
28
|
-
if [ "$TAG" != "$PKG" ]; then
|
|
29
|
-
echo "Tag $TAG does not match package.json version $PKG"
|
|
30
|
-
exit 1
|
|
31
|
-
fi
|
|
32
|
-
|
|
33
|
-
- run: npm install -g npm@latest
|
|
34
|
-
|
|
35
|
-
- run: npm ci
|
|
36
|
-
|
|
37
|
-
- run: npm publish --provenance --access public
|