webspresso 0.0.53 → 0.0.56
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 +44 -1
- package/bin/commands/admin-password.js +11 -62
- package/package.json +1 -1
- package/plugins/seo-checker/panel.js +20 -9
- package/plugins/site-analytics/index.js +7 -4
package/README.md
CHANGED
|
@@ -249,6 +249,25 @@ This command will:
|
|
|
249
249
|
- `--short-name <string>` – manifest.json `short_name` (PWA)
|
|
250
250
|
- `--no-layout` – Do not add include to layout.njk
|
|
251
251
|
|
|
252
|
+
### Admin Panel Commands
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
# Create admin_users table migration
|
|
256
|
+
webspresso admin:setup
|
|
257
|
+
|
|
258
|
+
# List all admin users
|
|
259
|
+
webspresso admin:list
|
|
260
|
+
|
|
261
|
+
# Reset admin password (interactive)
|
|
262
|
+
webspresso admin:password
|
|
263
|
+
|
|
264
|
+
# Reset with options
|
|
265
|
+
webspresso admin:password -e admin@example.com -p yeni_sifre123
|
|
266
|
+
webspresso admin:password -c ./webspresso.db.js -E production
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
> **Note:** Requires `webspresso.db.js` or `knexfile.js` in project root. Run from project directory.
|
|
270
|
+
|
|
252
271
|
## Project Structure
|
|
253
272
|
|
|
254
273
|
Create your app with this structure:
|
|
@@ -1339,9 +1358,33 @@ webspresso db:make create_posts_table
|
|
|
1339
1358
|
webspresso db:make create_users_table --model User
|
|
1340
1359
|
|
|
1341
1360
|
# Admin Panel Setup
|
|
1342
|
-
webspresso admin:setup
|
|
1361
|
+
webspresso admin:setup # Create admin_users migration
|
|
1362
|
+
webspresso admin:list # List all admin users
|
|
1363
|
+
webspresso admin:password # Reset admin password (interactive or -e -p)
|
|
1343
1364
|
```
|
|
1344
1365
|
|
|
1366
|
+
**Admin CLI Commands:**
|
|
1367
|
+
|
|
1368
|
+
```bash
|
|
1369
|
+
# Create admin_users table migration
|
|
1370
|
+
webspresso admin:setup
|
|
1371
|
+
|
|
1372
|
+
# List all admin users
|
|
1373
|
+
webspresso admin:list
|
|
1374
|
+
|
|
1375
|
+
# Reset admin password (interactive: prompts for email and password)
|
|
1376
|
+
webspresso admin:password
|
|
1377
|
+
|
|
1378
|
+
# Reset with options
|
|
1379
|
+
webspresso admin:password -e admin@example.com -p yeni_sifre123
|
|
1380
|
+
|
|
1381
|
+
# Use custom config or environment
|
|
1382
|
+
webspresso admin:password -c ./webspresso.db.js -E production
|
|
1383
|
+
webspresso admin:list -c ./webspresso.db.js
|
|
1384
|
+
```
|
|
1385
|
+
|
|
1386
|
+
> **Note:** Database config is loaded from `webspresso.db.js` or `knexfile.js` in the project root. Run commands from your project directory.
|
|
1387
|
+
|
|
1345
1388
|
**Database Config File (`webspresso.db.js`):**
|
|
1346
1389
|
|
|
1347
1390
|
```javascript
|
|
@@ -3,9 +3,8 @@
|
|
|
3
3
|
* Reset admin user password via CLI
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
const fs = require('fs');
|
|
7
|
-
const path = require('path');
|
|
8
6
|
const readline = require('readline');
|
|
7
|
+
const { loadDbConfig, createDbInstance } = require('../utils/db');
|
|
9
8
|
|
|
10
9
|
function registerCommand(program) {
|
|
11
10
|
program
|
|
@@ -13,41 +12,13 @@ function registerCommand(program) {
|
|
|
13
12
|
.description('Reset admin user password')
|
|
14
13
|
.option('-e, --email <email>', 'Admin user email')
|
|
15
14
|
.option('-p, --password <password>', 'New password (not recommended, use interactive mode)')
|
|
16
|
-
.option('-c, --config <path>', 'Path to database config file')
|
|
15
|
+
.option('-c, --config <path>', 'Path to database config file (webspresso.db.js or knexfile.js)')
|
|
16
|
+
.option('-E, --env <environment>', 'Environment (development, production)', 'development')
|
|
17
17
|
.action(async (options) => {
|
|
18
18
|
try {
|
|
19
|
-
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
// Try to find and load the database config
|
|
23
|
-
let dbConfig = null;
|
|
24
|
-
const configPaths = [
|
|
25
|
-
options.config,
|
|
26
|
-
path.join(cwd, 'webspresso.config.js'),
|
|
27
|
-
path.join(cwd, 'database.config.js'),
|
|
28
|
-
path.join(cwd, 'db.config.js'),
|
|
29
|
-
].filter(Boolean);
|
|
30
|
-
|
|
31
|
-
for (const configPath of configPaths) {
|
|
32
|
-
if (fs.existsSync(configPath)) {
|
|
33
|
-
const config = require(configPath);
|
|
34
|
-
dbConfig = config.database || config;
|
|
35
|
-
break;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (!dbConfig) {
|
|
40
|
-
console.error('❌ Error: Could not find database configuration.');
|
|
41
|
-
console.error(' Please run this command from your project root.');
|
|
42
|
-
process.exit(1);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// Lazy load dependencies
|
|
46
|
-
const bcrypt = require('bcrypt');
|
|
47
|
-
const knex = require('knex');
|
|
48
|
-
|
|
49
|
-
// Initialize database connection
|
|
50
|
-
const db = knex(dbConfig);
|
|
19
|
+
const { config, path: configPath } = loadDbConfig(options.config);
|
|
20
|
+
const db = await createDbInstance(config, options.env);
|
|
21
|
+
console.log(`\n📦 Using config: ${configPath}\n`);
|
|
51
22
|
|
|
52
23
|
// Check if admin_users table exists
|
|
53
24
|
const hasTable = await db.schema.hasTable('admin_users');
|
|
@@ -174,35 +145,13 @@ function registerCommand(program) {
|
|
|
174
145
|
program
|
|
175
146
|
.command('admin:list')
|
|
176
147
|
.description('List all admin users')
|
|
177
|
-
.option('-c, --config <path>', 'Path to database config file')
|
|
148
|
+
.option('-c, --config <path>', 'Path to database config file (webspresso.db.js or knexfile.js)')
|
|
149
|
+
.option('-E, --env <environment>', 'Environment (development, production)', 'development')
|
|
178
150
|
.action(async (options) => {
|
|
179
151
|
try {
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
let dbConfig = null;
|
|
184
|
-
const configPaths = [
|
|
185
|
-
options.config,
|
|
186
|
-
path.join(cwd, 'webspresso.config.js'),
|
|
187
|
-
path.join(cwd, 'database.config.js'),
|
|
188
|
-
path.join(cwd, 'db.config.js'),
|
|
189
|
-
].filter(Boolean);
|
|
190
|
-
|
|
191
|
-
for (const configPath of configPaths) {
|
|
192
|
-
if (fs.existsSync(configPath)) {
|
|
193
|
-
const config = require(configPath);
|
|
194
|
-
dbConfig = config.database || config;
|
|
195
|
-
break;
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
if (!dbConfig) {
|
|
200
|
-
console.error('❌ Error: Could not find database configuration.');
|
|
201
|
-
process.exit(1);
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
const knex = require('knex');
|
|
205
|
-
const db = knex(dbConfig);
|
|
152
|
+
const { config, path: configPath } = loadDbConfig(options.config);
|
|
153
|
+
const db = await createDbInstance(config, options.env);
|
|
154
|
+
console.log(`\n📦 Using config: ${configPath}\n`);
|
|
206
155
|
|
|
207
156
|
// Check if admin_users table exists
|
|
208
157
|
const hasTable = await db.schema.hasTable('admin_users');
|
package/package.json
CHANGED
|
@@ -172,34 +172,44 @@ function generatePanelStyles() {
|
|
|
172
172
|
.seo-tabs {
|
|
173
173
|
display: flex;
|
|
174
174
|
padding: 0 12px;
|
|
175
|
-
gap:
|
|
175
|
+
gap: 4px;
|
|
176
176
|
background: rgba(0,0,0,0.2);
|
|
177
177
|
border-bottom: 1px solid rgba(255,255,255,0.06);
|
|
178
178
|
overflow-x: auto;
|
|
179
|
-
|
|
179
|
+
overflow-y: hidden;
|
|
180
|
+
scrollbar-width: thin;
|
|
181
|
+
scrollbar-color: #3f3f46 transparent;
|
|
180
182
|
}
|
|
181
183
|
|
|
182
184
|
.seo-tabs::-webkit-scrollbar {
|
|
183
|
-
|
|
185
|
+
height: 4px;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.seo-tabs::-webkit-scrollbar-track {
|
|
189
|
+
background: transparent;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.seo-tabs::-webkit-scrollbar-thumb {
|
|
193
|
+
background: #3f3f46;
|
|
194
|
+
border-radius: 2px;
|
|
184
195
|
}
|
|
185
196
|
|
|
186
197
|
.seo-tab {
|
|
187
|
-
flex:
|
|
188
|
-
|
|
189
|
-
padding: 12px 8px;
|
|
198
|
+
flex: 0 0 auto;
|
|
199
|
+
padding: 10px 10px;
|
|
190
200
|
background: none;
|
|
191
201
|
border: none;
|
|
192
202
|
color: #71717a;
|
|
193
203
|
font-size: 10px;
|
|
194
204
|
font-weight: 500;
|
|
195
205
|
text-transform: uppercase;
|
|
196
|
-
letter-spacing: 0.
|
|
206
|
+
letter-spacing: 0.3px;
|
|
197
207
|
cursor: pointer;
|
|
198
208
|
transition: all 0.2s;
|
|
199
209
|
display: flex;
|
|
200
210
|
flex-direction: column;
|
|
201
211
|
align-items: center;
|
|
202
|
-
gap:
|
|
212
|
+
gap: 4px;
|
|
203
213
|
border-bottom: 2px solid transparent;
|
|
204
214
|
white-space: nowrap;
|
|
205
215
|
}
|
|
@@ -400,7 +410,8 @@ function generatePanelStyles() {
|
|
|
400
410
|
}
|
|
401
411
|
|
|
402
412
|
.seo-tab {
|
|
403
|
-
|
|
413
|
+
flex: 0 0 auto;
|
|
414
|
+
padding: 8px 8px;
|
|
404
415
|
font-size: 9px;
|
|
405
416
|
}
|
|
406
417
|
|
|
@@ -62,17 +62,20 @@ function siteAnalyticsPlugin(options = {}) {
|
|
|
62
62
|
|
|
63
63
|
ctx.app.use(trackingMiddleware);
|
|
64
64
|
|
|
65
|
-
// Client error tracking: public POST endpoint + inject script
|
|
66
65
|
if (trackClientErrors) {
|
|
67
|
-
const errorHandler = createErrorReportHandler({ knex, tableName: errorsTableName });
|
|
68
|
-
ctx.addRoute('post', '/_analytics/report-error', errorHandler);
|
|
69
|
-
|
|
70
66
|
const script = generateErrorTrackerScript({ endpoint: '/_analytics/report-error' });
|
|
71
67
|
ctx.injectBody(`<script>${script}</script>`, { id: 'site-analytics-error-tracker', priority: 5 });
|
|
72
68
|
}
|
|
73
69
|
},
|
|
74
70
|
|
|
75
71
|
onRoutesReady(ctx) {
|
|
72
|
+
// Client error report endpoint (must be in onRoutesReady - addRoute only mounts there)
|
|
73
|
+
if (trackClientErrors) {
|
|
74
|
+
const knex = db.knex || db;
|
|
75
|
+
const errorHandler = createErrorReportHandler({ knex, tableName: errorsTableName });
|
|
76
|
+
ctx.addRoute('post', '/_analytics/report-error', errorHandler);
|
|
77
|
+
}
|
|
78
|
+
|
|
76
79
|
const adminApi = ctx.usePlugin('admin-panel');
|
|
77
80
|
if (!adminApi) {
|
|
78
81
|
console.warn('[site-analytics] admin-panel plugin not found, skipping admin page registration');
|