webspresso 0.0.105 → 0.0.107
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/.agents/AGENTS.md +15 -2
- package/.agents/CLI.md +219 -7
- package/.agents/FLAGS.md +118 -0
- package/.agents/LOGGING.md +93 -0
- package/.agents/METRICS.md +127 -0
- package/.agents/MIGRATION_JOBS.md +95 -0
- package/.agents/PLUGINS.md +10 -3
- package/.agents/QUEUE.md +42 -0
- package/.agents/RATE_LIMIT.md +147 -0
- package/.agents/SCALE_OUT.md +109 -0
- package/.agents/SECRETS.md +117 -0
- package/AGENTS.md +10 -0
- package/bin/commands/add-aws.js +396 -0
- package/bin/commands/add-ci.js +523 -0
- package/bin/commands/add-cloudflare.js +240 -0
- package/bin/commands/add-cloudrun.js +381 -0
- package/bin/commands/add-migration-job.js +396 -0
- package/bin/commands/assets-sync.js +209 -0
- package/bin/commands/client-generate.js +52 -0
- package/bin/commands/console.js +53 -0
- package/bin/commands/db-migrate.js +47 -2
- package/bin/commands/db-studio.js +84 -0
- package/bin/commands/deploy-check.js +242 -13
- package/bin/commands/export.js +87 -0
- package/bin/commands/secrets-pull.js +208 -0
- package/bin/utils/db.js +7 -1
- package/bin/webspresso.js +39 -7
- package/core/app.js +453 -0
- package/core/auth/authenticate.js +93 -0
- package/core/auth/index.js +38 -5
- package/core/auth/jwt.js +85 -13
- package/core/auth/magic-link.js +23 -5
- package/core/auth/manager.js +57 -6
- package/core/auth/middleware.js +16 -68
- package/core/auth/redis-session.js +1045 -0
- package/core/auth/session-manager.js +28 -2
- package/core/auth/sessions.js +308 -22
- package/core/cache/cdn.js +296 -0
- package/core/cache/index.js +12 -0
- package/core/cache/tagged-lru.js +9 -1
- package/core/console/commands.js +148 -0
- package/core/console/context.js +260 -0
- package/core/console/eval.js +73 -0
- package/core/console/index.js +22 -0
- package/core/console/repl.js +102 -0
- package/core/content/service.js +1 -0
- package/core/errors/domain.js +20 -1
- package/core/errors/http.js +1 -0
- package/core/events/dispatcher.js +7 -0
- package/core/events/signal.js +7 -0
- package/core/export/discovery.js +191 -0
- package/core/export/exporter.js +277 -0
- package/core/export/index.js +24 -0
- package/core/flags/evaluator.js +252 -0
- package/core/flags/hasher.js +37 -0
- package/core/flags/index.js +21 -0
- package/core/flags/manager.js +263 -0
- package/core/flags/store.js +126 -0
- package/core/health/middleware.js +3 -3
- package/core/http/adapter.js +74 -0
- package/core/http/express-adapter.js +46 -0
- package/core/http/hono-adapter.js +531 -0
- package/core/http/index.js +41 -0
- package/core/http/pipeline.js +519 -0
- package/core/index.js +347 -0
- package/core/limits/middleware.js +9 -1
- package/core/logger/formatters.js +264 -0
- package/core/logger/index.js +260 -0
- package/core/logger/trace.js +137 -0
- package/core/mail/mailer.js +1 -1
- package/core/metrics/collectors.js +125 -0
- package/core/metrics/index.js +45 -0
- package/core/metrics/middleware.js +230 -0
- package/core/metrics/registry.js +366 -0
- package/core/orm/d1.js +265 -0
- package/core/orm/eager-loader.js +81 -1
- package/core/orm/index.js +122 -8
- package/core/orm/json-fields.js +44 -13
- package/core/orm/migrate-cloud.js +194 -0
- package/core/orm/model.js +12 -0
- package/core/orm/pool.js +97 -0
- package/core/orm/query-builder.js +42 -15
- package/core/orm/repository.js +59 -12
- package/core/orm/scopes.js +54 -4
- package/core/queue/adapters/cloudflare.js +131 -0
- package/core/queue/adapters/pubsub.js +400 -0
- package/core/queue/adapters/sqs.js +419 -0
- package/core/queue/adapters/wait-until.js +77 -0
- package/core/queue/index.js +8 -0
- package/core/queue/manager.js +11 -0
- package/core/rate-limit/index.js +22 -0
- package/core/rate-limit/limiter.js +219 -0
- package/core/rate-limit/stores/memory.js +129 -0
- package/core/rate-limit/stores/redis.js +151 -0
- package/core/rate-limit/utils.js +112 -0
- package/core/resilience/circuit-breaker.js +31 -0
- package/core/secrets/index.js +113 -0
- package/core/secrets/manager.js +308 -0
- package/core/secrets/providers/aws.js +288 -0
- package/core/secrets/providers/env.js +44 -0
- package/core/secrets/providers/gcp.js +307 -0
- package/core/secrets/providers/memory.js +76 -0
- package/core/services/index.js +9 -0
- package/core/shutdown/shutdown-manager.js +66 -38
- package/core/stream/index.js +19 -0
- package/core/stream/text-stream.js +326 -0
- package/core/studio/index.js +43 -0
- package/core/studio/inspector.js +266 -0
- package/core/studio/server.js +341 -0
- package/core/studio/ui.js +681 -0
- package/core/utils/string.js +77 -16
- package/core/validation/index.js +18 -0
- package/index.d.ts +1106 -10
- package/index.js +129 -3
- package/package.json +20 -8
- package/plugins/admin-panel/client/parts/07-model-list.js +5 -2
- package/plugins/admin-panel/index.js +36 -16
- package/plugins/admin-panel/modules/user-management.js +3 -2
- package/plugins/api-key/index.js +3 -2
- package/plugins/audit-log/index.js +3 -1
- package/plugins/basic-auth/index.js +3 -2
- package/plugins/cors.js +3 -2
- package/plugins/csrf/index.js +6 -4
- package/plugins/csv/index.js +8 -5
- package/plugins/dashboard/index.js +27 -7
- package/plugins/email/index.js +11 -9
- package/plugins/index.js +3 -0
- package/plugins/queue/index.js +18 -2
- package/plugins/redirect/index.js +7 -2
- package/plugins/seo-checker/index.js +2 -2
- package/plugins/site-analytics/index.js +3 -1
- package/plugins/swagger.js +8 -2
- package/plugins/upload/gcs-provider.js +148 -0
- package/plugins/upload/index.js +132 -74
- package/plugins/upload/s3-provider.js +257 -0
- package/plugins/webhooks/index.js +27 -23
- package/plugins/xlsx/index.js +7 -5
- package/src/api/api-loader.js +12 -95
- package/src/api/define-api.js +1 -0
- package/src/app-context.js +9 -1
- package/src/client-runtime/constants.js +10 -0
- package/src/client-runtime/mount.js +2 -3
- package/src/dev/client-gen.js +458 -0
- package/src/discovery/scan-routes.js +5 -2
- package/src/file-router.js +14 -3
- package/src/helpers.js +53 -0
- package/src/pages/page-loader.js +12 -205
- package/src/plugin-manager.js +280 -47
- package/src/server.js +253 -169
- package/src/services/discovery.js +9 -1
- package/src/services/executor.js +271 -49
- package/src/services/index.js +52 -3
- package/src/services/loader.js +120 -0
- package/src/services/memoize.js +223 -49
- package/src/services/registry.js +501 -95
- package/src/services/validator.js +202 -33
package/.agents/AGENTS.md
CHANGED
|
@@ -19,6 +19,12 @@ When tasked with a feature or bugfix, **immediately consult the corresponding to
|
|
|
19
19
|
| **Background Jobs & Worker Queue** | [`.agents/QUEUE.md`](QUEUE.md) | `jobs/` |
|
|
20
20
|
| **Decoupled Events & Signals** | [`.agents/EVENTS.md`](EVENTS.md) | `core/events/`, `listeners/` |
|
|
21
21
|
| **Fault Tolerance / Circuit Breaker / Retry** | [`.agents/RESILIENCE.md`](RESILIENCE.md) | `core/resilience/` |
|
|
22
|
+
| **Stateless Scale-Out (Redis Sessions & DB Pool)** | [`.agents/SCALE_OUT.md`](SCALE_OUT.md) | `core/auth/redis-session.js`, `core/orm/pool.js` |
|
|
23
|
+
| **Cloud Secrets (GCP & AWS Secret Manager)** | [`.agents/SECRETS.md`](SECRETS.md) | `core/secrets/`, `bin/commands/secrets-pull.js` |
|
|
24
|
+
| **Cloud Metrics & Distributed Tracing** | [`.agents/METRICS.md`](METRICS.md) | `core/metrics/`, `/metrics` |
|
|
25
|
+
| **Cloud Migration Jobs (Zero-Downtime DB Deploy)** | [`.agents/MIGRATION_JOBS.md`](MIGRATION_JOBS.md) | `bin/commands/add-migration-job.js`, `core/orm/migrate-cloud.js` |
|
|
26
|
+
| **Rate Limiting Engine (Zero-Dependency & Redis)** | [`.agents/RATE_LIMIT.md`](RATE_LIMIT.md) | `core/rate-limit/` |
|
|
27
|
+
| **Feature Flags & Canary Splitter (`core/flags`)** | [`.agents/FLAGS.md`](FLAGS.md) | `core/flags/` |
|
|
22
28
|
| **API Signatures & Types Verification** | [`index.d.ts`](../index.d.ts) | **Canonical Ground Truth** |
|
|
23
29
|
|
|
24
30
|
---
|
|
@@ -50,10 +56,10 @@ This `.agents/` customization root is organized into modular topic guides:
|
|
|
50
56
|
10. **[Realtime Layer & Adapters](.agents/REALTIME.md)** — Framework-agnostic realtime layer (`core/realtime`), generic WebSocket, SSE, and Socket.IO adapters, subscription identity, backoff reconnect, and auth lifecycle.
|
|
51
57
|
11. **[Email Plugin Guide](.agents/EMAIL.md)** — MJML template compilation, Nodemailer transport, DB delivery logs, Auth Email bridge, and Admin UI.
|
|
52
58
|
12. **[Admin Panel Customization](.agents/ADMIN.md)** — Extending Mithril.js Admin Panel SPA (Custom pages `component.js`, custom field renderers, widgets, single & bulk actions).
|
|
53
|
-
13. **[CLI Tooling & Commands](CLI.md)** — `webspresso dev`, `build`, `doctor`, `db:migrate`, `db:seed`, `polar:migrate`, `favicon:generate`, `add:tailwind`, `add:docker`, `deploy:check`, `agents:init`.
|
|
59
|
+
13. **[CLI Tooling & Commands](CLI.md)** — `webspresso dev`, `build`, `doctor`, `db:migrate`, `db:seed`, `polar:migrate`, `favicon:generate`, `add:tailwind`, `add:docker`, `add:cloudrun`, `add:aws`, `add:cloudflare`, `deploy:check`, `agents:init`.
|
|
54
60
|
14. **[Development & Testing Workflow](.agents/WORKFLOW.md)** — CLI commands, Vitest unit/integration testing, Playwright E2E tests, TypeScript type checking, and zero regression policy.
|
|
55
61
|
15. **[Coding Standards & Conventions](.agents/CONVENTIONS.md)** — Zero external dependencies policy, strict function signature & schema verification, clean component separation, and log traceback inspection rules.
|
|
56
|
-
16. **[Background Job Queue](.agents/QUEUE.md)** — In-Memory, Knex Database,
|
|
62
|
+
16. **[Background Job Queue](.agents/QUEUE.md)** — In-Memory, Knex Database, Distributed Redis, AWS SQS, and Google Cloud Pub/Sub queue adapters, job auto-discovery (`jobs/`), retries, and graceful draining.
|
|
57
63
|
17. **[SSR Streaming & Chunked Transfer](.agents/STREAMING.md)** — Native HTTP chunked streaming (`res.renderStream()`), deferred data loader slots (`defer: { key: promise }`), and TTFB optimization.
|
|
58
64
|
18. **Polar billing production checklist** — [docs/guides/polar-production-checklist.md](../docs/guides/polar-production-checklist.md) (env, webhooks, rate limits, external tier hooks, CSP). Plugin reference: [PLUGINS.md § polarPlugin](PLUGINS.md).
|
|
59
65
|
19. **[Decoupled Events & Signals Architecture](.agents/EVENTS.md)** — Zero-dependency enterprise event dispatcher (`core/events`), sync/async/parallel/serial/waterfall dispatch, wildcard listeners (`order.*`), Django-style `Signal` and sender filtering, queue bridging, and listener auto-discovery.
|
|
@@ -62,6 +68,13 @@ This `.agents/` customization root is organized into modular topic guides:
|
|
|
62
68
|
22. **[Cloud & Kubernetes Health Probes](.agents/HEALTH.md)** — Zero-dependency RFC-compliant liveness (`/healthz`), readiness (`/readyz`), and combined diagnostic (`/health`) probes (`core/health`), event loop lag telemetry, database/queue health monitors, automatic HTTP 503 draining on graceful shutdown, and `createApp({ healthCheck: true })`.
|
|
63
69
|
23. **[LRU & Tagged Cache Engine](.agents/CACHE.md)** — Zero-dependency, memory-bounded in-memory LRU cache (`core/cache`), byte budget constraints (`maxBytes` / `maxMemoryMb`), TTL expiration, stampede protection (`getOrSet`), leak-free tag invalidation (`TaggedLruCache`), ORM query cache provider, and `createApp({ cache })`.
|
|
64
70
|
24. **[Enterprise Resilience & Circuit Breaker](.agents/RESILIENCE.md)** — Zero-dependency fault tolerance engine (`core/resilience`), three-state `CircuitBreaker` (`CLOSED`, `OPEN`, `HALF_OPEN`), rolling window failure rate, per-call execution timeout, fallback handlers, and exponential backoff retry engine (`retry`, `withRetry`) with randomized jitter and transient error detection.
|
|
71
|
+
25. **[Structured Cloud Logging & Distributed Tracing](.agents/LOGGING.md)** — Zero-dependency cloud logger (`core/logger`), GCP Cloud Logging, AWS CloudWatch, automatic trace propagation (`x-cloud-trace-context`, `x-amzn-trace-id`, `traceparent`), sensitive key redaction, and `req.logger` child context.
|
|
72
|
+
26. **[Stateless Scale-Out & Database Pool Management](.agents/SCALE_OUT.md)** — Distributed Redis session store (`createRedisSessionStore`), Redis session tracker (`createRedisSessionTracker`), zero-dependency RESP client, serverless DB connection pool optimizer (`normalizeServerlessPoolConfig`), and scale-out preflight audits (`deploy:check`).
|
|
73
|
+
27. **[Cloud Secrets Management](.agents/SECRETS.md)** — Zero-dependency Google Cloud Secret Manager & AWS Secrets Manager/SSM integration (`core/secrets`), in-memory caching with TTL, dot-notation JSON subkeys, process.env hydration, and `webspresso secrets:pull`.
|
|
74
|
+
28. **[Cloud Metrics & Distributed Tracing](.agents/METRICS.md)** — Zero-dependency Prometheus exposition format (`/metrics`), JSON telemetry (`/metrics.json`), HTTP latency histograms, Node.js event loop/memory/pool/cache collectors, and W3C `traceparent` & `x-trace-id` propagation (`core/metrics`).
|
|
75
|
+
29. **[Cloud Migration Jobs & Zero-Downtime Database Deploy](.agents/MIGRATION_JOBS.md)** — Dedicated pre-deploy migration jobs for Cloud Run, AWS ECS, and Kubernetes (`webspresso add:migration-job`), connection retries, and stale lock auto-healing (`webspresso db:migrate --safe`).
|
|
76
|
+
30. **[Native Zero-Dependency Rate Limiting Engine](.agents/RATE_LIMIT.md)** — Framework-agnostic rate limiter (`core/rate-limit`), sliding window in-memory & Redis stores, RFC 6585 standard headers (`RateLimit-*`, `Retry-After`), Express & Hono dual support, and `rateLimit({ window, limit })`.
|
|
77
|
+
31. **[Feature Flags & Canary Traffic Splitter](.agents/FLAGS.md)** — Zero-dependency feature flag and canary rollout engine (`core/flags`), deterministic FNV-1a bucketing, targeting rules (users, roles, email domains), A/B variants, SSR template helpers (`fsy.hasFeature`), and declarative API guards (`defineApi({ flag })`).
|
|
65
78
|
|
|
66
79
|
---
|
|
67
80
|
|
package/.agents/CLI.md
CHANGED
|
@@ -332,12 +332,17 @@ npx webspresso add:docker --force
|
|
|
332
332
|
|
|
333
333
|
## 17. Production Deployment Preflight Check (`deploy:check` / `check:deploy`)
|
|
334
334
|
|
|
335
|
-
Run comprehensive pre-flight verification before deploying to Fly.io, Railway, Render, VPS, or Kubernetes:
|
|
335
|
+
Run comprehensive pre-flight verification before deploying to Google Cloud Run, AWS (App Runner / ECS), Cloudflare Workers, Fly.io, Railway, Render, VPS, or Kubernetes:
|
|
336
336
|
|
|
337
337
|
```bash
|
|
338
|
-
# Run production preflight verification
|
|
338
|
+
# Run production preflight verification (auto-detects target platform)
|
|
339
339
|
npx webspresso deploy:check
|
|
340
340
|
|
|
341
|
+
# Target a specific cloud platform explicitly (cloudrun, aws, cloudflare, docker)
|
|
342
|
+
npx webspresso deploy:check --platform cloudrun
|
|
343
|
+
npx webspresso deploy:check --platform aws
|
|
344
|
+
npx webspresso deploy:check -p cloudflare
|
|
345
|
+
|
|
341
346
|
# Run against a specific environment (.env.staging or .env.production)
|
|
342
347
|
npx webspresso deploy:check --env staging
|
|
343
348
|
|
|
@@ -349,11 +354,17 @@ npx webspresso deploy:check --json
|
|
|
349
354
|
```
|
|
350
355
|
|
|
351
356
|
### Audited Verification Areas:
|
|
352
|
-
1. **
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
+
1. **Platform-Specific Cloud Preflight**:
|
|
358
|
+
- **Google Cloud Run**: Ephemeral SQLite/local upload warnings, SIGTERM timeout alignment (<= 10000ms), `.gcloudignore` secrets exclusion (`.env`), `cloudbuild.yaml` pipeline, and dynamic `PORT` binding.
|
|
359
|
+
- **AWS (App Runner / ECS Fargate)**: Ephemeral storage audits, `apprunner.yaml` / `ecs-task-definition.json` validity, and CloudWatch `awslogs` log driver configuration.
|
|
360
|
+
- **Cloudflare Workers**: `wrangler.toml` configuration and `nodejs_compat` compatibility flag verification.
|
|
361
|
+
- **Stateless Scale-Out**: Distributed Redis sessions and serverless connection pool limits.
|
|
362
|
+
2. **Secrets & Cryptography**: Ensures `SESSION_SECRET` or `APP_KEY` is set, >= 32 characters, and not using weak placeholder defaults.
|
|
363
|
+
3. **Git & Leak Prevention**: Verifies `.env` and local database files are excluded in `.gitignore`.
|
|
364
|
+
4. **Container Hardening**: Ensures `Dockerfile` runs as a non-root `USER`, configures a `HEALTHCHECK`, and uses multi-stage caching.
|
|
365
|
+
5. **Database & Migrations**: Audits for pending unapplied migrations and warns against ephemeral SQLite storage.
|
|
366
|
+
6. **Server Optimizations**: Validates HTTP compression (`compression: true`), graceful shutdown, and health check endpoints.
|
|
367
|
+
7. **Actionable Remediations**: Emits precise, single-command remediation steps for every warning and error detected.
|
|
357
368
|
|
|
358
369
|
---
|
|
359
370
|
|
|
@@ -435,3 +446,204 @@ npx webspresso make:mail Welcome
|
|
|
435
446
|
# Outputs: emails/WelcomeEmail.js
|
|
436
447
|
```
|
|
437
448
|
|
|
449
|
+
---
|
|
450
|
+
|
|
451
|
+
## 21. Google Cloud Run Deployment (`add:cloudrun` / `cloudrun`)
|
|
452
|
+
|
|
453
|
+
Generate production-ready Google Cloud Run configuration with Google Cloud Build CI/CD pipeline, `.gcloudignore`, and one-command deployment script:
|
|
454
|
+
|
|
455
|
+
```bash
|
|
456
|
+
# Generate cloudbuild.yaml, .gcloudignore, deploy-cloudrun.sh, and Dockerfile
|
|
457
|
+
npx webspresso add:cloudrun
|
|
458
|
+
|
|
459
|
+
# Customize region, container resources, scaling limits, and Cloud SQL
|
|
460
|
+
npx webspresso add:cloudrun --region europe-west1 --memory 1Gi --cpu 2 --min-instances 1 --max-instances 20 --cloud-sql my-project:europe-west1:my-db
|
|
461
|
+
|
|
462
|
+
# Overwrite existing files
|
|
463
|
+
npx webspresso add:cloudrun --force
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
### Generated Artifacts:
|
|
467
|
+
- **`cloudbuild.yaml`**: Multi-stage Docker image build, Google Artifact Registry push, and zero-downtime serverless Cloud Run deployment with Gen2 execution environment.
|
|
468
|
+
- **`.gcloudignore`**: Prevents `.env`, SQLite files, node_modules, and test directories from entering the Cloud Build upload context.
|
|
469
|
+
- **`deploy-cloudrun.sh`**: Executable bash script for direct zero-friction deployment (`chmod +x`).
|
|
470
|
+
- **`package.json` Scripts**: Adds `gcp:deploy` and `gcp:build`.
|
|
471
|
+
|
|
472
|
+
---
|
|
473
|
+
|
|
474
|
+
## 22. AWS App Runner & ECS Fargate Deployment (`add:aws` / `aws`)
|
|
475
|
+
|
|
476
|
+
Generate production-ready AWS deployment configuration supporting both AWS App Runner and Amazon ECS (Fargate):
|
|
477
|
+
|
|
478
|
+
```bash
|
|
479
|
+
# Generate apprunner.yaml, ecs-task-definition.json, deploy-aws.sh, and Dockerfile
|
|
480
|
+
npx webspresso add:aws
|
|
481
|
+
|
|
482
|
+
# Customize region, CPU, and memory allocations
|
|
483
|
+
npx webspresso add:aws --region us-east-1 --cpu "1 vCPU" --memory "2 GB"
|
|
484
|
+
|
|
485
|
+
# Overwrite existing files
|
|
486
|
+
npx webspresso add:aws --force
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
### Generated Artifacts:
|
|
490
|
+
- **`apprunner.yaml`**: AWS App Runner configuration with build commands (`npm ci --omit=dev`), start command, and port network mapping.
|
|
491
|
+
- **`ecs-task-definition.json`**: Production ECS Fargate task definition with `awsvpc` network mode, container resource constraints, CloudWatch `awslogs`, and native `/healthz` health checks.
|
|
492
|
+
- **`deploy-aws.sh`**: Automated deployment shell script that verifies AWS credentials, creates Amazon ECR repositories, builds and pushes Docker images, and updates services.
|
|
493
|
+
- **`package.json` Scripts**: Adds `aws:deploy`.
|
|
494
|
+
|
|
495
|
+
---
|
|
496
|
+
|
|
497
|
+
## 23. Cloudflare Workers Deployment (`add:cloudflare` / `cloudflare`)
|
|
498
|
+
|
|
499
|
+
Generate serverless edge deployment files for Cloudflare Workers with D1, KV, and Queues support:
|
|
500
|
+
|
|
501
|
+
```bash
|
|
502
|
+
# Generate wrangler.toml and worker.js
|
|
503
|
+
npx webspresso add:cloudflare
|
|
504
|
+
|
|
505
|
+
# Include Cloudflare D1, KV, and Queues
|
|
506
|
+
npx webspresso add:cloudflare --d1 --kv --queue
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
---
|
|
510
|
+
|
|
511
|
+
## 24. Cloud Static Asset Sync (`assets:sync` / `assets-sync`)
|
|
512
|
+
|
|
513
|
+
Upload and synchronize compiled static assets (`public/assets/`, `dist/`, fonts, images) to S3, Cloudflare R2, or Google Cloud Storage with immutable CDN cache headers:
|
|
514
|
+
|
|
515
|
+
```bash
|
|
516
|
+
# Preview files to be uploaded without transmitting data
|
|
517
|
+
npx webspresso assets:sync --dry-run
|
|
518
|
+
|
|
519
|
+
# Sync assets to an AWS S3 bucket
|
|
520
|
+
npx webspresso assets:sync --bucket my-cdn-bucket --provider s3
|
|
521
|
+
|
|
522
|
+
# Sync assets to Google Cloud Storage
|
|
523
|
+
npx webspresso assets:sync --bucket my-gcs-bucket --provider gcs --prefix assets
|
|
524
|
+
|
|
525
|
+
# Override directory or custom Cache-Control header
|
|
526
|
+
npx webspresso assets:sync --dir public --cache-control "public, max-age=604800"
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
---
|
|
530
|
+
|
|
531
|
+
## 25. Cloud Secrets Synchronization (`secrets:pull` / `pull:secrets`)
|
|
532
|
+
|
|
533
|
+
Pull cloud secrets from Google Cloud Secret Manager or AWS Secrets Manager into a local `.env.local` file for secure local development:
|
|
534
|
+
|
|
535
|
+
```bash
|
|
536
|
+
# Auto-detect cloud platform and pull expected secrets
|
|
537
|
+
npx webspresso secrets:pull
|
|
538
|
+
|
|
539
|
+
# Explicitly pull specific secrets from Google Cloud Secret Manager
|
|
540
|
+
npx webspresso secrets:pull --platform cloudrun -s SESSION_SECRET DATABASE_URL
|
|
541
|
+
|
|
542
|
+
# Explicitly pull from AWS Secrets Manager
|
|
543
|
+
npx webspresso secrets:pull --platform aws -s SESSION_SECRET DATABASE_URL
|
|
544
|
+
|
|
545
|
+
# Unpack a JSON secret bundle to stdout (dry run)
|
|
546
|
+
npx webspresso secrets:pull --bundle prod/app/config --dry-run
|
|
547
|
+
|
|
548
|
+
# Output secrets in JSON format
|
|
549
|
+
npx webspresso secrets:pull -s API_KEY DB_PASS --format json -o secrets.json
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
---
|
|
553
|
+
|
|
554
|
+
## 26. Zero-Secret CI/CD Pipeline Generator (`add:ci` / `add:workflow`)
|
|
555
|
+
|
|
556
|
+
Scaffold automated, keyless GitHub Actions workflows (Google WIF, AWS IAM OIDC, Cloudflare) and GitLab CI pipelines with integrated test suites and `webspresso deploy:check --strict` gating:
|
|
557
|
+
|
|
558
|
+
```bash
|
|
559
|
+
# Auto-detect cloud platform and scaffold GitHub Actions workflows
|
|
560
|
+
npx webspresso add:ci
|
|
561
|
+
|
|
562
|
+
# Explicitly target Google Cloud Run (Workload Identity Federation)
|
|
563
|
+
npx webspresso add:ci --platform cloudrun
|
|
564
|
+
|
|
565
|
+
# Explicitly target AWS (IAM OIDC Role & Amazon ECR)
|
|
566
|
+
npx webspresso add:ci --platform aws
|
|
567
|
+
|
|
568
|
+
# Explicitly target Cloudflare Workers
|
|
569
|
+
npx webspresso add:ci --platform cloudflare
|
|
570
|
+
|
|
571
|
+
# Scaffold all cloud workflows alongside a GitLab CI pipeline (.gitlab-ci.yml)
|
|
572
|
+
npx webspresso add:ci --platform all --gitlab
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
---
|
|
576
|
+
|
|
577
|
+
## 27. Type-Safe Frontend Client Generator (`client:generate` / `client:gen`)
|
|
578
|
+
|
|
579
|
+
Generate an end-to-end typed TypeScript HTTP client from your Webspresso API routes and Zod schemas for React, Next.js, Vite, Vue, Svelte, or mobile apps:
|
|
580
|
+
|
|
581
|
+
```bash
|
|
582
|
+
# Generate client into src/client.ts (or .webspresso/client.ts)
|
|
583
|
+
npx webspresso client:generate
|
|
584
|
+
|
|
585
|
+
# Specify custom output path and base URL
|
|
586
|
+
npx webspresso client:generate --out src/api-client.ts --base-url https://api.myapp.com
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
---
|
|
590
|
+
|
|
591
|
+
## 28. DB Studio Live Telemetry & SQL Runner (`db:studio`)
|
|
592
|
+
|
|
593
|
+
Launch an interactive database inspector, SQL query runner, and real-time system monitoring dashboard:
|
|
594
|
+
|
|
595
|
+
```bash
|
|
596
|
+
# Launch DB Studio on default port 4567
|
|
597
|
+
npx webspresso db:studio
|
|
598
|
+
|
|
599
|
+
# Custom port without opening default browser
|
|
600
|
+
npx webspresso db:studio --port 5000 --no-open
|
|
601
|
+
```
|
|
602
|
+
- Schema inspection & CRUD operations for all database tables.
|
|
603
|
+
- Real-time SSE Live Telemetry streaming Node.js memory metrics (RSS, Heap), Knex connection pool utilization, background queues, and circuit breaker trip states.
|
|
604
|
+
- Interactive Circuit Breaker manual reset (`POST /_studio/api/breakers/:name/reset`).
|
|
605
|
+
|
|
606
|
+
---
|
|
607
|
+
|
|
608
|
+
## 29. Interactive REPL Console (`console` / `c`)
|
|
609
|
+
|
|
610
|
+
Launch an interactive Node.js REPL session with auto-injected framework context (database, repositories, services, queues, events, feature flags, and cache):
|
|
611
|
+
|
|
612
|
+
```bash
|
|
613
|
+
# Start interactive console
|
|
614
|
+
npx webspresso console
|
|
615
|
+
# Alias:
|
|
616
|
+
npx webspresso c
|
|
617
|
+
|
|
618
|
+
# Evaluate a single expression and print output (with top-level await support)
|
|
619
|
+
npx webspresso console -e "await Note.find({ status: 'published' })"
|
|
620
|
+
|
|
621
|
+
# Target specific environment or config file
|
|
622
|
+
npx webspresso console -E production -c config/db.js
|
|
623
|
+
|
|
624
|
+
# Disable command history persistence or banner
|
|
625
|
+
npx webspresso console --no-history --no-banner
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
### Context & Shortcuts Injected:
|
|
629
|
+
- `db`: Knex / ORM database instance.
|
|
630
|
+
- `<ModelName>` (e.g. `Note`, `User`): Direct repository shortcuts (`await Note.find()`, `await Note.findById(1)`).
|
|
631
|
+
- `models`: Dictionary of all loaded model repositories (`models.Note`).
|
|
632
|
+
- `services`: ServiceRegistry instance.
|
|
633
|
+
- `service(name, input)`: Direct helper to invoke domain services (`await service('notes.create', payload)`).
|
|
634
|
+
- `queue`: Background QueueDispatcher (`await queue.dispatch('email.send', data)`).
|
|
635
|
+
- `events`: Decoupled EventDispatcher (`events.emit('order.created', order)`).
|
|
636
|
+
- `flags`: FeatureFlagManager (`flags.isEnabled('new_checkout', { user })`).
|
|
637
|
+
- `cache`: TaggedLruCache instance (`await cache.get('key')`).
|
|
638
|
+
- `mailer`: Framework mailer service.
|
|
639
|
+
- `reload()`: Hot-reloads all models and services from filesystem without exiting the REPL.
|
|
640
|
+
- `help()`: Displays interactive help menu with all available objects and commands.
|
|
641
|
+
|
|
642
|
+
### Custom REPL Dot-Commands:
|
|
643
|
+
- `.models`: List all loaded models, table names, and available repository methods.
|
|
644
|
+
- `.services`: List all registered business services and descriptions.
|
|
645
|
+
- `.routes`: Scan and list all API endpoints and SSR pages.
|
|
646
|
+
- `.flags`: List active feature flags and targeting rules.
|
|
647
|
+
- `.reload`: Hot-reload models and services from filesystem.
|
|
648
|
+
- `.exit`: Exit the console session (`Ctrl+D`).
|
|
649
|
+
|
package/.agents/FLAGS.md
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Feature Flags & Canary Traffic Splitter (`core/flags`)
|
|
2
|
+
|
|
3
|
+
Webspresso features an enterprise-grade, zero-dependency **Feature Flag & Canary Traffic Splitting Engine** in `core/flags/`. It enables gradual rollouts, multivariate A/B testing, user/role/domain targeting, and runtime overrides across Nunjucks SSR templates, API endpoints (`defineApi`), service layers, and Edge/Hono adapters.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🎯 Key Capabilities
|
|
8
|
+
|
|
9
|
+
1. **Sub-Microsecond Deterministic Bucketing**:
|
|
10
|
+
- FNV-1a 32-bit hashing algorithm (`getBucket`) maps user identifiers to deterministic integer buckets `0 .. 99` across distributed nodes without network calls.
|
|
11
|
+
2. **Flexible Targeting Rules**:
|
|
12
|
+
- **Boolean Toggles**: `enabled: true | false`.
|
|
13
|
+
- **Canary Percentage Rollout**: `rollout: 10` (10% of traffic, consistent per user).
|
|
14
|
+
- **Targeted Whitelists**: `users: ['user_123', 'admin@corp.com']`.
|
|
15
|
+
- **Role-Based Targeting**: `roles: ['admin', 'beta_tester']`.
|
|
16
|
+
- **Email Domain Targeting**: `emailDomains: ['acme.com']`.
|
|
17
|
+
- **Multivariate A/B Variants**: `variants: [{ name: 'blue_button', weight: 50 }, { name: 'green_button', weight: 50 }]`.
|
|
18
|
+
- **Custom Predicates**: `condition: (ctx) => ctx.plan === 'enterprise'`.
|
|
19
|
+
3. **Multi-Layer Integration**:
|
|
20
|
+
- **Express / Hono Middleware**: Automatically injects `req.flags`, `req.hasFeature()`, and `req.getVariant()`.
|
|
21
|
+
- **Nunjucks SSR Templates**: Access via `{{ fsy.hasFeature('new_ui') }}` and `{{ fsy.flag('theme') }}`.
|
|
22
|
+
- **Declarative API Route Guard**: `defineApi({ flag: 'beta_feature' })` returns HTTP 404 (or configured status) if disabled.
|
|
23
|
+
- **Environment Variable Overrides**: Instant runtime overrides via `FEATURE_<FLAG_NAME>=true|false`.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## 🚀 Quick Start
|
|
28
|
+
|
|
29
|
+
### 1. Application Configuration
|
|
30
|
+
|
|
31
|
+
```javascript
|
|
32
|
+
const { createApp } = require('webspresso');
|
|
33
|
+
|
|
34
|
+
const app = createApp({
|
|
35
|
+
flags: {
|
|
36
|
+
// 1. Simple toggle
|
|
37
|
+
dark_mode: true,
|
|
38
|
+
|
|
39
|
+
// 2. 20% Canary rollout
|
|
40
|
+
new_checkout: {
|
|
41
|
+
rollout: 20,
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
// 3. User & Role targeting
|
|
45
|
+
ai_assistant: {
|
|
46
|
+
roles: ['pro', 'admin'],
|
|
47
|
+
users: ['vip_client_1'],
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
// 4. Multivariate A/B Test
|
|
51
|
+
pricing_page_test: {
|
|
52
|
+
variants: [
|
|
53
|
+
{ name: 'control', weight: 50 },
|
|
54
|
+
{ name: 'discount_banner', weight: 50 },
|
|
55
|
+
],
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### 2. Nunjucks SSR Templates (`pages/*.njk`)
|
|
62
|
+
|
|
63
|
+
```nunjucks
|
|
64
|
+
{% if fsy.hasFeature('new_checkout') %}
|
|
65
|
+
{% include "components/new-checkout.njk" %}
|
|
66
|
+
{% else %}
|
|
67
|
+
{% include "components/legacy-checkout.njk" %}
|
|
68
|
+
{% endif %}
|
|
69
|
+
|
|
70
|
+
{% if fsy.flag('pricing_page_test') == 'discount_banner' %}
|
|
71
|
+
<div class="banner">Special 20% Discount Applied!</div>
|
|
72
|
+
{% endif %}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### 3. File-Based API Endpoints (`pages/api/...`)
|
|
76
|
+
|
|
77
|
+
```javascript
|
|
78
|
+
const { defineApi } = require('webspresso');
|
|
79
|
+
|
|
80
|
+
module.exports = defineApi({
|
|
81
|
+
// Automatically blocks request with HTTP 404 if flag is disabled
|
|
82
|
+
flag: 'ai_assistant',
|
|
83
|
+
handler: async (req, res, ctx) => {
|
|
84
|
+
// Also accessible inside ctx or req
|
|
85
|
+
const isVip = ctx.hasFeature('vip_access');
|
|
86
|
+
return res.json({ success: true, isVip });
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### 4. Route Guard Middleware
|
|
92
|
+
|
|
93
|
+
```javascript
|
|
94
|
+
const { createFeatureFlagManager } = require('webspresso');
|
|
95
|
+
|
|
96
|
+
const flags = createFeatureFlagManager({
|
|
97
|
+
flags: { secret_admin: { roles: ['admin'] } },
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// Use as standalone route middleware
|
|
101
|
+
app.get('/admin/secret', flags.guard('secret_admin', { statusCode: 403 }), (req, res) => {
|
|
102
|
+
res.send('Welcome, Admin!');
|
|
103
|
+
});
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## ⚙️ Environment Overrides
|
|
109
|
+
|
|
110
|
+
Flags can be overridden at runtime without code deployment or restart:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
# Enable flag
|
|
114
|
+
FEATURE_NEW_CHECKOUT=true npm start
|
|
115
|
+
|
|
116
|
+
# Disable flag
|
|
117
|
+
FEATURE_NEW_CHECKOUT=false npm start
|
|
118
|
+
```
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Structured Cloud Logging & Distributed Tracing Guide
|
|
2
|
+
|
|
3
|
+
Webspresso features an enterprise, zero-dependency Structured Cloud Logger (`core/logger`) designed specifically for serverless and containerized cloud platforms (Google Cloud Run, AWS App Runner, ECS Fargate, Lambda, Kubernetes).
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🎯 Key Capabilities
|
|
8
|
+
|
|
9
|
+
1. **Native Cloud Platform Detection & Formatting**:
|
|
10
|
+
- **Google Cloud Platform (`format: 'gcp'`)**: Automatically emits JSON payloads with Google Cloud Logging `severity` levels (`DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`), `logging.googleapis.com/trace`, `logging.googleapis.com/spanId`, and RFC `httpRequest` metadata.
|
|
11
|
+
- **Amazon Web Services (`format: 'aws'`)**: Formats logs with `level`, `requestId`, `xrayTraceId`, and `http` metrics compatible with AWS CloudWatch and AWS X-Ray.
|
|
12
|
+
- **Standard JSON (`format: 'json'`)**: Compact, structured single-line JSON stream for Docker, Kubernetes, and Datadog.
|
|
13
|
+
- **Development Pretty (`format: 'pretty'`)**: Fast, ANSI color-coded console logs for local developer happiness.
|
|
14
|
+
2. **Distributed Tracing Context Propagation**:
|
|
15
|
+
- Parses incoming request trace headers automatically:
|
|
16
|
+
- `x-cloud-trace-context` (Google Cloud Trace)
|
|
17
|
+
- `x-amzn-trace-id` (AWS X-Ray)
|
|
18
|
+
- `traceparent` (W3C standard)
|
|
19
|
+
- `x-request-id` / `x-correlation-id`
|
|
20
|
+
- Injects trace ID and span ID into every log statement emitted during the request lifecycle.
|
|
21
|
+
3. **Automatic Child Logger on Requests (`req.logger`)**:
|
|
22
|
+
- In API route handlers and SSR page loaders, `req.logger` is pre-bound to the request's trace ID and contextual metadata.
|
|
23
|
+
- Automatically logs HTTP access on request finish (`res.on('finish')`) with latency, status code, remote IP, and user-agent.
|
|
24
|
+
4. **Deep Sensitive Key Redaction**:
|
|
25
|
+
- Recursively masks sensitive fields (`password`, `token`, `secret`, `authorization`, `cookie`, `apiKey`) to prevent accidental credential leakage in cloud log aggregation systems.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 🚀 Usage in Application Code
|
|
30
|
+
|
|
31
|
+
### In API Route Handlers
|
|
32
|
+
|
|
33
|
+
```javascript
|
|
34
|
+
// pages/api/orders.post.js
|
|
35
|
+
const { defineApi } = require('webspresso');
|
|
36
|
+
|
|
37
|
+
module.exports = defineApi({
|
|
38
|
+
schema: ({ z }) => ({
|
|
39
|
+
body: z.object({ amount: z.number().positive(), customerId: z.string() }),
|
|
40
|
+
}),
|
|
41
|
+
handler: async (req, res) => {
|
|
42
|
+
// req.logger is automatically bound to the request's trace ID
|
|
43
|
+
req.logger.info('Processing order checkout', {
|
|
44
|
+
customerId: req.input.body.customerId,
|
|
45
|
+
amount: req.input.body.amount,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
try {
|
|
49
|
+
const order = await req.service('order.create', req.input.body);
|
|
50
|
+
req.logger.info('Order processed successfully', { orderId: order.id });
|
|
51
|
+
return res.status(201).json(order);
|
|
52
|
+
} catch (err) {
|
|
53
|
+
req.logger.error('Failed to process order', { error: err.message });
|
|
54
|
+
throw err;
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Standalone Logger & Child Context
|
|
61
|
+
|
|
62
|
+
```javascript
|
|
63
|
+
const { createLogger } = require('webspresso');
|
|
64
|
+
|
|
65
|
+
const logger = createLogger({
|
|
66
|
+
format: 'auto', // 'gcp' | 'aws' | 'json' | 'pretty'
|
|
67
|
+
level: 'info',
|
|
68
|
+
defaultMeta: { service: 'payment-worker' },
|
|
69
|
+
project: 'my-gcp-project', // optional GCP project ID
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
logger.info('Worker started');
|
|
73
|
+
|
|
74
|
+
// Create contextual child logger
|
|
75
|
+
const jobLogger = logger.child({ jobId: 'job_42' });
|
|
76
|
+
jobLogger.info('Task execution started');
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Configuration in `createApp`
|
|
80
|
+
|
|
81
|
+
```javascript
|
|
82
|
+
const { createApp } = require('webspresso');
|
|
83
|
+
|
|
84
|
+
const app = createApp({
|
|
85
|
+
pagesDir: './pages',
|
|
86
|
+
logger: {
|
|
87
|
+
format: 'auto', // Auto-detected from K_SERVICE, AWS_EXECUTION_ENV, or NODE_ENV
|
|
88
|
+
level: 'info',
|
|
89
|
+
exclude: ['/healthz', '/readyz', '/favicon.ico'],
|
|
90
|
+
redact: ['password', 'secret', 'token'],
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
```
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# Cloud Metrics & Distributed Tracing Guide
|
|
2
|
+
|
|
3
|
+
Webspresso provides an enterprise-grade, zero-dependency Cloud Metrics & Distributed Tracing engine (`core/metrics`) delivering Prometheus exposition format (`/metrics`), JSON telemetry (`/metrics.json`), HTTP latency histograms, and W3C/GCP/AWS distributed tracing header propagation.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🎯 Key Capabilities
|
|
8
|
+
|
|
9
|
+
1. **Prometheus-Compatible Exposition Format**:
|
|
10
|
+
- Zero external dependencies (no `prom-client` or OpenTelemetry npm packages required).
|
|
11
|
+
- Generates compliant `text/plain; version=0.0.4; charset=utf-8` output directly consumable by Prometheus, Grafana Agent, Google Cloud Managed Service for Prometheus, AWS CloudWatch Container Insights, and Datadog.
|
|
12
|
+
- Dual-format exposition: `/metrics` for Prometheus scraping and `/metrics.json` (or `Accept: application/json`) for programmatic inspection or lightweight dashboards.
|
|
13
|
+
2. **Distributed Tracing & W3C Propagation**:
|
|
14
|
+
- Parses incoming tracing headers automatically (`traceparent`, `x-cloud-trace-context`, `x-amzn-trace-id`, `x-request-id`).
|
|
15
|
+
- Automatically injects `x-trace-id` and W3C `traceparent` (`00-${traceId}-${spanId}-01`) onto outgoing HTTP response headers.
|
|
16
|
+
- Attaches `req.traceId` and `req.spanId` to the incoming request object for seamless correlation with `req.logger`.
|
|
17
|
+
3. **Core HTTP Request Telemetry**:
|
|
18
|
+
- `webspresso_http_requests_total{method, route, status}`: Counter for all processed HTTP requests.
|
|
19
|
+
- `webspresso_http_request_duration_seconds{method, route}`: Latency histogram with cumulative buckets, `_sum`, and `_count`.
|
|
20
|
+
- `webspresso_http_active_requests`: Gauge tracking in-flight concurrent requests.
|
|
21
|
+
- **Noise-free scraping**: Internal scrape calls to `/metrics`, `/metrics.json`, and `/healthz` are excluded from HTTP latency counters to prevent self-polluting metrics graphs.
|
|
22
|
+
4. **Automated Node.js & Framework Collectors**:
|
|
23
|
+
- **Process & Memory**: `process_uptime_seconds`, `nodejs_heap_size_used_bytes`, `nodejs_heap_size_total_bytes`, `process_resident_memory_bytes`, `nodejs_external_memory_bytes`.
|
|
24
|
+
- **CPU**: `process_cpu_user_seconds_total`, `process_cpu_system_seconds_total`.
|
|
25
|
+
- **Event Loop Lag**: `nodejs_eventloop_lag_seconds{quantile="0.50|0.99|max"}` via native `perf_hooks.monitorEventLoopDelay`.
|
|
26
|
+
- **Database Connection Pool**: `webspresso_db_pool_size`, `webspresso_db_pool_used`, `webspresso_db_pool_available` (Knex pool).
|
|
27
|
+
- **In-Memory Cache**: `webspresso_cache_entries`, `webspresso_cache_bytes` (LRU cache).
|
|
28
|
+
- **Circuit Breakers**: `webspresso_circuit_breaker_state{name}` (0=closed, 1=half-open, 2=open), `webspresso_circuit_breaker_failures_total{name}`.
|
|
29
|
+
5. **Security & Gating**:
|
|
30
|
+
- Protect metrics endpoints with bearer token authentication (`auth: 'secret-token'`).
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 🚀 Configuration & Enabling Metrics
|
|
35
|
+
|
|
36
|
+
### 1. Enabling via `createApp`
|
|
37
|
+
|
|
38
|
+
```javascript
|
|
39
|
+
const { createApp } = require('webspresso');
|
|
40
|
+
|
|
41
|
+
const { app } = createApp({
|
|
42
|
+
pagesDir: './pages',
|
|
43
|
+
metrics: {
|
|
44
|
+
enabled: true, // default: true if metrics option is passed
|
|
45
|
+
path: '/metrics', // default: '/metrics'
|
|
46
|
+
collectDefault: true, // default: true (system, memory, pool, cache, lag)
|
|
47
|
+
traceHeader: true, // default: true (x-trace-id, traceparent)
|
|
48
|
+
auth: process.env.METRICS_TOKEN || null, // Optional Bearer token protection
|
|
49
|
+
buckets: [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10],
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Or enable with shorthand:
|
|
55
|
+
|
|
56
|
+
```javascript
|
|
57
|
+
createApp({
|
|
58
|
+
metrics: true, // mounts /metrics and /metrics.json with defaults
|
|
59
|
+
});
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 📊 Custom Application Metrics
|
|
65
|
+
|
|
66
|
+
Application routes, services, and plugins can register and record custom domain metrics via `app.metrics` or `req.metrics`:
|
|
67
|
+
|
|
68
|
+
```javascript
|
|
69
|
+
// Register a custom counter
|
|
70
|
+
const orderCounter = app.metrics.counter(
|
|
71
|
+
'shop_orders_placed_total',
|
|
72
|
+
'Total number of completed customer orders'
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
// Register a custom gauge
|
|
76
|
+
const activeUsersGauge = app.metrics.gauge(
|
|
77
|
+
'shop_active_cart_sessions',
|
|
78
|
+
'Number of carts currently active'
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
// In an API handler
|
|
82
|
+
// pages/api/checkout.post.js
|
|
83
|
+
module.exports = defineApi({
|
|
84
|
+
handler: async (req, res) => {
|
|
85
|
+
const order = await req.service('order.create', req.body);
|
|
86
|
+
|
|
87
|
+
// Increment domain metric
|
|
88
|
+
orderCounter.inc({ plan: order.plan, currency: order.currency }, 1);
|
|
89
|
+
|
|
90
|
+
return res.status(201).json(order);
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## 🛡️ Standalone Registry Usage
|
|
98
|
+
|
|
99
|
+
```javascript
|
|
100
|
+
const { createMetricsRegistry } = require('webspresso');
|
|
101
|
+
|
|
102
|
+
const registry = createMetricsRegistry();
|
|
103
|
+
|
|
104
|
+
const counter = registry.counter('jobs_processed_total', 'Jobs processed by worker');
|
|
105
|
+
counter.inc({ queue: 'email', status: 'success' }, 1);
|
|
106
|
+
|
|
107
|
+
const histogram = registry.histogram('job_execution_duration_seconds', 'Job execution duration', [0.1, 0.5, 1, 5]);
|
|
108
|
+
histogram.observe({ queue: 'email' }, 0.24);
|
|
109
|
+
|
|
110
|
+
// Format output
|
|
111
|
+
console.log(registry.formatPrometheus());
|
|
112
|
+
console.log(JSON.stringify(registry.formatJson(), null, 2));
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## 📈 Prometheus Scrape Configuration (`prometheus.yml`)
|
|
118
|
+
|
|
119
|
+
```yaml
|
|
120
|
+
scrape_configs:
|
|
121
|
+
- job_name: 'webspresso-app'
|
|
122
|
+
scrape_interval: 15s
|
|
123
|
+
metrics_path: '/metrics'
|
|
124
|
+
bearer_token: 'YOUR_METRICS_TOKEN' # if auth is enabled
|
|
125
|
+
static_configs:
|
|
126
|
+
- targets: ['localhost:3000']
|
|
127
|
+
```
|