@codyswann/lisa 1.13.0 → 1.15.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/cdk/copy-overwrite/jest.cdk.ts +71 -0
- package/cdk/copy-overwrite/jest.config.ts +28 -0
- package/cdk/copy-overwrite/tsconfig.cdk.json +14 -0
- package/cdk/copy-overwrite/tsconfig.eslint.json +2 -1
- package/cdk/copy-overwrite/tsconfig.json +3 -0
- package/cdk/create-only/cdk.json +23 -0
- package/cdk/create-only/tsconfig.local.json +4 -0
- package/expo/copy-overwrite/.claude/skills/owasp-zap/SKILL.md +56 -0
- package/expo/copy-overwrite/.claude/skills/testing-library/SKILL.md +5 -10
- package/expo/copy-overwrite/.github/workflows/zap-baseline.yml +107 -0
- package/expo/copy-overwrite/.zap/baseline.conf +36 -0
- package/expo/copy-overwrite/jest.config.ts +28 -0
- package/expo/copy-overwrite/jest.expo.ts +119 -0
- package/expo/copy-overwrite/scripts/zap-baseline.sh +92 -0
- package/expo/copy-overwrite/tsconfig.eslint.json +2 -1
- package/expo/copy-overwrite/tsconfig.expo.json +12 -0
- package/expo/copy-overwrite/tsconfig.json +5 -0
- package/expo/create-only/.github/workflows/ci.yml +8 -0
- package/expo/create-only/tsconfig.local.json +3 -0
- package/expo/package-lisa/package.lisa.json +4 -2
- package/nestjs/copy-overwrite/.github/workflows/zap-baseline.yml +123 -0
- package/nestjs/copy-overwrite/.zap/baseline.conf +39 -0
- package/nestjs/copy-overwrite/jest.config.ts +28 -0
- package/nestjs/copy-overwrite/jest.nestjs.ts +89 -0
- package/nestjs/copy-overwrite/scripts/zap-baseline.sh +99 -0
- package/nestjs/copy-overwrite/tsconfig.build.json +5 -0
- package/nestjs/copy-overwrite/tsconfig.eslint.json +10 -0
- package/nestjs/copy-overwrite/tsconfig.json +5 -0
- package/nestjs/copy-overwrite/tsconfig.nestjs.json +16 -0
- package/nestjs/copy-overwrite/tsconfig.spec.json +7 -0
- package/nestjs/create-only/.github/workflows/ci.yml +8 -0
- package/nestjs/create-only/tsconfig.local.json +6 -0
- package/nestjs/package-lisa/package.lisa.json +2 -1
- package/package.json +1 -1
- package/typescript/copy-overwrite/.claude/commands/security/zap-scan.md +12 -0
- package/typescript/copy-overwrite/.github/workflows/quality.yml +100 -5
- package/typescript/copy-overwrite/jest.base.ts +112 -0
- package/typescript/copy-overwrite/jest.config.ts +34 -0
- package/typescript/copy-overwrite/jest.typescript.ts +72 -0
- package/typescript/copy-overwrite/tsconfig.base.json +15 -0
- package/typescript/copy-overwrite/tsconfig.eslint.json +3 -2
- package/typescript/copy-overwrite/tsconfig.json +5 -0
- package/typescript/copy-overwrite/tsconfig.typescript.json +11 -0
- package/typescript/create-only/jest.config.local.ts +30 -0
- package/typescript/create-only/jest.thresholds.json +8 -0
- package/typescript/create-only/tsconfig.local.json +6 -0
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
# - Snyk dependency vulnerability scanning
|
|
19
19
|
# - GitGuardian secret detection
|
|
20
20
|
# - FOSSA license compliance checking
|
|
21
|
+
# - OWASP ZAP DAST baseline scanning
|
|
21
22
|
# - E2E testing:
|
|
22
23
|
# - Playwright web E2E tests (auto-detects playwright.config.ts)
|
|
23
24
|
# - Maestro Cloud mobile E2E tests (requires MAESTRO_API_KEY, project ID, and app binary)
|
|
@@ -54,10 +55,20 @@ on:
|
|
|
54
55
|
default: 'npm'
|
|
55
56
|
type: string
|
|
56
57
|
skip_jobs:
|
|
57
|
-
description: 'Jobs to skip (comma-separated: lint,lint_slow,typecheck,test,test:unit,test:integration,test:e2e,maestro_e2e,playwright_e2e,format,build,dead_code,sg_scan,npm_security_scan,github_issue)'
|
|
58
|
+
description: 'Jobs to skip (comma-separated: lint,lint_slow,typecheck,test,test:unit,test:integration,test:e2e,maestro_e2e,playwright_e2e,format,build,dead_code,sg_scan,npm_security_scan,zap_baseline,github_issue)'
|
|
58
59
|
required: false
|
|
59
60
|
default: ''
|
|
60
61
|
type: string
|
|
62
|
+
zap_target_url:
|
|
63
|
+
description: 'Target URL for OWASP ZAP baseline scan (leave empty to skip ZAP)'
|
|
64
|
+
required: false
|
|
65
|
+
default: ''
|
|
66
|
+
type: string
|
|
67
|
+
zap_rules_file:
|
|
68
|
+
description: 'Path to ZAP rules configuration file'
|
|
69
|
+
required: false
|
|
70
|
+
default: '.zap/baseline.conf'
|
|
71
|
+
type: string
|
|
61
72
|
working_directory:
|
|
62
73
|
description: 'Directory to run commands in (if not root)'
|
|
63
74
|
required: false
|
|
@@ -1242,12 +1253,74 @@ jobs:
|
|
|
1242
1253
|
echo "::warning::FOSSA license compliance check skipped - FOSSA_API_KEY not configured"
|
|
1243
1254
|
echo "To enable license compliance checking, add FOSSA_API_KEY to your repository secrets"
|
|
1244
1255
|
|
|
1256
|
+
zap_baseline:
|
|
1257
|
+
name: 🕷️ OWASP ZAP Baseline
|
|
1258
|
+
runs-on: ubuntu-latest
|
|
1259
|
+
timeout-minutes: 20
|
|
1260
|
+
if: ${{ !contains(inputs.skip_jobs, 'zap_baseline') && inputs.zap_target_url != '' }}
|
|
1261
|
+
steps:
|
|
1262
|
+
- name: 📥 Checkout repository
|
|
1263
|
+
uses: actions/checkout@v4
|
|
1264
|
+
|
|
1265
|
+
- name: 🔧 Setup Node.js
|
|
1266
|
+
uses: actions/setup-node@v4
|
|
1267
|
+
with:
|
|
1268
|
+
node-version: ${{ inputs.node_version }}
|
|
1269
|
+
cache: ${{ inputs.package_manager != 'bun' && inputs.package_manager || '' }}
|
|
1270
|
+
|
|
1271
|
+
- name: 🍞 Setup Bun
|
|
1272
|
+
if: inputs.package_manager == 'bun'
|
|
1273
|
+
uses: oven-sh/setup-bun@v2
|
|
1274
|
+
with:
|
|
1275
|
+
bun-version: '1.3.8'
|
|
1276
|
+
|
|
1277
|
+
- name: 📦 Install dependencies
|
|
1278
|
+
run: |
|
|
1279
|
+
if [ "${{ inputs.package_manager }}" = "npm" ]; then
|
|
1280
|
+
npm ci
|
|
1281
|
+
elif [ "${{ inputs.package_manager }}" = "yarn" ]; then
|
|
1282
|
+
yarn install --frozen-lockfile
|
|
1283
|
+
elif [ "${{ inputs.package_manager }}" = "bun" ]; then
|
|
1284
|
+
bun install --frozen-lockfile
|
|
1285
|
+
fi
|
|
1286
|
+
working-directory: ${{ inputs.working_directory || '.' }}
|
|
1287
|
+
|
|
1288
|
+
- name: 🔍 Check for ZAP rules file
|
|
1289
|
+
id: check_rules
|
|
1290
|
+
run: |
|
|
1291
|
+
if [ -f "${{ inputs.zap_rules_file }}" ]; then
|
|
1292
|
+
echo "has_rules=true" >> $GITHUB_OUTPUT
|
|
1293
|
+
else
|
|
1294
|
+
echo "has_rules=false" >> $GITHUB_OUTPUT
|
|
1295
|
+
fi
|
|
1296
|
+
working-directory: ${{ inputs.working_directory || '.' }}
|
|
1297
|
+
|
|
1298
|
+
- name: 🕷️ Run ZAP baseline scan
|
|
1299
|
+
uses: zaproxy/action-baseline@v0.14.0
|
|
1300
|
+
with:
|
|
1301
|
+
target: ${{ inputs.zap_target_url }}
|
|
1302
|
+
rules_file_name: ${{ steps.check_rules.outputs.has_rules == 'true' && inputs.zap_rules_file || '' }}
|
|
1303
|
+
fail_action: true
|
|
1304
|
+
allow_issue_writing: false
|
|
1305
|
+
artifact_name: 'zap-report'
|
|
1306
|
+
|
|
1307
|
+
- name: 📤 Upload ZAP report
|
|
1308
|
+
if: always()
|
|
1309
|
+
uses: actions/upload-artifact@v4
|
|
1310
|
+
with:
|
|
1311
|
+
name: zap-baseline-report-${{ github.run_id }}
|
|
1312
|
+
path: |
|
|
1313
|
+
zap-report.html
|
|
1314
|
+
zap-report.json
|
|
1315
|
+
zap-report.md
|
|
1316
|
+
retention-days: 14
|
|
1317
|
+
|
|
1245
1318
|
# Enterprise security tools summary
|
|
1246
1319
|
security_tools_summary:
|
|
1247
1320
|
name: 🔒 Security Tools Summary
|
|
1248
1321
|
runs-on: ubuntu-latest
|
|
1249
|
-
if: always() && (needs.sonarcloud.result != 'skipped' || needs.snyk.result != 'skipped' || needs.secret_scanning.result != 'skipped' || needs.license_compliance.result != 'skipped')
|
|
1250
|
-
needs: [sonarcloud, snyk, secret_scanning, license_compliance]
|
|
1322
|
+
if: always() && (needs.sonarcloud.result != 'skipped' || needs.snyk.result != 'skipped' || needs.secret_scanning.result != 'skipped' || needs.license_compliance.result != 'skipped' || needs.zap_baseline.result != 'skipped')
|
|
1323
|
+
needs: [sonarcloud, snyk, secret_scanning, license_compliance, zap_baseline]
|
|
1251
1324
|
steps:
|
|
1252
1325
|
- name: 📝 Generate security tools summary
|
|
1253
1326
|
run: |
|
|
@@ -1292,6 +1365,15 @@ jobs:
|
|
|
1292
1365
|
echo "- 📜 **FOSSA License Compliance**: ❌ Failed" >> $GITHUB_STEP_SUMMARY
|
|
1293
1366
|
fi
|
|
1294
1367
|
|
|
1368
|
+
# OWASP ZAP Baseline status
|
|
1369
|
+
if [ "${{ needs.zap_baseline.result }}" == "skipped" ]; then
|
|
1370
|
+
echo "- 🕷️ **OWASP ZAP Baseline**: ⏭️ Skipped (no target URL)" >> $GITHUB_STEP_SUMMARY
|
|
1371
|
+
elif [ "${{ needs.zap_baseline.result }}" == "success" ]; then
|
|
1372
|
+
echo "- 🕷️ **OWASP ZAP Baseline**: ✅ Passed" >> $GITHUB_STEP_SUMMARY
|
|
1373
|
+
else
|
|
1374
|
+
echo "- 🕷️ **OWASP ZAP Baseline**: ❌ Failed" >> $GITHUB_STEP_SUMMARY
|
|
1375
|
+
fi
|
|
1376
|
+
|
|
1295
1377
|
echo "" >> $GITHUB_STEP_SUMMARY
|
|
1296
1378
|
echo "## 📊 Security Posture" >> $GITHUB_STEP_SUMMARY
|
|
1297
1379
|
echo "" >> $GITHUB_STEP_SUMMARY
|
|
@@ -1328,7 +1410,14 @@ jobs:
|
|
|
1328
1410
|
fi
|
|
1329
1411
|
fi
|
|
1330
1412
|
|
|
1331
|
-
|
|
1413
|
+
if [ "${{ needs.zap_baseline.result }}" != "skipped" ]; then
|
|
1414
|
+
ACTIVE_TOOLS=$((ACTIVE_TOOLS + 1))
|
|
1415
|
+
if [ "${{ needs.zap_baseline.result }}" == "success" ]; then
|
|
1416
|
+
PASSED_TOOLS=$((PASSED_TOOLS + 1))
|
|
1417
|
+
fi
|
|
1418
|
+
fi
|
|
1419
|
+
|
|
1420
|
+
echo "- **Active Security Tools**: $ACTIVE_TOOLS / 5" >> $GITHUB_STEP_SUMMARY
|
|
1332
1421
|
echo "- **Passed Checks**: $PASSED_TOOLS / $ACTIVE_TOOLS" >> $GITHUB_STEP_SUMMARY
|
|
1333
1422
|
|
|
1334
1423
|
if [ $ACTIVE_TOOLS -gt 0 ]; then
|
|
@@ -1382,6 +1471,7 @@ jobs:
|
|
|
1382
1471
|
snyk,
|
|
1383
1472
|
secret_scanning,
|
|
1384
1473
|
license_compliance,
|
|
1474
|
+
zap_baseline,
|
|
1385
1475
|
]
|
|
1386
1476
|
steps:
|
|
1387
1477
|
- name: 📋 Validate compliance framework
|
|
@@ -1594,6 +1684,7 @@ jobs:
|
|
|
1594
1684
|
snyk,
|
|
1595
1685
|
secret_scanning,
|
|
1596
1686
|
license_compliance,
|
|
1687
|
+
zap_baseline,
|
|
1597
1688
|
compliance_validation,
|
|
1598
1689
|
]
|
|
1599
1690
|
steps:
|
|
@@ -1648,7 +1739,8 @@ jobs:
|
|
|
1648
1739
|
sonarcloud: '${{ needs.sonarcloud.result }}',
|
|
1649
1740
|
snyk: '${{ needs.snyk.result }}',
|
|
1650
1741
|
secret_scan: '${{ needs.secret_scanning.result }}',
|
|
1651
|
-
license_check: '${{ needs.license_compliance.result }}'
|
|
1742
|
+
license_check: '${{ needs.license_compliance.result }}',
|
|
1743
|
+
zap_baseline: '${{ needs.zap_baseline.result }}'
|
|
1652
1744
|
},
|
|
1653
1745
|
compliance: '${{ needs.compliance_validation.result }}'
|
|
1654
1746
|
},
|
|
@@ -1806,6 +1898,7 @@ jobs:
|
|
|
1806
1898
|
snyk,
|
|
1807
1899
|
secret_scanning,
|
|
1808
1900
|
license_compliance,
|
|
1901
|
+
zap_baseline,
|
|
1809
1902
|
]
|
|
1810
1903
|
steps:
|
|
1811
1904
|
- name: 📊 Generate performance report
|
|
@@ -1856,6 +1949,7 @@ jobs:
|
|
|
1856
1949
|
echo "| Snyk | ${{ needs.snyk.result }} | Security |" >> $GITHUB_STEP_SUMMARY
|
|
1857
1950
|
echo "| Secret Scan | ${{ needs.secret_scanning.result }} | Security |" >> $GITHUB_STEP_SUMMARY
|
|
1858
1951
|
echo "| License Check | ${{ needs.license_compliance.result }} | Security |" >> $GITHUB_STEP_SUMMARY
|
|
1952
|
+
echo "| ZAP Baseline | ${{ needs.zap_baseline.result }} | Security |" >> $GITHUB_STEP_SUMMARY
|
|
1859
1953
|
|
|
1860
1954
|
echo "" >> $GITHUB_STEP_SUMMARY
|
|
1861
1955
|
echo "## 💡 Performance Tips" >> $GITHUB_STEP_SUMMARY
|
|
@@ -1885,6 +1979,7 @@ jobs:
|
|
|
1885
1979
|
[ "${{ needs.snyk.result }}" != "skipped" ] && SECURITY_JOBS=$((SECURITY_JOBS + 1))
|
|
1886
1980
|
[ "${{ needs.secret_scanning.result }}" != "skipped" ] && SECURITY_JOBS=$((SECURITY_JOBS + 1))
|
|
1887
1981
|
[ "${{ needs.license_compliance.result }}" != "skipped" ] && SECURITY_JOBS=$((SECURITY_JOBS + 1))
|
|
1982
|
+
[ "${{ needs.zap_baseline.result }}" != "skipped" ] && SECURITY_JOBS=$((SECURITY_JOBS + 1))
|
|
1888
1983
|
|
|
1889
1984
|
echo "" >> $GITHUB_STEP_SUMMARY
|
|
1890
1985
|
echo "## 🚀 Optimization Metrics" >> $GITHUB_STEP_SUMMARY
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is managed by Lisa.
|
|
3
|
+
* Do not edit directly — changes will be overwritten on the next `lisa` run.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Jest Configuration - Shared Base
|
|
8
|
+
*
|
|
9
|
+
* Exports shared configuration pieces that can be imported by
|
|
10
|
+
* project-specific jest.config.ts files. Reduces duplication between
|
|
11
|
+
* typescript, expo, nestjs, and other project type configurations.
|
|
12
|
+
*
|
|
13
|
+
* @see https://jestjs.io/docs/configuration
|
|
14
|
+
* @module jest.base
|
|
15
|
+
*/
|
|
16
|
+
import type { Config } from "jest";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Default coverage thresholds used when not specified in project config.
|
|
20
|
+
* Projects can override via jest.thresholds.json.
|
|
21
|
+
*/
|
|
22
|
+
export const defaultThresholds: Config["coverageThreshold"] = {
|
|
23
|
+
global: {
|
|
24
|
+
statements: 70,
|
|
25
|
+
branches: 70,
|
|
26
|
+
functions: 70,
|
|
27
|
+
lines: 70,
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Default patterns to exclude from coverage collection.
|
|
33
|
+
* Common across all stacks — stack-specific configs extend this list.
|
|
34
|
+
*/
|
|
35
|
+
export const defaultCoverageExclusions: readonly string[] = [
|
|
36
|
+
"!**/*.d.ts",
|
|
37
|
+
"!**/index.ts",
|
|
38
|
+
"!**/node_modules/**",
|
|
39
|
+
"!**/dist/**",
|
|
40
|
+
"!**/*.test.ts",
|
|
41
|
+
"!**/*.spec.ts",
|
|
42
|
+
"!**/*.mock.ts",
|
|
43
|
+
"!**/test/**",
|
|
44
|
+
"!**/tests/**",
|
|
45
|
+
"!**/__tests__/**",
|
|
46
|
+
"!**/__mocks__/**",
|
|
47
|
+
];
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Merges project-specific threshold overrides into default thresholds.
|
|
51
|
+
* Allows projects to selectively raise or lower coverage requirements
|
|
52
|
+
* via jest.thresholds.json without replacing the entire threshold object.
|
|
53
|
+
*
|
|
54
|
+
* Spreads all top-level keys from both defaults and overrides (including
|
|
55
|
+
* per-path/per-file patterns like `"./src/api/": { branches: 80 }`).
|
|
56
|
+
* The `global` key receives special treatment: its properties are
|
|
57
|
+
* shallow-merged so individual metrics can be overridden without
|
|
58
|
+
* replacing the entire global object.
|
|
59
|
+
*
|
|
60
|
+
* @param defaults - Base thresholds from the stack config
|
|
61
|
+
* @param overrides - Project-specific overrides from jest.thresholds.json
|
|
62
|
+
* @returns Merged thresholds with overrides taking precedence
|
|
63
|
+
*/
|
|
64
|
+
export const mergeThresholds = (
|
|
65
|
+
defaults: Config["coverageThreshold"],
|
|
66
|
+
overrides: Config["coverageThreshold"]
|
|
67
|
+
): Config["coverageThreshold"] => ({
|
|
68
|
+
...defaults,
|
|
69
|
+
...overrides,
|
|
70
|
+
global: {
|
|
71
|
+
...(defaults?.global as Record<string, number>),
|
|
72
|
+
...(overrides?.global as Record<string, number>),
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Merges multiple Jest configs together with array concatenation and
|
|
78
|
+
* shallow object merging. Later configs take precedence for scalar values.
|
|
79
|
+
* Arrays are concatenated and deduplicated to allow additive composition.
|
|
80
|
+
*
|
|
81
|
+
* @param configs - Jest config objects to merge in order of precedence
|
|
82
|
+
* @returns Single merged Jest config
|
|
83
|
+
* @remarks Used by entry-point jest.config.ts files to combine stack config
|
|
84
|
+
* with project-local overrides without losing array values like testMatch
|
|
85
|
+
* or collectCoverageFrom.
|
|
86
|
+
*/
|
|
87
|
+
export const mergeConfigs = (...configs: Config[]): Config =>
|
|
88
|
+
configs.reduce(
|
|
89
|
+
(acc, config) =>
|
|
90
|
+
(Object.keys(config) as (keyof Config)[]).reduce((merged, key) => {
|
|
91
|
+
const accVal = acc[key];
|
|
92
|
+
const configVal = config[key];
|
|
93
|
+
|
|
94
|
+
const mergedValue =
|
|
95
|
+
Array.isArray(accVal) && Array.isArray(configVal)
|
|
96
|
+
? [...new Set([...accVal, ...configVal])]
|
|
97
|
+
: typeof accVal === "object" &&
|
|
98
|
+
accVal !== null &&
|
|
99
|
+
!Array.isArray(accVal) &&
|
|
100
|
+
typeof configVal === "object" &&
|
|
101
|
+
configVal !== null &&
|
|
102
|
+
!Array.isArray(configVal)
|
|
103
|
+
? {
|
|
104
|
+
...(accVal as Record<string, unknown>),
|
|
105
|
+
...(configVal as Record<string, unknown>),
|
|
106
|
+
}
|
|
107
|
+
: configVal;
|
|
108
|
+
|
|
109
|
+
return { ...merged, [key]: mergedValue };
|
|
110
|
+
}, acc),
|
|
111
|
+
{} as Config
|
|
112
|
+
);
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is managed by Lisa.
|
|
3
|
+
* Do not edit directly — changes will be overwritten on the next `lisa` run.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Jest Configuration - Main Entry Point (TypeScript)
|
|
8
|
+
*
|
|
9
|
+
* Imports the TypeScript-specific configuration and project-local customizations.
|
|
10
|
+
* Do not modify this file directly - use jest.config.local.ts for project-specific settings.
|
|
11
|
+
*
|
|
12
|
+
* Inheritance chain:
|
|
13
|
+
* jest.config.ts (this file)
|
|
14
|
+
* └── jest.typescript.ts
|
|
15
|
+
* └── jest.base.ts
|
|
16
|
+
*
|
|
17
|
+
* @see https://jestjs.io/docs/configuration
|
|
18
|
+
* @module jest.config
|
|
19
|
+
*/
|
|
20
|
+
import { mergeConfigs, mergeThresholds } from "./jest.base.ts";
|
|
21
|
+
import {
|
|
22
|
+
defaultThresholds,
|
|
23
|
+
getTypescriptJestConfig,
|
|
24
|
+
} from "./jest.typescript.ts";
|
|
25
|
+
|
|
26
|
+
import localConfig from "./jest.config.local.ts";
|
|
27
|
+
import thresholdsOverrides from "./jest.thresholds.json" with { type: "json" };
|
|
28
|
+
|
|
29
|
+
const thresholds = mergeThresholds(defaultThresholds, thresholdsOverrides);
|
|
30
|
+
|
|
31
|
+
export default mergeConfigs(
|
|
32
|
+
getTypescriptJestConfig({ thresholds }),
|
|
33
|
+
localConfig
|
|
34
|
+
);
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is managed by Lisa.
|
|
3
|
+
* Do not edit directly — changes will be overwritten on the next `lisa` run.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Jest Configuration - TypeScript Stack
|
|
8
|
+
*
|
|
9
|
+
* Provides TypeScript/Node-specific Jest configuration.
|
|
10
|
+
* Imports shared utilities from jest.base.ts.
|
|
11
|
+
* Stack-specific configs (expo, nestjs, cdk) should import and extend this.
|
|
12
|
+
*
|
|
13
|
+
* @see https://jestjs.io/docs/configuration
|
|
14
|
+
* @module jest.typescript
|
|
15
|
+
*/
|
|
16
|
+
import type { Config } from "jest";
|
|
17
|
+
|
|
18
|
+
import {
|
|
19
|
+
defaultCoverageExclusions,
|
|
20
|
+
defaultThresholds,
|
|
21
|
+
mergeConfigs,
|
|
22
|
+
mergeThresholds,
|
|
23
|
+
} from "./jest.base.ts";
|
|
24
|
+
|
|
25
|
+
// Re-export base utilities for stack-specific configs to use
|
|
26
|
+
export {
|
|
27
|
+
defaultCoverageExclusions,
|
|
28
|
+
defaultThresholds,
|
|
29
|
+
mergeConfigs,
|
|
30
|
+
mergeThresholds,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Options for configuring the TypeScript Jest config factory.
|
|
35
|
+
*/
|
|
36
|
+
interface TypescriptJestOptions {
|
|
37
|
+
/** Coverage thresholds (merged defaults + project overrides) */
|
|
38
|
+
readonly thresholds?: Config["coverageThreshold"];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Creates a Jest configuration for TypeScript/Node projects using ts-jest.
|
|
43
|
+
*
|
|
44
|
+
* @param options - Configuration options for threshold overrides
|
|
45
|
+
* @param options.thresholds - Coverage thresholds (merged defaults + project overrides)
|
|
46
|
+
* @returns Jest config object with ts-jest transform, ESM support, and coverage settings
|
|
47
|
+
* @remarks Uses ts-jest ESM preset for projects with "type": "module" in package.json.
|
|
48
|
+
* Projects needing CommonJS should override the preset in jest.config.local.ts.
|
|
49
|
+
*/
|
|
50
|
+
export const getTypescriptJestConfig = ({
|
|
51
|
+
thresholds = defaultThresholds,
|
|
52
|
+
}: TypescriptJestOptions = {}): Config => ({
|
|
53
|
+
preset: "ts-jest/presets/default-esm",
|
|
54
|
+
testEnvironment: "node",
|
|
55
|
+
testMatch: ["<rootDir>/tests/**/*.test.ts", "<rootDir>/src/**/*.test.ts"],
|
|
56
|
+
testPathIgnorePatterns: ["/node_modules/", "/dist/"],
|
|
57
|
+
moduleNameMapper: {
|
|
58
|
+
"^(\\.{1,2}/.*)\\.js$": "$1",
|
|
59
|
+
},
|
|
60
|
+
transform: {
|
|
61
|
+
"^.+\\.tsx?$": [
|
|
62
|
+
"ts-jest",
|
|
63
|
+
{
|
|
64
|
+
useESM: true,
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
},
|
|
68
|
+
extensionsToTreatAsEsm: [".ts"],
|
|
69
|
+
collectCoverageFrom: ["src/**/*.ts", ...defaultCoverageExclusions],
|
|
70
|
+
coverageThreshold: thresholds,
|
|
71
|
+
testTimeout: 10000,
|
|
72
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/tsconfig",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"strict": true,
|
|
5
|
+
"skipLibCheck": true,
|
|
6
|
+
"forceConsistentCasingInFileNames": true,
|
|
7
|
+
"esModuleInterop": true,
|
|
8
|
+
"resolveJsonModule": true,
|
|
9
|
+
"noImplicitReturns": true,
|
|
10
|
+
"noFallthroughCasesInSwitch": true,
|
|
11
|
+
"declaration": true,
|
|
12
|
+
"sourceMap": true,
|
|
13
|
+
"baseUrl": "./"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
"extends": "./tsconfig.json",
|
|
3
3
|
"compilerOptions": {
|
|
4
4
|
"rootDir": ".",
|
|
5
|
-
"noEmit": true
|
|
5
|
+
"noEmit": true,
|
|
6
|
+
"allowImportingTsExtensions": true
|
|
6
7
|
},
|
|
7
|
-
"include": ["src/**/*", "tests/**/*", "test/**/*", "*.config.ts", "eslint.*.ts"],
|
|
8
|
+
"include": ["src/**/*", "tests/**/*", "test/**/*", "*.config.ts", "eslint.*.ts", "jest.*.ts"],
|
|
8
9
|
"exclude": ["node_modules", "dist", "build"]
|
|
9
10
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Jest Configuration - Project-Local Customizations
|
|
3
|
+
*
|
|
4
|
+
* Add project-specific Jest settings here. This file is create-only,
|
|
5
|
+
* meaning Lisa will create it but never overwrite your customizations.
|
|
6
|
+
*
|
|
7
|
+
* Example:
|
|
8
|
+
* ```ts
|
|
9
|
+
* import type { Config } from "jest";
|
|
10
|
+
*
|
|
11
|
+
* const config: Config = {
|
|
12
|
+
* moduleNameMapper: {
|
|
13
|
+
* "^@/(.*)$": "<rootDir>/src/$1",
|
|
14
|
+
* },
|
|
15
|
+
* setupFiles: ["<rootDir>/jest.setup.ts"],
|
|
16
|
+
* };
|
|
17
|
+
*
|
|
18
|
+
* export default config;
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* @see https://jestjs.io/docs/configuration
|
|
22
|
+
* @module jest.config.local
|
|
23
|
+
*/
|
|
24
|
+
import type { Config } from "jest";
|
|
25
|
+
|
|
26
|
+
const config: Config = {
|
|
27
|
+
// Add project-specific settings here
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export default config;
|