workspai 0.43.0
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/LICENSE +21 -0
- package/README.md +624 -0
- package/contracts/agent-customization-pack.v1.json +229 -0
- package/contracts/analyze-last-run.v1.json +106 -0
- package/contracts/artifact-remediation-plan.v1.json +163 -0
- package/contracts/backend-import-stack-parity.snapshot.json +37 -0
- package/contracts/cli-log-event.v1.json +51 -0
- package/contracts/create-planner-capabilities.v1.json +251 -0
- package/contracts/doctor-project-evidence.v1.json +304 -0
- package/contracts/doctor-remediation-plan.v1.json +496 -0
- package/contracts/doctor-workspace-evidence.v1.json +315 -0
- package/contracts/extension-cli-compatibility.v1.json +26 -0
- package/contracts/infra-stack.v1.json +305 -0
- package/contracts/module-layout.v1.json +34 -0
- package/contracts/module-support.v1.json +20 -0
- package/contracts/pipeline-last-run.v1.json +80 -0
- package/contracts/release-readiness.v1.json +60 -0
- package/contracts/runtime-command-surface.v1.json +364 -0
- package/contracts/workspace-intelligence/agent-action-outcome.v1.json +38 -0
- package/contracts/workspace-intelligence/blocker-resolution.v1.json +65 -0
- package/contracts/workspace-intelligence/doctor-fix-result.v1.json +44 -0
- package/contracts/workspace-intelligence/fact-freshness.v1.json +58 -0
- package/contracts/workspace-intelligence/studio-blocker-handoff.v1.json +115 -0
- package/contracts/workspace-intelligence/workspace-context.v1.json +142 -0
- package/contracts/workspace-intelligence/workspace-contract-verify.v1.json +51 -0
- package/contracts/workspace-intelligence/workspace-dependency-graph.v1.json +152 -0
- package/contracts/workspace-intelligence/workspace-explain.v1.json +31 -0
- package/contracts/workspace-intelligence/workspace-impact.v1.json +114 -0
- package/contracts/workspace-intelligence/workspace-intelligence-history.v1.json +40 -0
- package/contracts/workspace-intelligence/workspace-model-diff.v1.json +105 -0
- package/contracts/workspace-intelligence/workspace-model-snapshot.v1.json +36 -0
- package/contracts/workspace-intelligence/workspace-model.v1.json +135 -0
- package/contracts/workspace-intelligence/workspace-operational-skill.v1.json +37 -0
- package/contracts/workspace-intelligence/workspace-skills-index.v1.json +27 -0
- package/contracts/workspace-intelligence/workspace-verify.v1.json +213 -0
- package/contracts/workspace-registry.v1.json +83 -0
- package/contracts/workspace-run-last.v1.json +112 -0
- package/data/modules-embeddings.json +16953 -0
- package/dist/analyze-5BU4QIPK.js +1 -0
- package/dist/artifact-remediation-plan-5GJWPPRS.js +3 -0
- package/dist/autopilot-release-QYUOVB26.js +1 -0
- package/dist/chunk-22DT744Z.js +1 -0
- package/dist/chunk-2E6WGUN6.js +1 -0
- package/dist/chunk-2FIX2MDC.js +1 -0
- package/dist/chunk-3KXW53QI.js +1 -0
- package/dist/chunk-3ZK2GU7C.js +1 -0
- package/dist/chunk-4KUIFXHM.js +5 -0
- package/dist/chunk-54XJNLYC.js +13 -0
- package/dist/chunk-5SWNSJGW.js +1 -0
- package/dist/chunk-5XATWNME.js +1 -0
- package/dist/chunk-753LOKFZ.js +2 -0
- package/dist/chunk-7YHK5NM3.js +2 -0
- package/dist/chunk-A5FBGRJA.js +1 -0
- package/dist/chunk-AAKUNWPR.js +78 -0
- package/dist/chunk-AFSZHLQT.js +1 -0
- package/dist/chunk-AQ4XZZC6.js +1 -0
- package/dist/chunk-CVTCPPEF.js +1 -0
- package/dist/chunk-DNAY5ALC.js +1 -0
- package/dist/chunk-EWYYLJQY.js +2 -0
- package/dist/chunk-GSWPGELT.js +2 -0
- package/dist/chunk-GZTYAEWX.js +1 -0
- package/dist/chunk-HTYMXMQM.js +1 -0
- package/dist/chunk-IBJEQHJR.js +205 -0
- package/dist/chunk-ICGWHIMK.js +1 -0
- package/dist/chunk-JEI6BTZI.js +3 -0
- package/dist/chunk-JHC6SCJC.js +1 -0
- package/dist/chunk-LO4C4VXR.js +4 -0
- package/dist/chunk-LPZFK3Y6.js +920 -0
- package/dist/chunk-LUP4U6EE.js +1 -0
- package/dist/chunk-LYC6AIF2.js +2 -0
- package/dist/chunk-LZQNVH7D.js +1 -0
- package/dist/chunk-NAAQMSO3.js +1 -0
- package/dist/chunk-NFUXULIF.js +1 -0
- package/dist/chunk-OCGZNSOE.js +1 -0
- package/dist/chunk-OJEWQO3Z.js +33 -0
- package/dist/chunk-OL64GWQC.js +9 -0
- package/dist/chunk-PI5KUXDA.js +7 -0
- package/dist/chunk-PYCJWW4B.js +1 -0
- package/dist/chunk-RE773WOX.js +13 -0
- package/dist/chunk-RO73VVHW.js +2 -0
- package/dist/chunk-S5KTATOU.js +1 -0
- package/dist/chunk-SI3AQKIP.js +1 -0
- package/dist/chunk-T3GJ7YVG.js +1 -0
- package/dist/chunk-T6OR6YOI.js +2 -0
- package/dist/chunk-VRDF2J46.js +653 -0
- package/dist/chunk-VZKSNUEE.js +2 -0
- package/dist/chunk-WU4ZRRA5.js +4 -0
- package/dist/chunk-XEJD4KCV.js +33 -0
- package/dist/chunk-XZGVNGRB.js +1 -0
- package/dist/chunk-Y45WZR5N.js +5 -0
- package/dist/create-WRZO4HK2.js +1 -0
- package/dist/demo-kit-AJ5LIM5G.js +149 -0
- package/dist/doctor-MF3M3FS3.js +1 -0
- package/dist/dotnet-webapi-clean-IPY3MCGQ.js +425 -0
- package/dist/gofiber-standard-N5N3QGH3.js +1397 -0
- package/dist/gogin-standard-LAWQTBWL.js +1459 -0
- package/dist/imported-projects-registry-FOIE27WT.js +1 -0
- package/dist/index.d.ts +141 -0
- package/dist/index.js +454 -0
- package/dist/managed-agent-markers-AXUM75OE.js +8 -0
- package/dist/module-layout-NZ43RSC5.js +1 -0
- package/dist/pipeline-QCUHFWDY.js +5 -0
- package/dist/platform-capabilities-XAVU4HSM.js +1 -0
- package/dist/pythonRapidkitExec-3L3XJBSY.js +1 -0
- package/dist/springboot-standard-OZYF7ZM7.js +697 -0
- package/dist/workspace-PR6VZRBG.js +1 -0
- package/dist/workspace-agent-sync-KTYF3HQR.js +1 -0
- package/dist/workspace-archive-GCZNI44O.js +3 -0
- package/dist/workspace-context-QUTOP2XV.js +1 -0
- package/dist/workspace-contract-XUGMCUSQ.js +1 -0
- package/dist/workspace-explain-JEONEGZZ.js +1 -0
- package/dist/workspace-explain-contract-DNS2YEL7.js +1 -0
- package/dist/workspace-feedback-R6H4UFZB.js +1 -0
- package/dist/workspace-foundation-KGSV4E6D.js +1 -0
- package/dist/workspace-graph-2A5THUCI.js +1 -0
- package/dist/workspace-history-CGCK2DJI.js +1 -0
- package/dist/workspace-intelligence-QJGVL37U.js +1 -0
- package/dist/workspace-marker-SMBC3Z2Q.js +1 -0
- package/dist/workspace-mcp-serve-AK4MYEHQ.js +3 -0
- package/dist/workspace-model-PNXXOGPO.js +1 -0
- package/dist/workspace-python-engine-state-MTWIIZPY.js +2 -0
- package/dist/workspace-registry-summary-RUJE6RPH.js +1 -0
- package/dist/workspace-run-Y7YMUIHX.js +1 -0
- package/dist/workspace-verify-WSDUUTR5.js +1 -0
- package/dist/workspace-watch-AGPOJ74Q.js +1 -0
- package/docs/AI_DYNAMIC_INTEGRATION.md +440 -0
- package/docs/AI_EXAMPLES.md +419 -0
- package/docs/AI_FEATURES.md +460 -0
- package/docs/AI_QUICKSTART.md +245 -0
- package/docs/DEVELOPMENT.md +90 -0
- package/docs/From Code to Shared Understanding.png +0 -0
- package/docs/OPEN_SOURCE_USER_SCENARIOS.md +170 -0
- package/docs/OPTIMIZATION_GUIDE.md +504 -0
- package/docs/PACKAGE_MANAGER_POLICY.md +25 -0
- package/docs/README.md +125 -0
- package/docs/SECURITY.md +63 -0
- package/docs/SETUP.md +107 -0
- package/docs/UTILITIES.md +221 -0
- package/docs/WORKSPACE_MARKER_SPEC.md +276 -0
- package/docs/ci-workflows.md +59 -0
- package/docs/commands-reference.md +172 -0
- package/docs/config-file-guide.md +299 -0
- package/docs/contracts/ARTIFACT_CATALOG.md +333 -0
- package/docs/contracts/CLI_LOG_EVENT_STREAM.md +123 -0
- package/docs/contracts/COMMAND_OWNERSHIP_MATRIX.md +138 -0
- package/docs/contracts/NAMING_AND_COEXISTENCE.md +60 -0
- package/docs/contracts/README.md +86 -0
- package/docs/contracts/RUNTIME_ACCEPTANCE_MATRIX.md +98 -0
- package/docs/contracts/RUNTIME_SUPPORT_MATRIX.md +75 -0
- package/docs/contracts/rapidkit-cli-contracts.json +239 -0
- package/docs/create-planner-capabilities.md +81 -0
- package/docs/doctor-command.md +467 -0
- package/docs/examples/ci-agent-grounding.yml +65 -0
- package/docs/from-code-to-shared-understanding.md +45 -0
- package/docs/governance-policy.enterprise.example.json +40 -0
- package/docs/mirror-config.enterprise.example.json +60 -0
- package/docs/policies.workspace.example.yml +23 -0
- package/docs/workspace-operations.md +160 -0
- package/docs/workspace-run.md +104 -0
- package/package.json +179 -0
- package/rapidkit.config.example.cjs +62 -0
- package/scripts/check-agent-customization-drift.mjs +78 -0
- package/scripts/check-cli-resolution.cjs +72 -0
- package/scripts/enforce-package-manager.cjs +10 -0
- package/scripts/enterprise-package-smoke.mjs +463 -0
- package/scripts/prepack-enterprise.mjs +43 -0
- package/templates/generator.js +179 -0
- package/templates/kits/fastapi-ddd/README.md.j2 +117 -0
- package/templates/kits/fastapi-ddd/common/env.example.j2 +10 -0
- package/templates/kits/fastapi-ddd/env.example.j2 +1 -0
- package/templates/kits/fastapi-ddd/pyproject.toml.j2 +64 -0
- package/templates/kits/fastapi-ddd/src/__init__.py.j2 +3 -0
- package/templates/kits/fastapi-ddd/src/app/__init__.py.j2 +11 -0
- package/templates/kits/fastapi-ddd/src/app/application/__init__.py.j2 +5 -0
- package/templates/kits/fastapi-ddd/src/app/application/interfaces.py.j2 +43 -0
- package/templates/kits/fastapi-ddd/src/app/application/use_cases/__init__.py.j2 +6 -0
- package/templates/kits/fastapi-ddd/src/app/application/use_cases/health.py.j2 +14 -0
- package/templates/kits/fastapi-ddd/src/app/application/use_cases/notes.py.j2 +24 -0
- package/templates/kits/fastapi-ddd/src/app/config/__init__.py.j2 +16 -0
- package/templates/kits/fastapi-ddd/src/app/domain/__init__.py.j2 +3 -0
- package/templates/kits/fastapi-ddd/src/app/domain/models/__init__.py.j2 +6 -0
- package/templates/kits/fastapi-ddd/src/app/domain/models/health.py.j2 +16 -0
- package/templates/kits/fastapi-ddd/src/app/domain/models/note.py.j2 +27 -0
- package/templates/kits/fastapi-ddd/src/app/infrastructure/__init__.py.j2 +5 -0
- package/templates/kits/fastapi-ddd/src/app/infrastructure/repositories/__init__.py.j2 +6 -0
- package/templates/kits/fastapi-ddd/src/app/infrastructure/repositories/health.py.j2 +17 -0
- package/templates/kits/fastapi-ddd/src/app/infrastructure/repositories/notes.py.j2 +28 -0
- package/templates/kits/fastapi-ddd/src/app/main.py.j2 +61 -0
- package/templates/kits/fastapi-ddd/src/app/presentation/__init__.py.j2 +3 -0
- package/templates/kits/fastapi-ddd/src/app/presentation/api/__init__.py.j2 +5 -0
- package/templates/kits/fastapi-ddd/src/app/presentation/api/dependencies/__init__.py.j2 +19 -0
- package/templates/kits/fastapi-ddd/src/app/presentation/api/router.py.j2 +10 -0
- package/templates/kits/fastapi-ddd/src/app/presentation/api/routes/__init__.py.j2 +5 -0
- package/templates/kits/fastapi-ddd/src/app/presentation/api/routes/health.py.j2 +27 -0
- package/templates/kits/fastapi-ddd/src/app/presentation/api/routes/notes.py.j2 +50 -0
- package/templates/kits/fastapi-ddd/src/app/shared/__init__.py.j2 +5 -0
- package/templates/kits/fastapi-ddd/src/app/shared/result.py.j2 +28 -0
- package/templates/kits/fastapi-ddd/src/cli.py.j2 +170 -0
- package/templates/kits/fastapi-ddd/src/main.py.j2 +35 -0
- package/templates/kits/fastapi-ddd/src/modules/__init__.py.j2 +3 -0
- package/templates/kits/fastapi-ddd/src/routing/__init__.py.j2 +13 -0
- package/templates/kits/fastapi-ddd/src/routing/health.py.j2 +7 -0
- package/templates/kits/fastapi-ddd/src/routing/notes.py.j2 +7 -0
- package/templates/kits/fastapi-ddd/tests/__init__.py.j2 +1 -0
- package/templates/kits/fastapi-ddd/tests/test_app_factory.py.j2 +22 -0
- package/templates/kits/fastapi-ddd/tests/test_health.py.j2 +17 -0
- package/templates/kits/fastapi-ddd/tests/test_notes.py.j2 +27 -0
- package/templates/kits/fastapi-standard/README.md.j2 +140 -0
- package/templates/kits/fastapi-standard/common/env.example.j2 +10 -0
- package/templates/kits/fastapi-standard/env.example.j2 +1 -0
- package/templates/kits/fastapi-standard/pyproject.toml.j2 +64 -0
- package/templates/kits/fastapi-standard/src/__init__.py.j2 +3 -0
- package/templates/kits/fastapi-standard/src/cli.py.j2 +171 -0
- package/templates/kits/fastapi-standard/src/main.py.j2 +66 -0
- package/templates/kits/fastapi-standard/src/modules/__init__.py.j2 +3 -0
- package/templates/kits/fastapi-standard/src/routing/__init__.py.j2 +16 -0
- package/templates/kits/fastapi-standard/src/routing/examples.py.j2 +71 -0
- package/templates/kits/fastapi-standard/src/routing/health.py.j2 +22 -0
- package/templates/kits/fastapi-standard/tests/__init__.py.j2 +1 -0
- package/templates/kits/fastapi-standard/tests/test_examples.py.j2 +29 -0
- package/templates/kits/fastapi-standard/tests/test_health.py.j2 +17 -0
- package/templates/kits/nestjs-standard/Dockerfile.j2 +41 -0
- package/templates/kits/nestjs-standard/README.md.j2 +134 -0
- package/templates/kits/nestjs-standard/docker-compose.yml.j2 +94 -0
- package/templates/kits/nestjs-standard/docs/README.md.j2 +15 -0
- package/templates/kits/nestjs-standard/env.example.j2 +18 -0
- package/templates/kits/nestjs-standard/eslint.config.cjs.j2 +9 -0
- package/templates/kits/nestjs-standard/jest.config.ts.j2 +28 -0
- package/templates/kits/nestjs-standard/nest-cli.json.j2 +10 -0
- package/templates/kits/nestjs-standard/package.json.j2 +101 -0
- package/templates/kits/nestjs-standard/src/app.controller.ts.j2 +14 -0
- package/templates/kits/nestjs-standard/src/app.module.ts.j2 +26 -0
- package/templates/kits/nestjs-standard/src/app.service.ts.j2 +16 -0
- package/templates/kits/nestjs-standard/src/auth/auth.controller.ts.j2 +20 -0
- package/templates/kits/nestjs-standard/src/auth/auth.module.ts.j2 +13 -0
- package/templates/kits/nestjs-standard/src/auth/auth.service.ts.j2 +6 -0
- package/templates/kits/nestjs-standard/src/auth/entities/token.entity.ts.j2 +3 -0
- package/templates/kits/nestjs-standard/src/auth/entities/user.entity.ts.j2 +3 -0
- package/templates/kits/nestjs-standard/src/auth/entities/webauthn.entity.ts.j2 +3 -0
- package/templates/kits/nestjs-standard/src/config/configuration.ts.j2 +85 -0
- package/templates/kits/nestjs-standard/src/config/index.ts.j2 +2 -0
- package/templates/kits/nestjs-standard/src/config/validation.ts.j2 +21 -0
- package/templates/kits/nestjs-standard/src/examples/dto/create-note.dto.ts.j2 +11 -0
- package/templates/kits/nestjs-standard/src/examples/examples.controller.ts.j2 +24 -0
- package/templates/kits/nestjs-standard/src/examples/examples.module.ts.j2 +10 -0
- package/templates/kits/nestjs-standard/src/examples/examples.service.ts.j2 +33 -0
- package/templates/kits/nestjs-standard/src/main.ts.j2 +53 -0
- package/templates/kits/nestjs-standard/src/modules/index.ts.j2 +25 -0
- package/templates/kits/nestjs-standard/test/app.controller.spec.ts.j2 +24 -0
- package/templates/kits/nestjs-standard/test/app.e2e-spec.ts.j2 +60 -0
- package/templates/kits/nestjs-standard/test/examples.controller.spec.ts.j2 +28 -0
- package/templates/kits/nestjs-standard/test/jest-e2e.json.j2 +15 -0
- package/templates/kits/nestjs-standard/tsconfig.build.json.j2 +12 -0
- package/templates/kits/nestjs-standard/tsconfig.json.j2 +26 -0
- package/workspai.config.example.cjs +62 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# {{ project_name | replace('-', ' ') | title }}
|
|
2
|
+
|
|
3
|
+
A production-ready NestJS 11 application generated with Workspai's **NestJS Standard Kit**.
|
|
4
|
+
|
|
5
|
+
## Getting Started
|
|
6
|
+
> Recommended Node version: `{{ node_version }}` (`.nvmrc` and `.node-version` are included for your toolchain)
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
# Bootstrap dependencies using the local CLI
|
|
10
|
+
npx workspai init # use make init if you prefer a Make target
|
|
11
|
+
|
|
12
|
+
# Copy env templates + install hooks/tooling
|
|
13
|
+
./bootstrap.sh
|
|
14
|
+
|
|
15
|
+
# Run the dev server with hot reload
|
|
16
|
+
make dev
|
|
17
|
+
|
|
18
|
+
# Or rely on the project-local RapidKit Core helpers:
|
|
19
|
+
npx workspai dev
|
|
20
|
+
|
|
21
|
+
# Run linting, type-checking, tests, and supply-chain audits
|
|
22
|
+
make lint
|
|
23
|
+
make typecheck
|
|
24
|
+
make test
|
|
25
|
+
make audit
|
|
26
|
+
npx workspai lint
|
|
27
|
+
npx workspai test
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
> Use `npx workspai init` (or `make init`) whenever dependencies change. Pass `SKIP_INIT=1` (for example `SKIP_INIT=1 make install`) if you only need to refresh tooling/hooks.
|
|
31
|
+
|
|
32
|
+
> Lockfiles are generated automatically during scaffolding. Set `RAPIDKIT_SKIP_LOCKS=1` (or `RAPIDKIT_GENERATE_LOCKS=0`) before running `workspai create` if you need to skip this step.
|
|
33
|
+
|
|
34
|
+
> Need the project-local RapidKit Core command list? Run `rapidkit --help` when RapidKit Core is installed, or use `npx workspai --help` for workspace-level commands.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Quick start (developer)
|
|
39
|
+
|
|
40
|
+
1. `npx workspai init` bootstraps dependencies through the project-aware launcher and enforces lockfile flags for your chosen package manager.
|
|
41
|
+
2. `make init` remains available as an alias to `npx workspai init` when you prefer Make targets.
|
|
42
|
+
3. `./bootstrap.sh` copies `.env.example` to `.env` (when missing) and runs `SKIP_INIT=1 make install` so git hooks and tooling stay current without reinstalling packages.
|
|
43
|
+
4. `make dev` wraps `{{ package_manager if package_manager != 'pnpm' else 'pnpm' }} run start:dev` and centralizes env loading; use it for day-to-day development.
|
|
44
|
+
5. `make lint`, `make typecheck`, and `make test` proxy to the underlying package scripts or `tsc` so local changes match CI expectations.
|
|
45
|
+
6. `make audit` executes `{{ package_manager }}`'s security audit (falling back to dev dependencies if needed) to surface vulnerable packages early.
|
|
46
|
+
|
|
47
|
+
`make install` is still available; it re-runs `npx workspai init` unless you set `SKIP_INIT=1`, so prefer `SKIP_INIT=1 make install` when you only need to refresh tooling.
|
|
48
|
+
|
|
49
|
+
Prefer `npx workspai dev`, `npx workspai test`, or `npx workspai lint` when you want the project-aware launcher to auto-detect the right runtime; they call into the same project scripts wrapped by the Make targets.
|
|
50
|
+
|
|
51
|
+
Prefer the Make targets for consistency, but you can always fall back to native commands if needed:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
{{ package_manager if package_manager != 'pnpm' else 'pnpm' }} install
|
|
55
|
+
{{ package_manager if package_manager != 'pnpm' else 'pnpm' }} run start:dev
|
|
56
|
+
{{ package_manager if package_manager != 'pnpm' else 'pnpm' }} test
|
|
57
|
+
{{ package_manager if package_manager != 'pnpm' else 'pnpm' }} run lint
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
If you see engine compatibility errors during `{{ package_manager }} install`, update your Node runtime (nvm/asdf) or use the provided Dockerfile which targets `NODE_VERSION={{ node_version }}`.
|
|
61
|
+
|
|
62
|
+
## Features
|
|
63
|
+
|
|
64
|
+
- Modular architecture with configuration hooks
|
|
65
|
+
- {{ 'JWT/OAuth2 authentication scaffolding' if auth_type != 'none' else 'Authentication ready' }}
|
|
66
|
+
- Optional integrations:
|
|
67
|
+
- Database: {{ database_type | default('postgresql') | upper }}
|
|
68
|
+
- Redis caching
|
|
69
|
+
- Structured logging and telemetry
|
|
70
|
+
- Monitoring endpoints
|
|
71
|
+
|
|
72
|
+
## Project Structure
|
|
73
|
+
|
|
74
|
+
- `src/main.ts` – Bootstraps the NestJS application
|
|
75
|
+
- `src/app.module.ts` – Core application module with injection anchors
|
|
76
|
+
- `src/modules/` – Container for RapidKit Core modules (`// <<<inject:module-init>>>`)
|
|
77
|
+
- `src/config/` – Centralized configuration module and validation
|
|
78
|
+
- `test/` – Unit and e2e testing with Jest
|
|
79
|
+
|
|
80
|
+
## RapidKit Core Modules
|
|
81
|
+
|
|
82
|
+
Install additional modules as needed:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
rapidkit add module settings
|
|
86
|
+
rapidkit add module logging
|
|
87
|
+
rapidkit add module auth
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
<!-- <<<inject:module-snippet>>> -->
|
|
91
|
+
|
|
92
|
+
## Example feature
|
|
93
|
+
|
|
94
|
+
The scaffold ships with an `ExamplesModule` exposing a tiny in-memory notes API under `/examples/notes`. Use it to validate request/response flows or to demo module structure before wiring real adapters:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
# Create a note
|
|
98
|
+
curl -s -X POST http://localhost:3000/examples/notes \
|
|
99
|
+
-H "Content-Type: application/json" \
|
|
100
|
+
-d '{"title":"hello","body":"documented via Workspai"}'
|
|
101
|
+
|
|
102
|
+
# List all notes
|
|
103
|
+
curl -s http://localhost:3000/examples/notes | jq
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Replace the in-memory service with a proper repository once you add RapidKit Core database modules.
|
|
107
|
+
|
|
108
|
+
## Docker
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
docker-compose up -d
|
|
112
|
+
docker-compose down
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Scripts
|
|
116
|
+
|
|
117
|
+
| Command | Description |
|
|
118
|
+
| --- | --- |
|
|
119
|
+
| `{{ package_manager if package_manager != 'pnpm' else 'pnpm' }} start:dev` | Start development server |
|
|
120
|
+
| `{{ package_manager if package_manager != 'pnpm' else 'pnpm' }} build` | Build production artifacts |
|
|
121
|
+
| `{{ package_manager if package_manager != 'pnpm' else 'pnpm' }} test` | Run tests |
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
Generated by Workspai.
|
|
125
|
+
|
|
126
|
+
## 📄 License
|
|
127
|
+
|
|
128
|
+
This project is licensed under the **{{ license }}** License - see the `LICENSE` file included at the project root for details.
|
|
129
|
+
|
|
130
|
+
## 🔒 Security & secrets
|
|
131
|
+
|
|
132
|
+
- Copy `.env.example` to `.env` and populate secrets (`SECRET_KEY`, DB credentials, etc.) before deploying.
|
|
133
|
+
- **Do not** commit real secrets or `.env` to git; `.gitignore` already contains `.env` to protect accidental commits.
|
|
134
|
+
- For production, tighten CORS and allowed hosts rather than using wildcard settings provided for convenience in dev.
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
version: '3.8'
|
|
2
|
+
services:
|
|
3
|
+
app:
|
|
4
|
+
build: .
|
|
5
|
+
container_name: {{ project_name | replace('_', '-') }}
|
|
6
|
+
ports:
|
|
7
|
+
- "8000:8000"
|
|
8
|
+
env_file:
|
|
9
|
+
- .env
|
|
10
|
+
environment:
|
|
11
|
+
NODE_ENV: development
|
|
12
|
+
command: {{ ('pnpm' if package_manager == 'pnpm' else (package_manager if package_manager in ['npm', 'yarn'] else 'npm')) }} run start:dev
|
|
13
|
+
volumes:
|
|
14
|
+
- .:/usr/src/app
|
|
15
|
+
- /usr/src/app/node_modules
|
|
16
|
+
{% if database_type in ['postgresql', 'mysql', 'mongodb'] or include_caching %}
|
|
17
|
+
depends_on:
|
|
18
|
+
{% if database_type == 'postgresql' %}
|
|
19
|
+
postgres:
|
|
20
|
+
condition: service_healthy
|
|
21
|
+
{% elif database_type == 'mysql' %}
|
|
22
|
+
mysql:
|
|
23
|
+
condition: service_healthy
|
|
24
|
+
{% elif database_type == 'mongodb' %}
|
|
25
|
+
mongodb:
|
|
26
|
+
condition: service_started
|
|
27
|
+
{% endif %}
|
|
28
|
+
{% if include_caching %}
|
|
29
|
+
redis:
|
|
30
|
+
condition: service_started
|
|
31
|
+
{% endif %}
|
|
32
|
+
{% endif %}
|
|
33
|
+
healthcheck:
|
|
34
|
+
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
|
|
35
|
+
interval: 10s
|
|
36
|
+
timeout: 3s
|
|
37
|
+
retries: 5
|
|
38
|
+
|
|
39
|
+
{% if database_type == 'postgresql' %}
|
|
40
|
+
postgres:
|
|
41
|
+
image: postgres:15-alpine
|
|
42
|
+
environment:
|
|
43
|
+
POSTGRES_USER: user
|
|
44
|
+
POSTGRES_PASSWORD: password
|
|
45
|
+
POSTGRES_DB: {{ project_name | replace('-', '_') }}
|
|
46
|
+
ports:
|
|
47
|
+
- "5432:5432"
|
|
48
|
+
healthcheck:
|
|
49
|
+
test: ["CMD-SHELL", "pg_isready -U user"]
|
|
50
|
+
interval: 10s
|
|
51
|
+
timeout: 3s
|
|
52
|
+
retries: 5
|
|
53
|
+
|
|
54
|
+
{% elif database_type == 'mysql' %}
|
|
55
|
+
mysql:
|
|
56
|
+
image: mysql:8.1
|
|
57
|
+
environment:
|
|
58
|
+
MYSQL_ROOT_PASSWORD: password
|
|
59
|
+
MYSQL_DATABASE: {{ project_name | replace('-', '_') }}
|
|
60
|
+
MYSQL_USER: user
|
|
61
|
+
MYSQL_PASSWORD: password
|
|
62
|
+
ports:
|
|
63
|
+
- "3306:3306"
|
|
64
|
+
healthcheck:
|
|
65
|
+
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
|
|
66
|
+
interval: 10s
|
|
67
|
+
timeout: 5s
|
|
68
|
+
retries: 5
|
|
69
|
+
|
|
70
|
+
{% elif database_type == 'mongodb' %}
|
|
71
|
+
mongodb:
|
|
72
|
+
image: mongo:7
|
|
73
|
+
ports:
|
|
74
|
+
- "27017:27017"
|
|
75
|
+
volumes:
|
|
76
|
+
- mongodb_data:/data/db
|
|
77
|
+
|
|
78
|
+
{% endif %}
|
|
79
|
+
{% if include_caching %}
|
|
80
|
+
redis:
|
|
81
|
+
image: redis:7-alpine
|
|
82
|
+
ports:
|
|
83
|
+
- "6379:6379"
|
|
84
|
+
command: ["redis-server", "--appendonly", "yes"]
|
|
85
|
+
healthcheck:
|
|
86
|
+
test: ["CMD", "redis-cli", "ping"]
|
|
87
|
+
interval: 10s
|
|
88
|
+
timeout: 3s
|
|
89
|
+
retries: 5
|
|
90
|
+
{% endif %}
|
|
91
|
+
|
|
92
|
+
volumes:
|
|
93
|
+
mongodb_data:
|
|
94
|
+
driver: local
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Documentation
|
|
2
|
+
|
|
3
|
+
Welcome to the documentation portal for **{{ project_name | replace('-', ' ') | title }}**.
|
|
4
|
+
|
|
5
|
+
## Contents
|
|
6
|
+
|
|
7
|
+
- `architecture/` – System design documents and decisions
|
|
8
|
+
- `operations/` – Runbooks and operational procedures
|
|
9
|
+
- `modules/` – Documentation for installed RapidKit Core modules
|
|
10
|
+
|
|
11
|
+
## Getting Started
|
|
12
|
+
|
|
13
|
+
1. Update this documentation with project-specific details.
|
|
14
|
+
2. Document any architectural decisions in `architecture/adr-000-template.md`.
|
|
15
|
+
3. Keep module docs in sync with installed RapidKit Core modules.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Application
|
|
2
|
+
APP_NAME={{ project_name | upper }}
|
|
3
|
+
PORT=8000
|
|
4
|
+
HOST=0.0.0.0
|
|
5
|
+
NODE_ENV=development
|
|
6
|
+
|
|
7
|
+
# Security
|
|
8
|
+
JWT_SECRET="{{ '' | generate_secret(48) }}"
|
|
9
|
+
JWT_EXPIRATION=1h
|
|
10
|
+
|
|
11
|
+
# Database
|
|
12
|
+
DATABASE_URL=postgresql://user:password@localhost:5432/{{ project_name | replace('-', '_') }}
|
|
13
|
+
|
|
14
|
+
# Redis
|
|
15
|
+
REDIS_HOST=localhost
|
|
16
|
+
REDIS_PORT=6379
|
|
17
|
+
|
|
18
|
+
# <<<inject:module-env>>>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Config } from 'jest';
|
|
2
|
+
|
|
3
|
+
const config: Config = {
|
|
4
|
+
moduleFileExtensions: ['js', 'json', 'ts'],
|
|
5
|
+
rootDir: '.',
|
|
6
|
+
testEnvironment: 'node',
|
|
7
|
+
testRegex: '.*\\.spec.ts$',
|
|
8
|
+
testPathIgnorePatterns: [
|
|
9
|
+
'/node_modules/',
|
|
10
|
+
'/.workspai/vendor/',
|
|
11
|
+
'/.workspai/snapshots/',
|
|
12
|
+
'/.rapidkit/vendor/',
|
|
13
|
+
'/.rapidkit/snapshots/',
|
|
14
|
+
],
|
|
15
|
+
transform: {
|
|
16
|
+
'^.+\\.ts$': 'ts-jest',
|
|
17
|
+
},
|
|
18
|
+
collectCoverageFrom: ['src/**/*.{ts,tsx}', '!src/**/*.module.ts'],
|
|
19
|
+
coverageDirectory: './coverage',
|
|
20
|
+
moduleNameMapper: {
|
|
21
|
+
'^@config/(.*)$': '<rootDir>/src/config/$1',
|
|
22
|
+
'^@modules/(.*)$': '<rootDir>/src/modules/$1',
|
|
23
|
+
'^@shared/(.*)$': '<rootDir>/src/shared/$1',
|
|
24
|
+
},
|
|
25
|
+
setupFiles: ['dotenv/config'],
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export default config;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{ project_name | replace('_', '-') | lower }}",
|
|
3
|
+
"version": "{{ app_version | default('1.0.0') }}",
|
|
4
|
+
"description": "{{ description | default('NestJS application generated with Workspai') }}",
|
|
5
|
+
"license": "{{ license | default('Apache-2.0') }}",
|
|
6
|
+
"author": "{{ author }}",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">={{ node_version }}"
|
|
9
|
+
},
|
|
10
|
+
"private": true,
|
|
11
|
+
"scripts": {
|
|
12
|
+
"start": "node dist/main",
|
|
13
|
+
"dev": "nest start --watch",
|
|
14
|
+
"start:dev": "nest start --watch",
|
|
15
|
+
"start:debug": "nest start --debug --watch",
|
|
16
|
+
"start:prod": "node dist/main",
|
|
17
|
+
"build": "nest build",
|
|
18
|
+
"lint": "eslint \"{src,test}/**/*.ts\" --fix",
|
|
19
|
+
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
|
|
20
|
+
"test": "jest",
|
|
21
|
+
"test:watch": "jest --watch",
|
|
22
|
+
"test:cov": "jest --coverage",
|
|
23
|
+
"test:e2e": "jest --config ./test/jest-e2e.json"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@nestjs/common": "^11.1.10",
|
|
27
|
+
"@nestjs/config": "^4.0.2",
|
|
28
|
+
"@nestjs/core": "^11.1.10",
|
|
29
|
+
"@nestjs/platform-express": "^11.1.10",
|
|
30
|
+
"@nestjs/swagger": "^11.2.3",
|
|
31
|
+
"class-transformer": "^0.5.1",
|
|
32
|
+
"class-validator": "^0.14.3",
|
|
33
|
+
"reflect-metadata": "^0.2.2",
|
|
34
|
+
"rxjs": "^7.8.2",
|
|
35
|
+
"helmet": "^8.1.0",
|
|
36
|
+
"compression": "^1.8.1",
|
|
37
|
+
"winston": "^3.19.0",
|
|
38
|
+
"zod": "^4.2.1",
|
|
39
|
+
"joi": "^18.0.2",
|
|
40
|
+
"@nestjs/terminus": "^11.0.0",
|
|
41
|
+
{% if database_type in ['postgresql', 'mysql'] %}
|
|
42
|
+
"@nestjs/typeorm": "^11.0.0",
|
|
43
|
+
"typeorm": "^0.3.28",
|
|
44
|
+
{% if database_type == 'postgresql' %}
|
|
45
|
+
"pg": "^8.16.3",
|
|
46
|
+
{% elif database_type == 'mysql' %}
|
|
47
|
+
"mysql2": "^3.15.3",
|
|
48
|
+
{% endif %}
|
|
49
|
+
{% elif database_type == 'mongodb' %}
|
|
50
|
+
"@nestjs/mongoose": "^11.0.3",
|
|
51
|
+
"mongoose": "^9.0.1",
|
|
52
|
+
{% endif %}
|
|
53
|
+
{% if include_caching %}
|
|
54
|
+
"@nestjs/cache-manager": "^3.0.1",
|
|
55
|
+
"cache-manager": "^7.2.6",
|
|
56
|
+
"cache-manager-redis-store": "^3.0.1",
|
|
57
|
+
"ioredis": "^5.8.2",
|
|
58
|
+
{% endif %}
|
|
59
|
+
{% if include_monitoring %}
|
|
60
|
+
"prom-client": "^15.1.3",
|
|
61
|
+
{% endif %}
|
|
62
|
+
{% if auth_type in ['jwt', 'oauth2'] %}
|
|
63
|
+
"@nestjs/jwt": "^11.0.2",
|
|
64
|
+
"@nestjs/passport": "^11.0.5",
|
|
65
|
+
"bcrypt": "^6.0.0",
|
|
66
|
+
"passport": "^0.7.0",
|
|
67
|
+
"passport-jwt": "^4.0.1",
|
|
68
|
+
{% endif %}
|
|
69
|
+
"dotenv": "^17.2.3"
|
|
70
|
+
},
|
|
71
|
+
"devDependencies": {
|
|
72
|
+
"@eslint/eslintrc": "^3.3.3",
|
|
73
|
+
"@nestjs/cli": "^11.0.14",
|
|
74
|
+
"@nestjs/schematics": "^11.0.9",
|
|
75
|
+
"@nestjs/testing": "^11.1.10",
|
|
76
|
+
"@types/compression": "^1.8.1",
|
|
77
|
+
"@types/express": "^5.0.6",
|
|
78
|
+
"@types/jest": "^30.0.0",
|
|
79
|
+
"@types/node": "^18.19.130",
|
|
80
|
+
"@types/supertest": "^6.0.3",
|
|
81
|
+
"@typescript-eslint/eslint-plugin": "^8.50.1",
|
|
82
|
+
"@typescript-eslint/parser": "^8.50.1",
|
|
83
|
+
"eslint": "^9.39.2",
|
|
84
|
+
"eslint-config-prettier": "^10.1.8",
|
|
85
|
+
"eslint-plugin-import": "^2.32.0",
|
|
86
|
+
"eslint-plugin-prettier": "^5.5.4",
|
|
87
|
+
"jest": "^30.2.0",
|
|
88
|
+
"prettier": "^3.7.4",
|
|
89
|
+
"source-map-support": "^0.5.21",
|
|
90
|
+
"supertest": "^7.1.4",
|
|
91
|
+
"ts-jest": "^29.4.6",
|
|
92
|
+
"ts-loader": "^9.5.4",
|
|
93
|
+
"ts-node": "^10.9.2",
|
|
94
|
+
"tsconfig-paths": "^4.2.0",
|
|
95
|
+
"typescript": "^5.9.3"
|
|
96
|
+
},
|
|
97
|
+
"overrides": {
|
|
98
|
+
"cross-spawn": "7.0.5",
|
|
99
|
+
"glob": "10.5.0"
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Controller, Get } from '@nestjs/common';
|
|
2
|
+
import { AppService } from './app.service';
|
|
3
|
+
|
|
4
|
+
@Controller()
|
|
5
|
+
export class AppController {
|
|
6
|
+
constructor(private readonly appService: AppService) {}
|
|
7
|
+
|
|
8
|
+
@Get('health')
|
|
9
|
+
getHealth() {
|
|
10
|
+
return this.appService.getHealth();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// <<<inject:controller-routes>>>
|
|
14
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Module } from '@nestjs/common';
|
|
2
|
+
import { ConfigModule } from '@nestjs/config';
|
|
3
|
+
|
|
4
|
+
import { settingsConfiguration } from './config/configuration';
|
|
5
|
+
import { validationSchema } from './config/validation';
|
|
6
|
+
import { AppController } from './app.controller';
|
|
7
|
+
import { AppService } from './app.service';
|
|
8
|
+
import { rapidkitModules } from './modules';
|
|
9
|
+
import { ExamplesModule } from './examples/examples.module';
|
|
10
|
+
// <<<inject:module-imports>>>
|
|
11
|
+
|
|
12
|
+
@Module({
|
|
13
|
+
imports: [
|
|
14
|
+
ConfigModule.forRoot({
|
|
15
|
+
isGlobal: true,
|
|
16
|
+
load: [settingsConfiguration],
|
|
17
|
+
validationSchema,
|
|
18
|
+
expandVariables: true,
|
|
19
|
+
}),
|
|
20
|
+
ExamplesModule,
|
|
21
|
+
...rapidkitModules,
|
|
22
|
+
],
|
|
23
|
+
controllers: [AppController],
|
|
24
|
+
providers: [AppService],
|
|
25
|
+
})
|
|
26
|
+
export class AppModule {}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
|
|
3
|
+
@Injectable()
|
|
4
|
+
export class AppService {
|
|
5
|
+
getHealth() {
|
|
6
|
+
return {
|
|
7
|
+
status: 'ok',
|
|
8
|
+
timestamp: new Date().toISOString(),
|
|
9
|
+
version: process.env.APP_VERSION ?? process.env.npm_package_version ?? '0.0.1',
|
|
10
|
+
uptime: process.uptime(),
|
|
11
|
+
module: process.env.APP_MODULE ?? process.env.APP_NAME ?? process.env.npm_package_name ?? 'app',
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// <<<inject:service-methods>>>
|
|
16
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Controller } from '@nestjs/common';
|
|
2
|
+
|
|
3
|
+
@Controller('auth')
|
|
4
|
+
export class AuthController {
|
|
5
|
+
// <<<inject:auth-login>>>
|
|
6
|
+
// <<<inject:auth-signup>>>
|
|
7
|
+
// <<<inject:auth-refresh>>>
|
|
8
|
+
// <<<inject:auth-logout>>>
|
|
9
|
+
// <<<inject:auth-logout-all>>>
|
|
10
|
+
// <<<inject:auth-me>>>
|
|
11
|
+
// <<<inject:auth-protected>>>
|
|
12
|
+
// <<<inject:auth-oauth-google>>>
|
|
13
|
+
// <<<inject:auth-mfa-totp>>>
|
|
14
|
+
// <<<inject:auth-email-verification>>>
|
|
15
|
+
// <<<inject:auth-captcha>>>
|
|
16
|
+
// <<<inject:auth-biometric>>>
|
|
17
|
+
// <<<inject:auth-passwordless>>>
|
|
18
|
+
// <<<inject:auth-federated>>>
|
|
19
|
+
// <<<inject:auth-zero-trust>>>
|
|
20
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { registerAs } from '@nestjs/config';
|
|
3
|
+
|
|
4
|
+
/* eslint-disable @typescript-eslint/no-require-imports */
|
|
5
|
+
|
|
6
|
+
// Dynamic vendor loader - resolves .workspai/vendor in project root or uses
|
|
7
|
+
// RAPIDKIT_VENDOR_ROOT if set. This avoids hard-coded relative imports into
|
|
8
|
+
// src/.workspai and makes generated projects robust and portable.
|
|
9
|
+
const VENDOR_ROOT_ENV = 'RAPIDKIT_VENDOR_ROOT';
|
|
10
|
+
const VENDOR_MODULE = '{{ rapidkit_vendor_module }}';
|
|
11
|
+
const VENDOR_VERSION = '{{ rapidkit_vendor_version }}';
|
|
12
|
+
const VENDOR_CONFIGURATION_RELATIVE = 'src/config/configuration';
|
|
13
|
+
|
|
14
|
+
function resolveVendorRoot(): string {
|
|
15
|
+
const override = process.env[VENDOR_ROOT_ENV];
|
|
16
|
+
if (override && override.trim().length > 0) {
|
|
17
|
+
return path.resolve(override);
|
|
18
|
+
}
|
|
19
|
+
return path.resolve(process.cwd(), '.workspai', 'vendor');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function resolveVendorModule() {
|
|
23
|
+
const vendorPath = path.join(
|
|
24
|
+
resolveVendorRoot(),
|
|
25
|
+
VENDOR_MODULE,
|
|
26
|
+
VENDOR_VERSION,
|
|
27
|
+
VENDOR_CONFIGURATION_RELATIVE,
|
|
28
|
+
);
|
|
29
|
+
// Attempt to dynamically load a vendor-provided configuration. If the
|
|
30
|
+
// vendor snapshot is not present in .workspai/vendor (common when the
|
|
31
|
+
// 'settings' module wasn't installed), fail gracefully instead of
|
|
32
|
+
// allowing require() to throw and crash the application.
|
|
33
|
+
try {
|
|
34
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires, global-require
|
|
35
|
+
return require(vendorPath);
|
|
36
|
+
} catch (err: unknown) {
|
|
37
|
+
const e = err as { code?: string } | undefined;
|
|
38
|
+
// Only suppress MODULE_NOT_FOUND / ENOENT for the vendor path so other
|
|
39
|
+
// unexpected errors still surface to the user.
|
|
40
|
+
if (e && (e.code === 'MODULE_NOT_FOUND' || e.code === 'ENOENT')) {
|
|
41
|
+
// eslint-disable-next-line no-console
|
|
42
|
+
console.warn(`WARN: vendor settings not found at ${vendorPath} - continuing without vendor settings`);
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
throw err;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const _vendor = resolveVendorModule();
|
|
50
|
+
|
|
51
|
+
export default registerAs('app', () => ({
|
|
52
|
+
name: process.env.APP_NAME ?? "{{ project_name | replace('-', ' ') | title }}",
|
|
53
|
+
env: process.env.NODE_ENV ?? 'development',
|
|
54
|
+
host: process.env.HOST ?? '0.0.0.0',
|
|
55
|
+
port: parseInt(process.env.PORT ?? '8000', 10),
|
|
56
|
+
logLevel: (() => {
|
|
57
|
+
const raw = (process.env.LOG_LEVEL ?? 'log').toLowerCase();
|
|
58
|
+
if (raw === 'info') return 'log';
|
|
59
|
+
if (raw === 'warning') return 'warn';
|
|
60
|
+
return raw;
|
|
61
|
+
})(),
|
|
62
|
+
// <<<inject:configuration>>>
|
|
63
|
+
}));
|
|
64
|
+
|
|
65
|
+
// Provide a safe default settingsConfiguration if no vendor snapshot is present
|
|
66
|
+
// so generated projects still boot even when the optional settings module
|
|
67
|
+
// hasn't been installed.
|
|
68
|
+
const defaultSettings = () => ({
|
|
69
|
+
ENV: process.env.NODE_ENV ?? 'development',
|
|
70
|
+
DEBUG: process.env.DEBUG === '1' || process.env.DEBUG?.toLowerCase() === 'true',
|
|
71
|
+
PROJECT_NAME: process.env.APP_NAME ?? '{{ project_name | replace('-', ' ') | title }}',
|
|
72
|
+
SECRET_KEY: process.env.SECRET_KEY ?? '{{ '' | generate_secret(48) }}',
|
|
73
|
+
VERSION: process.env.APP_VERSION ?? '0.0.1',
|
|
74
|
+
ALLOWED_HOSTS: (process.env.ALLOWED_HOSTS ?? '*').split(',').map((s) => s.trim()).filter(Boolean),
|
|
75
|
+
CONFIG_FILES: [],
|
|
76
|
+
CONFIG_REFRESH_INTERVAL: Number.parseInt(process.env.CONFIG_REFRESH_INTERVAL ?? '60', 10),
|
|
77
|
+
VAULT_URL: null,
|
|
78
|
+
AWS_REGION: null,
|
|
79
|
+
HOT_RELOAD_ENABLED:
|
|
80
|
+
process.env.HOT_RELOAD_ENABLED === '1' || process.env.HOT_RELOAD_ENABLED?.toLowerCase() === 'true',
|
|
81
|
+
HOT_RELOAD_ENV_ALLOWLIST: (process.env.HOT_RELOAD_ENV_ALLOWLIST ?? '').split(',').map((s) => s.trim()).filter(Boolean),
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
export const settingsConfiguration =
|
|
85
|
+
_vendor?.settingsConfiguration ?? _vendor?.default?.settingsConfiguration ?? (() => defaultSettings());
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as Joi from 'joi';
|
|
2
|
+
|
|
3
|
+
export const validationSchema = Joi.object({
|
|
4
|
+
APP_NAME: Joi.string().default("{{ project_name | replace('-', ' ') | title }}"),
|
|
5
|
+
NODE_ENV: Joi.string().valid('development', 'production', 'test').default('development'),
|
|
6
|
+
HOST: Joi.string().hostname().default('0.0.0.0'),
|
|
7
|
+
PORT: Joi.number().port().default(8000),
|
|
8
|
+
LOG_LEVEL: Joi.string()
|
|
9
|
+
.lowercase()
|
|
10
|
+
.valid('error', 'warn', 'log', 'debug', 'verbose', 'info', 'warning')
|
|
11
|
+
.default('log'),
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
export const loggingValidationSchema = Joi.object({
|
|
15
|
+
LOG_LEVEL: Joi.string().valid('debug', 'info', 'warning', 'error').default('info'),
|
|
16
|
+
LOG_FORMAT: Joi.string().valid('json', 'text', 'colored').default('json'),
|
|
17
|
+
LOG_SINKS: Joi.string().default('stderr'),
|
|
18
|
+
LOG_ASYNC_QUEUE: Joi.boolean().truthy('true').falsy('false').default(true),
|
|
19
|
+
LOG_FILE_PATH: Joi.string().default('logs/app.log'),
|
|
20
|
+
LOG_SAMPLING_RATE: Joi.number().min(0).max(1).default(1),
|
|
21
|
+
});
|