cerber-core 1.0.4 → 1.1.1

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.
Files changed (42) hide show
  1. package/CHANGELOG.md +158 -68
  2. package/README.md +198 -5
  3. package/USAGE_GUIDE.md +254 -0
  4. package/bin/cerber +120 -104
  5. package/dev/templates/BACKEND_SCHEMA.ts.tpl +48 -0
  6. package/dev/templates/cerber-guardian.mjs.tpl +44 -0
  7. package/dev/templates/cerber.yml.tpl +53 -0
  8. package/dev/templates/health-checks.ts.tpl +11 -0
  9. package/dev/templates/health-route.ts.tpl +50 -0
  10. package/dev/templates/pre-commit.tpl +4 -0
  11. package/dist/cli/contract-parser.d.ts +13 -0
  12. package/dist/cli/contract-parser.d.ts.map +1 -0
  13. package/dist/cli/contract-parser.js +265 -0
  14. package/dist/cli/contract-parser.js.map +1 -0
  15. package/dist/cli/init.d.ts +11 -0
  16. package/dist/cli/init.d.ts.map +1 -0
  17. package/dist/cli/init.js +292 -0
  18. package/dist/cli/init.js.map +1 -0
  19. package/dist/cli/template-generator.d.ts +29 -0
  20. package/dist/cli/template-generator.d.ts.map +1 -0
  21. package/dist/cli/template-generator.js +252 -0
  22. package/dist/cli/template-generator.js.map +1 -0
  23. package/dist/cli/types.d.ts +79 -0
  24. package/dist/cli/types.d.ts.map +1 -0
  25. package/dist/cli/types.js +8 -0
  26. package/dist/cli/types.js.map +1 -0
  27. package/examples/backend-schema.ts +9 -2
  28. package/examples/frontend-schema.ts +9 -2
  29. package/package.json +106 -104
  30. package/solo/templates/BACKEND_SCHEMA.ts.tpl +48 -0
  31. package/solo/templates/cerber-guardian.mjs.tpl +44 -0
  32. package/solo/templates/cerber.yml.tpl +53 -0
  33. package/solo/templates/health-checks.ts.tpl +29 -0
  34. package/solo/templates/health-route.ts.tpl +50 -0
  35. package/solo/templates/pre-commit.tpl +4 -0
  36. package/team/templates/BACKEND_SCHEMA.ts.tpl +48 -0
  37. package/team/templates/CODEOWNERS.tpl +6 -0
  38. package/team/templates/cerber-guardian.mjs.tpl +44 -0
  39. package/team/templates/cerber.yml.tpl +53 -0
  40. package/team/templates/health-checks.ts.tpl +10 -0
  41. package/team/templates/health-route.ts.tpl +50 -0
  42. package/team/templates/pre-commit.tpl +4 -0
package/USAGE_GUIDE.md ADDED
@@ -0,0 +1,254 @@
1
+ # How to Use Cerber in Your Project
2
+
3
+ ## Quick Start (Recommended)
4
+
5
+ 1. **Install Cerber Core**
6
+ ```bash
7
+ npm install cerber-core --save-dev
8
+ ```
9
+
10
+ 2. **Run init command**
11
+ ```bash
12
+ npx cerber init
13
+ ```
14
+
15
+ 3. **Follow the prompts**
16
+ - If no `CERBER.md` exists, one will be created for you
17
+ - Customize the contract (mode, endpoints, branches)
18
+ - Run `npx cerber init` again to generate files
19
+
20
+ 4. **Review generated files**
21
+ - `CERBER.md` - Your architecture contract
22
+ - `scripts/cerber-guardian.mjs` - Pre-commit validator
23
+ - `.husky/pre-commit` - Git hook
24
+ - `src/cerber/health-checks.ts` - Health check templates
25
+ - `.github/workflows/cerber.yml` - CI/CD workflow
26
+
27
+ 5. **Customize for your project**
28
+ - Create `BACKEND_SCHEMA.ts` with your architecture rules
29
+ - Edit `src/cerber/health-checks.ts` to add your checks
30
+ - Update `.github/CODEOWNERS` if in team mode
31
+
32
+ 6. **Commit and push**
33
+ ```bash
34
+ git add .
35
+ git commit -m "feat: add Cerber protection"
36
+ git push
37
+ ```
38
+
39
+ ---
40
+
41
+ ## Configuration Modes
42
+
43
+ ### Solo Mode
44
+ **Best for:** Individual developers, prototypes, small projects
45
+
46
+ **Features:**
47
+ - Guardian pre-commit validation
48
+ - Basic health checks (optional)
49
+ - Simple CI workflow
50
+
51
+ **Setup:**
52
+ ```yaml
53
+ # In CERBER.md CERBER_CONTRACT
54
+ mode: solo
55
+ ```
56
+
57
+ ### Dev Mode (Default)
58
+ **Best for:** Small teams (2-5 developers), standard projects
59
+
60
+ **Features:**
61
+ - Guardian with required imports
62
+ - Health check endpoints
63
+ - GitHub Actions CI/CD
64
+ - Optional post-deploy health gates
65
+
66
+ **Setup:**
67
+ ```yaml
68
+ # In CERBER.md CERBER_CONTRACT
69
+ mode: dev
70
+ ```
71
+
72
+ ### Team Mode
73
+ **Best for:** Larger teams, strict architecture enforcement
74
+
75
+ **Features:**
76
+ - Everything from Dev mode
77
+ - CODEOWNERS protection
78
+ - Required PR reviews for architecture files
79
+ - Post-deploy health validation (enabled by default)
80
+
81
+ **Setup:**
82
+ ```yaml
83
+ # In CERBER.md CERBER_CONTRACT
84
+ mode: team
85
+ ```
86
+
87
+ ---
88
+
89
+ ## CERBER_CONTRACT Reference
90
+
91
+ ```yaml
92
+ version: 1
93
+ mode: dev # solo | dev | team
94
+
95
+ guardian:
96
+ enabled: true # Enable pre-commit validation
97
+ schemaFile: BACKEND_SCHEMA.ts # Path to your schema
98
+ hook: husky # husky | manual
99
+ approvalsTag: ARCHITECT_APPROVED # Tag for exceptions
100
+
101
+ health:
102
+ enabled: true # Generate health check templates
103
+ endpoint: /api/health # Your health endpoint path
104
+ failOn:
105
+ critical: true # Block deploy on critical issues
106
+ error: true # Block deploy on errors
107
+ warning: false # Allow warnings
108
+
109
+ ci:
110
+ provider: github # github | gitlab | manual
111
+ branches: [main] # Protected branches
112
+ requiredOnPR: true # Run Guardian on PRs
113
+ postDeploy:
114
+ enabled: false # Post-deploy health gate
115
+ waitSeconds: 90 # Wait time before check
116
+ healthUrlVar: CERBER_HEALTH_URL # GitHub Variable name
117
+ authHeaderSecret: CERBER_HEALTH_AUTH_HEADER # GitHub Secret name (optional)
118
+ ```
119
+
120
+ ---
121
+
122
+ ## CLI Flags
123
+
124
+ ### Basic Usage
125
+ ```bash
126
+ npx cerber init # Interactive setup
127
+ npx cerber init --mode dev # Override mode
128
+ npx cerber init --dry-run # Preview without creating files
129
+ npx cerber init --force # Overwrite existing files
130
+ ```
131
+
132
+ ### Advanced Flags
133
+ ```bash
134
+ --mode <mode> # Override contract mode (solo|dev|team)
135
+ --force # Overwrite existing files
136
+ --dry-run # Show what would be generated
137
+ --no-husky # Skip Husky hook generation
138
+ --no-workflow # Skip GitHub Actions workflow
139
+ --no-health # Skip health check templates
140
+ --write-contract # Update CERBER.md with CLI options
141
+ ```
142
+
143
+ ### Examples
144
+ ```bash
145
+ # Preview dev mode setup
146
+ npx cerber init --mode dev --dry-run
147
+
148
+ # Generate only Guardian files (no health checks)
149
+ npx cerber init --no-health --no-workflow
150
+
151
+ # Force regenerate all files in team mode
152
+ npx cerber init --mode team --force
153
+ ```
154
+
155
+ ---
156
+
157
+ ## GitHub Actions Setup
158
+
159
+ ### Required Variables
160
+
161
+ If you enable post-deploy health checks, set up GitHub Variables:
162
+
163
+ 1. Go to: **Settings** > **Secrets and variables** > **Actions** > **Variables**
164
+ 2. Add new repository variable:
165
+ - **Name:** `CERBER_HEALTH_URL`
166
+ - **Value:** `https://your-api.com/api/health`
167
+
168
+ ### Optional Secrets
169
+
170
+ For authenticated health endpoints:
171
+
172
+ 1. Go to: **Settings** > **Secrets and variables** > **Actions** > **Secrets**
173
+ 2. Add new repository secret:
174
+ - **Name:** `CERBER_HEALTH_AUTH_HEADER`
175
+ - **Value:** `Bearer your-token-here`
176
+
177
+ ---
178
+
179
+ ## Team Mode Setup
180
+
181
+ ### CODEOWNERS Configuration
182
+
183
+ 1. Edit `.github/CODEOWNERS`:
184
+ ```
185
+ /CERBER.md @your-username
186
+ /BACKEND_SCHEMA.ts @your-username
187
+ /.github/workflows/cerber.yml @your-username
188
+ ```
189
+
190
+ 2. Replace `@your-username` with:
191
+ - Your GitHub username (individual)
192
+ - Team name like `@org/architects` (organization)
193
+
194
+ ### Branch Protection
195
+
196
+ 1. Go to: **Settings** > **Branches** > **Branch protection rules**
197
+ 2. Add rule for `main`:
198
+ - ✅ Require pull request reviews before merging
199
+ - ✅ Require review from Code Owners
200
+ - ✅ Require status checks to pass
201
+ - Add: `cerber-guardian`
202
+ - Add: `post-deploy-health` (if enabled)
203
+
204
+ ---
205
+
206
+ ## Troubleshooting
207
+
208
+ ### "CERBER.md not found"
209
+ Run `npx cerber init` - it will create a template for you.
210
+
211
+ ### "Schema file not found"
212
+ Create `BACKEND_SCHEMA.ts` at your project root with Guardian rules. See [Guardian Configuration](https://github.com/Agaslez/cerber-core#guardian-configuration).
213
+
214
+ ### Guardian hook not running
215
+ ```bash
216
+ npx husky install
217
+ chmod +x .husky/pre-commit
218
+ ```
219
+
220
+ ### Post-deploy health check fails
221
+ - Verify `CERBER_HEALTH_URL` is set in GitHub Variables
222
+ - Check health endpoint returns proper JSON format
223
+ - Review `failOn` settings in `CERBER_CONTRACT`
224
+
225
+ ### Files already exist error
226
+ Use `--force` flag to overwrite:
227
+ ```bash
228
+ npx cerber init --force
229
+ ```
230
+
231
+ ---
232
+
233
+ ## Migration from Manual Setup
234
+
235
+ If you have existing Guardian/Cerber setup:
236
+
237
+ 1. Create `CERBER.md` with contract matching your current config
238
+ 2. Run `npx cerber init --dry-run` to preview changes
239
+ 3. Backup existing files
240
+ 4. Run `npx cerber init --force` to migrate
241
+ 5. Review and test generated files
242
+
243
+ ---
244
+
245
+ ## Next Steps
246
+
247
+ - 📖 Read [Guardian Configuration Guide](https://github.com/Agaslez/cerber-core#guardian-configuration)
248
+ - 🔍 Explore [Cerber Health Examples](https://github.com/Agaslez/cerber-core#cerber-examples)
249
+ - 💬 Ask questions in [GitHub Discussions](https://github.com/Agaslez/cerber-core/discussions)
250
+ - ⭐ Star the repo if Cerber saved you time!
251
+
252
+ ---
253
+
254
+ **Need help?** Open an issue or discussion: https://github.com/Agaslez/cerber-core
package/bin/cerber CHANGED
@@ -1,105 +1,121 @@
1
1
  #!/usr/bin/env node
2
-
3
- /**
4
- * Cerber Core - Unified CLI
5
- *
6
- * Main entry point for all Cerber commands
7
- *
8
- * @author Stefan Pitek
9
- * @license MIT
10
- */
11
-
12
- import chalk from 'chalk';
13
- import { program } from 'commander';
14
-
15
- program
16
- .name('cerber')
17
- .description('Cerber Core - Code quality & health monitoring')
18
- .version('1.0.0');
19
-
20
- program
21
- .command('guardian')
22
- .description('Run Guardian pre-commit validation')
23
- .option('-s, --schema <file>', 'Schema file path')
24
- .option('-v, --verbose', 'Verbose output')
25
- .option('--fail-on-warning', 'Exit with error on warnings')
26
- .action(async (options) => {
27
- const { Guardian } = await import('../dist/guardian/index.js');
28
- const schema = options.schema ? await import(options.schema) : null;
29
-
30
- const guardian = new Guardian(schema?.default || {});
31
- const result = await guardian.validate();
32
-
33
- if (!result.success) {
34
- console.error(chalk.red('❌ Guardian validation failed'));
35
- process.exit(1);
36
- }
37
-
38
- console.log(chalk.green(' Guardian validation passed'));
39
- });
40
-
41
- program
42
- .command('health')
43
- .description('Run Cerber health checks')
44
- .option('-c, --checks <file>', 'Health checks file path')
45
- .option('-u, --url <url>', 'Fetch health from URL')
46
- .option('-p, --parallel', 'Run checks in parallel')
47
- .action(async (options) => {
48
- const { Cerber } = await import('../dist/cerber/index.js');
49
-
50
- if (options.url) {
51
- const response = await fetch(options.url);
52
- const result = await response.json();
53
- console.log(JSON.stringify(result, null, 2));
54
- process.exit(result.status === 'healthy' ? 0 : 1);
55
- }
56
-
57
- const checksModule = options.checks ? await import(options.checks) : null;
58
- const checks = checksModule ? Object.values(checksModule).filter(v => typeof v === 'function') : [];
59
-
60
- const cerber = new Cerber(checks);
61
- const result = await cerber.runChecks({ parallel: options.parallel });
62
-
63
- process.exit(result.status === 'healthy' ? 0 : 1);
64
- });
65
-
66
- program
67
- .command('morning')
68
- .description('Run morning dashboard (SOLO)')
69
- .action(async () => {
70
- const { execSync } = await import('child_process');
71
- execSync('node solo/scripts/cerber-daily-check.js', { stdio: 'inherit' });
72
- });
73
-
74
- program
75
- .command('repair')
76
- .description('Auto-repair common issues (SOLO)')
77
- .option('--dry-run', 'Show what would be fixed without making changes')
78
- .option('--approve', 'Require approval for each fix')
79
- .action(async (options) => {
80
- const { execSync } = await import('child_process');
81
- const args = [
82
- options.dryRun && '--dry-run',
83
- options.approve && '--approve'
84
- ].filter(Boolean).join(' ');
85
-
86
- execSync(`node solo/scripts/cerber-auto-repair.js ${args}`, { stdio: 'inherit' });
87
- });
88
-
89
- program
90
- .command('focus <module>')
91
- .description('Generate focus context for module (TEAM)')
92
- .action(async (module) => {
93
- const { execSync } = await import('child_process');
94
- execSync(`bash team/scripts/cerber-focus.sh ${module}`, { stdio: 'inherit' });
95
- });
96
-
97
- program
98
- .command('dashboard')
99
- .description('Show system dashboard (SOLO)')
100
- .action(async () => {
101
- const { execSync } = await import('child_process');
102
- execSync('node solo/scripts/cerber-dashboard.js', { stdio: 'inherit' });
103
- });
104
-
105
- program.parse();
2
+
3
+ /**
4
+ * Cerber Core - Unified CLI
5
+ *
6
+ * Main entry point for all Cerber commands
7
+ *
8
+ * @author Stefan Pitek
9
+ * @license MIT
10
+ */
11
+
12
+ import chalk from 'chalk';
13
+ import { program } from 'commander';
14
+
15
+ program
16
+ .name('cerber')
17
+ .description('Cerber Core - Code quality & health monitoring')
18
+ .version('1.1.0');
19
+
20
+ program
21
+ .command('init')
22
+ .description('Initialize Cerber in your project')
23
+ .option('--mode <mode>', 'Override mode: solo | dev | team')
24
+ .option('--force', 'Overwrite existing files')
25
+ .option('--dry-run', 'Show what would be generated without creating files')
26
+ .option('--print-template', 'Print CERBER.md template contract to stdout')
27
+ .option('--no-husky', 'Skip Husky hook generation')
28
+ .option('--no-workflow', 'Skip GitHub Actions workflow generation')
29
+ .option('--no-health', 'Skip health check template generation')
30
+ .option('--write-contract', 'Update CERBER.md contract with CLI options')
31
+ .action(async (options) => {
32
+ const { initCommand } = await import('../dist/cli/init.js');
33
+ await initCommand(options);
34
+ });
35
+
36
+ program
37
+ .command('guardian')
38
+ .description('Run Guardian pre-commit validation')
39
+ .option('-s, --schema <file>', 'Schema file path')
40
+ .option('-v, --verbose', 'Verbose output')
41
+ .option('--fail-on-warning', 'Exit with error on warnings')
42
+ .action(async (options) => {
43
+ const { Guardian } = await import('../dist/guardian/index.js');
44
+ const schema = options.schema ? await import(options.schema) : null;
45
+
46
+ const guardian = new Guardian(schema?.default || {});
47
+ const result = await guardian.validate();
48
+
49
+ if (!result.success) {
50
+ console.error(chalk.red('❌ Guardian validation failed'));
51
+ process.exit(1);
52
+ }
53
+
54
+ console.log(chalk.green(' Guardian validation passed'));
55
+ });
56
+
57
+ program
58
+ .command('health')
59
+ .description('Run Cerber health checks')
60
+ .option('-c, --checks <file>', 'Health checks file path')
61
+ .option('-u, --url <url>', 'Fetch health from URL')
62
+ .option('-p, --parallel', 'Run checks in parallel')
63
+ .action(async (options) => {
64
+ const { Cerber } = await import('../dist/cerber/index.js');
65
+
66
+ if (options.url) {
67
+ const response = await fetch(options.url);
68
+ const result = await response.json();
69
+ console.log(JSON.stringify(result, null, 2));
70
+ process.exit(result.status === 'healthy' ? 0 : 1);
71
+ }
72
+
73
+ const checksModule = options.checks ? await import(options.checks) : null;
74
+ const checks = checksModule ? Object.values(checksModule).filter(v => typeof v === 'function') : [];
75
+
76
+ const cerber = new Cerber(checks);
77
+ const result = await cerber.runChecks({ parallel: options.parallel });
78
+
79
+ process.exit(result.status === 'healthy' ? 0 : 1);
80
+ });
81
+
82
+ program
83
+ .command('morning')
84
+ .description('Run morning dashboard (SOLO)')
85
+ .action(async () => {
86
+ const { execSync } = await import('child_process');
87
+ execSync('node solo/scripts/cerber-daily-check.js', { stdio: 'inherit' });
88
+ });
89
+
90
+ program
91
+ .command('repair')
92
+ .description('Auto-repair common issues (SOLO)')
93
+ .option('--dry-run', 'Show what would be fixed without making changes')
94
+ .option('--approve', 'Require approval for each fix')
95
+ .action(async (options) => {
96
+ const { execSync } = await import('child_process');
97
+ const args = [
98
+ options.dryRun && '--dry-run',
99
+ options.approve && '--approve'
100
+ ].filter(Boolean).join(' ');
101
+
102
+ execSync(`node solo/scripts/cerber-auto-repair.js ${args}`, { stdio: 'inherit' });
103
+ });
104
+
105
+ program
106
+ .command('focus <module>')
107
+ .description('Generate focus context for module (TEAM)')
108
+ .action(async (module) => {
109
+ const { execSync } = await import('child_process');
110
+ execSync(`bash team/scripts/cerber-focus.sh ${module}`, { stdio: 'inherit' });
111
+ });
112
+
113
+ program
114
+ .command('dashboard')
115
+ .description('Show system dashboard (SOLO)')
116
+ .action(async () => {
117
+ const { execSync } = await import('child_process');
118
+ execSync('node solo/scripts/cerber-dashboard.js', { stdio: 'inherit' });
119
+ });
120
+
121
+ program.parse();
@@ -0,0 +1,48 @@
1
+ /**
2
+ * ⚠️ CERBER TEMPLATE (NOT SOURCE OF TRUTH)
3
+ *
4
+ * This file is a starting point. Edit it to match YOUR architecture.
5
+ * The source of truth is CERBER.md.
6
+ *
7
+ * Generated by: npx cerber init
8
+ * Project: {{PROJECT_NAME}}
9
+ *
10
+ * See: https://github.com/Agaslez/cerber-core#guardian-configuration
11
+ */
12
+
13
+ export const BACKEND_SCHEMA = {
14
+ version: "1.0.0",
15
+
16
+ // Your architecture rules (customize)
17
+ rules: [],
18
+
19
+ // Patterns that should never appear in your code
20
+ forbiddenPatterns: [
21
+ // Uncomment and customize based on your tech stack:
22
+ // {
23
+ // pattern: /password\s*=\s*['"][^'"]+['"]/i,
24
+ // name: "Hardcoded passwords",
25
+ // severity: "error"
26
+ // },
27
+ // {
28
+ // pattern: /api[_-]?key\s*=\s*['"][^'"]+['"]/i,
29
+ // name: "Hardcoded API keys",
30
+ // severity: "error"
31
+ // }
32
+ ]
33
+ };
34
+
35
+ export default BACKEND_SCHEMA;
36
+
37
+ /**
38
+ * 💡 Next Steps:
39
+ *
40
+ * 1. Define your project structure in CERBER.md (single source of truth)
41
+ * 2. Add forbiddenPatterns for your tech stack
42
+ * 3. Add requiredImports rules for your architecture layers
43
+ * 4. Test with: npx cerber-guardian
44
+ *
45
+ * Full examples:
46
+ * - node_modules/cerber-core/examples/backend-schema.ts
47
+ * - node_modules/cerber-core/examples/frontend-schema.ts
48
+ */
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env node
2
+ // Generated by Cerber init - DO NOT EDIT MANUALLY
3
+ // To regenerate: npx cerber init --force
4
+
5
+ import { execSync } from 'child_process';
6
+ import fs from 'fs';
7
+
8
+ const SCHEMA_FILE = '{{SCHEMA_FILE}}';
9
+ const APPROVALS_TAG = '{{APPROVALS_TAG}}';
10
+
11
+ async function main() {
12
+ console.log('🛡️ Cerber Guardian: Validating staged files...');
13
+
14
+ if (!fs.existsSync(SCHEMA_FILE)) {
15
+ console.error(`❌ Schema file not found: ${SCHEMA_FILE}`);
16
+ console.error('Guardian MVP: schema missing. Add your rules to proceed.');
17
+ process.exit(1);
18
+ }
19
+
20
+ let stagedFiles;
21
+ try {
22
+ stagedFiles = execSync('git diff --cached --name-only', { encoding: 'utf-8' })
23
+ .trim()
24
+ .split('\n')
25
+ .filter(Boolean);
26
+ } catch (err) {
27
+ console.error('❌ Failed to get staged files');
28
+ process.exit(1);
29
+ }
30
+
31
+ if (stagedFiles.length === 0) {
32
+ console.log('✅ No files staged for commit');
33
+ return;
34
+ }
35
+
36
+ console.log(`Checking ${stagedFiles.length} file(s)...`);
37
+ console.log('Guardian MVP: schema detected. Add validation rules to enforce imports/forbidden patterns.');
38
+ console.log('✅ All checks passed');
39
+ }
40
+
41
+ main().catch(err => {
42
+ console.error('❌ Guardian check failed:', err?.message || err);
43
+ process.exit(1);
44
+ });
@@ -0,0 +1,53 @@
1
+ # Generated by Cerber init
2
+ name: Cerber CI
3
+
4
+ on:
5
+ push:
6
+ branches: {{CI_BRANCHES}}
7
+ pull_request:
8
+ branches: {{CI_BRANCHES}}
9
+ workflow_dispatch:
10
+
11
+ jobs:
12
+ cerber-ci:
13
+ name: Cerber CI
14
+ runs-on: ubuntu-latest
15
+
16
+ steps:
17
+ - name: Checkout code
18
+ uses: actions/checkout@v4
19
+
20
+ - name: Setup Node.js
21
+ uses: actions/setup-node@v4
22
+ with:
23
+ node-version: '20'
24
+ cache: 'npm'
25
+
26
+ - name: Install dependencies
27
+ run: npm ci
28
+
29
+ - name: Build (if script exists)
30
+ run: |
31
+ if npm run | grep -q "build"; then
32
+ npm run build
33
+ else
34
+ echo "No build script defined; skipping"
35
+ fi
36
+
37
+ - name: Test (if script exists)
38
+ run: |
39
+ if npm run | grep -q "test"; then
40
+ npm test
41
+ else
42
+ echo "No test script defined; skipping"
43
+ fi
44
+
45
+ - name: Run Guardian
46
+ run: |
47
+ if npm run | grep -q "cerber:guardian"; then
48
+ npm run cerber:guardian
49
+ else
50
+ node scripts/cerber-guardian.mjs
51
+ fi
52
+
53
+ {{POST_DEPLOY_BLOCK}}
@@ -0,0 +1,11 @@
1
+ // Generated by Cerber init - CUSTOMIZE THIS FILE
2
+ // To regenerate template: npx cerber init --force
3
+
4
+ import { CerberCheck, makeIssue } from 'cerber-core';
5
+
6
+ export const checks: Record<string, CerberCheck> = {
7
+ database: async () => {
8
+ // TODO: Implement your database health check
9
+ return [];
10
+ },
11
+ };