project-shield 1.1.2 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +518 -518
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -1
- package/dist/output/badge.js +24 -24
- package/dist/output/fixit.js +44 -44
- package/package.json +52 -52
- package/rules/v1.0.0.json +248 -248
package/dist/index.js
CHANGED
|
@@ -64,6 +64,7 @@ program
|
|
|
64
64
|
.option('-r, --ruleset <path>', 'Path to ruleset JSON file')
|
|
65
65
|
.option('-b, --badge <path>', 'Output path for SVG badge', '')
|
|
66
66
|
.option('--fix', 'Show fix-it remediation guides', false)
|
|
67
|
+
.option('--ci', 'CI mode: GitHub Actions annotations + non-interactive', false)
|
|
67
68
|
.option('--evidence <path>', 'Output path for evidence pack (JSON + PDF)')
|
|
68
69
|
.action(async (targetPath, options) => {
|
|
69
70
|
try {
|
|
@@ -108,6 +109,32 @@ program
|
|
|
108
109
|
console.log((0, fixit_js_1.formatFixitTerminal)(guides, gate.canSeeFullFixit));
|
|
109
110
|
}
|
|
110
111
|
}
|
|
112
|
+
// CI annotations (GitHub Actions)
|
|
113
|
+
const isCI = options.ci || !!process.env.GITHUB_ACTIONS;
|
|
114
|
+
if (isCI) {
|
|
115
|
+
for (const s of result.secrets) {
|
|
116
|
+
console.log(`::error file=${s.file},line=${s.line}::${s.type} ${s.description}`);
|
|
117
|
+
}
|
|
118
|
+
for (const m of result.mcp) {
|
|
119
|
+
if (m.overallSeverity === 'critical') {
|
|
120
|
+
console.log(`::error file=${m.file}::MCP check failed (${m.failedCount} issues)`);
|
|
121
|
+
}
|
|
122
|
+
else if (m.overallSeverity === 'warning') {
|
|
123
|
+
console.log(`::warning file=${m.file}::MCP check warning (${m.failedCount} issues)`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
for (const inj of result.injection) {
|
|
127
|
+
console.log(`::error file=${inj.file},line=${inj.line}::${inj.type} ${inj.description}`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// Pro upgrade prompt (Free tier only, when meaningful)
|
|
131
|
+
if (!gate.isPro && !isCI) {
|
|
132
|
+
const hasFindingsWorthUpgrading = result.summary.critical > 0 || result.summary.confirmedPii > 0;
|
|
133
|
+
if (hasFindingsWorthUpgrading) {
|
|
134
|
+
console.log('\n\x1b[33m💡 Upgrade to Pro for PDF reports, Evidence Packs, and client-ready proof.\x1b[0m');
|
|
135
|
+
console.log('\x1b[33m https://shield.codemeant.dev/#pricing\x1b[0m\n');
|
|
136
|
+
}
|
|
137
|
+
}
|
|
111
138
|
// Evidence Pack generation (Pro only)
|
|
112
139
|
if (options.evidence) {
|
|
113
140
|
if (!gate.canGenerateEvidence) {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,yCAAoC;AACpC,gDAAkC;AAClC,mDAA2C;AAC3C,uDAAqD;AACrD,iDAAoD;AACpD,+CAAkD;AAClD,iDAAiD;AACjD,gDAA+E;AAC/E,sDAA8E;AAC9E,gDAAyF;AACzF,sDAAmG;AACnG,yDAIiC;AACjC,yDAAyD;AACzD,iDAAyD;AACzD,+CAAmD;AACnD,uDAA0F;AAE1F,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,gBAAgB,CAAC;KACtB,WAAW,CAAC,8CAA8C,CAAC;KAC3D,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,0DAA0D,CAAC;KACvE,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;KAClC,MAAM,CAAC,uBAAuB,EAAE,kCAAkC,EAAE,UAAU,CAAC;KAC/E,MAAM,CAAC,qBAAqB,EAAE,4BAA4B,CAAC;KAC3D,MAAM,CAAC,sBAAsB,EAAE,2BAA2B,CAAC;KAC3D,MAAM,CAAC,oBAAoB,EAAE,2BAA2B,EAAE,EAAE,CAAC;KAC7D,MAAM,CAAC,OAAO,EAAE,gCAAgC,EAAE,KAAK,CAAC;KACxD,MAAM,CAAC,mBAAmB,EAAE,4CAA4C,CAAC;KACzE,MAAM,CAAC,KAAK,EAAE,UAAkB,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/output/badge.js
CHANGED
|
@@ -71,36 +71,36 @@ function generateBadge(score, lockStatus, options = { isPro: false }) {
|
|
|
71
71
|
const totalWidth = labelWidth + valueWidth;
|
|
72
72
|
const watermark = options.isPro ? '' : generateWatermark(labelWidth, totalWidth);
|
|
73
73
|
const disclaimer = 'This badge is informational only. It does not guarantee the absence of security vulnerabilities.';
|
|
74
|
-
return `<svg xmlns="http://www.w3.org/2000/svg" width="${totalWidth}" height="20" role="img" aria-label="${label}: ${value}">
|
|
75
|
-
<metadata>${disclaimer}</metadata>
|
|
76
|
-
<title>${label}: ${value}</title>
|
|
77
|
-
<linearGradient id="s" x2="0" y2="100%">
|
|
78
|
-
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
|
|
79
|
-
<stop offset="1" stop-opacity=".1"/>
|
|
80
|
-
</linearGradient>
|
|
81
|
-
<clipPath id="r">
|
|
82
|
-
<rect width="${totalWidth}" height="20" rx="3" fill="#fff"/>
|
|
83
|
-
</clipPath>
|
|
84
|
-
<g clip-path="url(#r)">
|
|
85
|
-
<rect width="${labelWidth}" height="20" fill="#555"/>
|
|
86
|
-
<rect x="${labelWidth}" width="${valueWidth}" height="20" fill="${color}"/>
|
|
87
|
-
<rect width="${totalWidth}" height="20" fill="url(#s)"/>
|
|
88
|
-
</g>
|
|
89
|
-
<g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="11">
|
|
90
|
-
<text aria-hidden="true" x="${labelWidth / 2}" y="15" fill="#010101" fill-opacity=".3">${label}</text>
|
|
91
|
-
<text x="${labelWidth / 2}" y="14">${label}</text>
|
|
92
|
-
<text aria-hidden="true" x="${labelWidth + valueWidth / 2}" y="15" fill="#010101" fill-opacity=".3">${value}</text>
|
|
93
|
-
<text x="${labelWidth + valueWidth / 2}" y="14">${value}</text>
|
|
94
|
-
</g>${watermark}
|
|
74
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" width="${totalWidth}" height="20" role="img" aria-label="${label}: ${value}">
|
|
75
|
+
<metadata>${disclaimer}</metadata>
|
|
76
|
+
<title>${label}: ${value}</title>
|
|
77
|
+
<linearGradient id="s" x2="0" y2="100%">
|
|
78
|
+
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
|
|
79
|
+
<stop offset="1" stop-opacity=".1"/>
|
|
80
|
+
</linearGradient>
|
|
81
|
+
<clipPath id="r">
|
|
82
|
+
<rect width="${totalWidth}" height="20" rx="3" fill="#fff"/>
|
|
83
|
+
</clipPath>
|
|
84
|
+
<g clip-path="url(#r)">
|
|
85
|
+
<rect width="${labelWidth}" height="20" fill="#555"/>
|
|
86
|
+
<rect x="${labelWidth}" width="${valueWidth}" height="20" fill="${color}"/>
|
|
87
|
+
<rect width="${totalWidth}" height="20" fill="url(#s)"/>
|
|
88
|
+
</g>
|
|
89
|
+
<g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="11">
|
|
90
|
+
<text aria-hidden="true" x="${labelWidth / 2}" y="15" fill="#010101" fill-opacity=".3">${label}</text>
|
|
91
|
+
<text x="${labelWidth / 2}" y="14">${label}</text>
|
|
92
|
+
<text aria-hidden="true" x="${labelWidth + valueWidth / 2}" y="15" fill="#010101" fill-opacity=".3">${value}</text>
|
|
93
|
+
<text x="${labelWidth + valueWidth / 2}" y="14">${value}</text>
|
|
94
|
+
</g>${watermark}
|
|
95
95
|
</svg>`;
|
|
96
96
|
}
|
|
97
97
|
/**
|
|
98
98
|
* Generate watermark text for free tier badges.
|
|
99
99
|
*/
|
|
100
100
|
function generateWatermark(labelWidth, totalWidth) {
|
|
101
|
-
return `
|
|
102
|
-
<g fill="#fff" fill-opacity="0.15" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" font-size="8" transform="rotate(-20, ${totalWidth / 2}, 10)">
|
|
103
|
-
<text x="${totalWidth / 2}" y="12">FREE</text>
|
|
101
|
+
return `
|
|
102
|
+
<g fill="#fff" fill-opacity="0.15" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" font-size="8" transform="rotate(-20, ${totalWidth / 2}, 10)">
|
|
103
|
+
<text x="${totalWidth / 2}" y="12">FREE</text>
|
|
104
104
|
</g>`;
|
|
105
105
|
}
|
|
106
106
|
/**
|
package/dist/output/fixit.js
CHANGED
|
@@ -17,9 +17,9 @@ const FIXIT_GUIDES = {
|
|
|
17
17
|
'Delete the old access key after confirming everything works',
|
|
18
18
|
'Store new keys in AWS Secrets Manager or environment variables',
|
|
19
19
|
],
|
|
20
|
-
code: `# Using AWS CLI to rotate keys
|
|
21
|
-
aws iam create-access-key --user-name YOUR_USER
|
|
22
|
-
aws iam update-access-key --access-key-id OLD_KEY_ID --status Inactive
|
|
20
|
+
code: `# Using AWS CLI to rotate keys
|
|
21
|
+
aws iam create-access-key --user-name YOUR_USER
|
|
22
|
+
aws iam update-access-key --access-key-id OLD_KEY_ID --status Inactive
|
|
23
23
|
aws iam delete-access-key --access-key-id OLD_KEY_ID`,
|
|
24
24
|
severity: 'critical',
|
|
25
25
|
references: [
|
|
@@ -35,10 +35,10 @@ aws iam delete-access-key --access-key-id OLD_KEY_ID`,
|
|
|
35
35
|
'Update your application with the new key',
|
|
36
36
|
'Use environment variables, never hardcode keys',
|
|
37
37
|
],
|
|
38
|
-
code: `# Store in environment variable
|
|
39
|
-
export STRIPE_SECRET_KEY=sk_live_new_key_here
|
|
40
|
-
|
|
41
|
-
# In your app, read from env
|
|
38
|
+
code: `# Store in environment variable
|
|
39
|
+
export STRIPE_SECRET_KEY=sk_live_new_key_here
|
|
40
|
+
|
|
41
|
+
# In your app, read from env
|
|
42
42
|
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);`,
|
|
43
43
|
severity: 'critical',
|
|
44
44
|
references: [
|
|
@@ -55,12 +55,12 @@ const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);`,
|
|
|
55
55
|
'Revoke the old key from all services that used it',
|
|
56
56
|
'Use a secrets manager for key storage',
|
|
57
57
|
],
|
|
58
|
-
code: `# Remove from git history
|
|
59
|
-
git rm --cached path/to/private_key.pem
|
|
60
|
-
echo "*.pem" >> .gitignore
|
|
61
|
-
echo "*.key" >> .gitignore
|
|
62
|
-
|
|
63
|
-
# Generate new key
|
|
58
|
+
code: `# Remove from git history
|
|
59
|
+
git rm --cached path/to/private_key.pem
|
|
60
|
+
echo "*.pem" >> .gitignore
|
|
61
|
+
echo "*.key" >> .gitignore
|
|
62
|
+
|
|
63
|
+
# Generate new key
|
|
64
64
|
openssl genrsa -out new_private_key.pem 4096`,
|
|
65
65
|
severity: 'critical',
|
|
66
66
|
references: [
|
|
@@ -75,10 +75,10 @@ openssl genrsa -out new_private_key.pem 4096`,
|
|
|
75
75
|
'Add the file to .gitignore if it contains secrets',
|
|
76
76
|
'Rotate the exposed secret',
|
|
77
77
|
],
|
|
78
|
-
code: `# .env file (add to .gitignore!)
|
|
79
|
-
SECRET_VALUE=your_secret_here
|
|
80
|
-
|
|
81
|
-
# In your code
|
|
78
|
+
code: `# .env file (add to .gitignore!)
|
|
79
|
+
SECRET_VALUE=your_secret_here
|
|
80
|
+
|
|
81
|
+
# In your code
|
|
82
82
|
const secret = process.env.SECRET_VALUE;`,
|
|
83
83
|
severity: 'warning',
|
|
84
84
|
references: [
|
|
@@ -93,9 +93,9 @@ const secret = process.env.SECRET_VALUE;`,
|
|
|
93
93
|
'If this is test data, use the official test RRN range',
|
|
94
94
|
'Review data handling for 개인정보보호법 compliance',
|
|
95
95
|
],
|
|
96
|
-
code: `// Masking function
|
|
97
|
-
function maskRRN(rrn: string): string {
|
|
98
|
-
return rrn.replace(/(\\d{6}[-]?\\d)\\d{6}/, '$1******');
|
|
96
|
+
code: `// Masking function
|
|
97
|
+
function maskRRN(rrn: string): string {
|
|
98
|
+
return rrn.replace(/(\\d{6}[-]?\\d)\\d{6}/, '$1******');
|
|
99
99
|
}`,
|
|
100
100
|
severity: 'critical',
|
|
101
101
|
references: [
|
|
@@ -110,10 +110,10 @@ function maskRRN(rrn: string): string {
|
|
|
110
110
|
'Never store full card numbers — use tokenization',
|
|
111
111
|
'Review PCI-DSS compliance requirements',
|
|
112
112
|
],
|
|
113
|
-
code: `// Use test card numbers for development
|
|
114
|
-
const TEST_CARDS = {
|
|
115
|
-
visa: '4111111111111111',
|
|
116
|
-
mastercard: '5555555555554444',
|
|
113
|
+
code: `// Use test card numbers for development
|
|
114
|
+
const TEST_CARDS = {
|
|
115
|
+
visa: '4111111111111111',
|
|
116
|
+
mastercard: '5555555555554444',
|
|
117
117
|
};`,
|
|
118
118
|
severity: 'critical',
|
|
119
119
|
references: [
|
|
@@ -127,12 +127,12 @@ const TEST_CARDS = {
|
|
|
127
127
|
'Use OAuth 2.0 or API key authentication',
|
|
128
128
|
'Never expose MCP endpoints without authentication',
|
|
129
129
|
],
|
|
130
|
-
code: `{
|
|
131
|
-
"auth": {
|
|
132
|
-
"type": "oauth2",
|
|
133
|
-
"clientId": "\${MCP_CLIENT_ID}",
|
|
134
|
-
"clientSecret": "\${MCP_CLIENT_SECRET}"
|
|
135
|
-
}
|
|
130
|
+
code: `{
|
|
131
|
+
"auth": {
|
|
132
|
+
"type": "oauth2",
|
|
133
|
+
"clientId": "\${MCP_CLIENT_ID}",
|
|
134
|
+
"clientSecret": "\${MCP_CLIENT_SECRET}"
|
|
135
|
+
}
|
|
136
136
|
}`,
|
|
137
137
|
severity: 'critical',
|
|
138
138
|
references: [
|
|
@@ -146,10 +146,10 @@ const TEST_CARDS = {
|
|
|
146
146
|
'Use ${ENV_VAR} syntax in MCP configuration',
|
|
147
147
|
'Store actual values in .env (added to .gitignore)',
|
|
148
148
|
],
|
|
149
|
-
code: `// Before (BAD)
|
|
150
|
-
{ "apiKey": "sk-live-abc123" }
|
|
151
|
-
|
|
152
|
-
// After (GOOD)
|
|
149
|
+
code: `// Before (BAD)
|
|
150
|
+
{ "apiKey": "sk-live-abc123" }
|
|
151
|
+
|
|
152
|
+
// After (GOOD)
|
|
153
153
|
{ "apiKey": "\${OPENAI_API_KEY}" }`,
|
|
154
154
|
severity: 'critical',
|
|
155
155
|
},
|
|
@@ -161,10 +161,10 @@ const TEST_CARDS = {
|
|
|
161
161
|
'Limit network access to required endpoints only',
|
|
162
162
|
'Remove --privileged mode if not absolutely necessary',
|
|
163
163
|
],
|
|
164
|
-
code: `// Before (BAD)
|
|
165
|
-
{ "allowedPaths": ["/"] }
|
|
166
|
-
|
|
167
|
-
// After (GOOD)
|
|
164
|
+
code: `// Before (BAD)
|
|
165
|
+
{ "allowedPaths": ["/"] }
|
|
166
|
+
|
|
167
|
+
// After (GOOD)
|
|
168
168
|
{ "allowedPaths": ["/home/user/project"] }`,
|
|
169
169
|
severity: 'critical',
|
|
170
170
|
},
|
|
@@ -176,12 +176,12 @@ const TEST_CARDS = {
|
|
|
176
176
|
'If in AI tool descriptions: ensure descriptions are concise and factual',
|
|
177
177
|
'Add input validation for any user-provided text that reaches AI models',
|
|
178
178
|
],
|
|
179
|
-
code: `// Input sanitization example
|
|
180
|
-
function sanitizeForAI(input: string): string {
|
|
181
|
-
// Remove common injection patterns
|
|
182
|
-
return input
|
|
183
|
-
.replace(/ignore\\s+(all\\s+)?previous\\s+instructions/gi, '[FILTERED]')
|
|
184
|
-
.replace(/you\\s+are\\s+now/gi, '[FILTERED]');
|
|
179
|
+
code: `// Input sanitization example
|
|
180
|
+
function sanitizeForAI(input: string): string {
|
|
181
|
+
// Remove common injection patterns
|
|
182
|
+
return input
|
|
183
|
+
.replace(/ignore\\s+(all\\s+)?previous\\s+instructions/gi, '[FILTERED]')
|
|
184
|
+
.replace(/you\\s+are\\s+now/gi, '[FILTERED]');
|
|
185
185
|
}`,
|
|
186
186
|
severity: 'critical',
|
|
187
187
|
references: [
|
package/package.json
CHANGED
|
@@ -1,52 +1,52 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "project-shield",
|
|
3
|
-
"version": "1.1.
|
|
4
|
-
"description": "Security scanner for AI coders and MCP users — detects API keys, secrets, and PII",
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"bin": {
|
|
7
|
-
"project-shield": "dist/index.js"
|
|
8
|
-
},
|
|
9
|
-
"scripts": {
|
|
10
|
-
"build": "tsc",
|
|
11
|
-
"typecheck": "tsc --noEmit",
|
|
12
|
-
"lint": "eslint src/",
|
|
13
|
-
"test": "vitest run",
|
|
14
|
-
"test:watch": "vitest",
|
|
15
|
-
"gate": "npm run typecheck && npm run lint && npm run test && npm run build",
|
|
16
|
-
"prepublishOnly": "npm run gate"
|
|
17
|
-
},
|
|
18
|
-
"files": [
|
|
19
|
-
"dist/",
|
|
20
|
-
"rules/"
|
|
21
|
-
],
|
|
22
|
-
"keywords": [
|
|
23
|
-
"security",
|
|
24
|
-
"scanner",
|
|
25
|
-
"secrets",
|
|
26
|
-
"pii",
|
|
27
|
-
"mcp",
|
|
28
|
-
"injection",
|
|
29
|
-
"prompt-injection",
|
|
30
|
-
"ai-security",
|
|
31
|
-
"claude",
|
|
32
|
-
"llm"
|
|
33
|
-
],
|
|
34
|
-
"author": "",
|
|
35
|
-
"license": "MIT",
|
|
36
|
-
"type": "commonjs",
|
|
37
|
-
"dependencies": {
|
|
38
|
-
"chalk": "^5.6.2",
|
|
39
|
-
"commander": "^14.0.3",
|
|
40
|
-
"glob": "^13.0.3",
|
|
41
|
-
"pdfkit": "^0.17.2"
|
|
42
|
-
},
|
|
43
|
-
"devDependencies": {
|
|
44
|
-
"@types/node": "^25.2.3",
|
|
45
|
-
"@types/pdfkit": "^0.17.5",
|
|
46
|
-
"@typescript-eslint/eslint-plugin": "^8.55.0",
|
|
47
|
-
"@typescript-eslint/parser": "^8.55.0",
|
|
48
|
-
"eslint": "^9.39.2",
|
|
49
|
-
"typescript": "^5.9.3",
|
|
50
|
-
"vitest": "^4.0.18"
|
|
51
|
-
}
|
|
52
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "project-shield",
|
|
3
|
+
"version": "1.1.3",
|
|
4
|
+
"description": "Security scanner for AI coders and MCP users — detects API keys, secrets, and PII",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"project-shield": "dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc",
|
|
11
|
+
"typecheck": "tsc --noEmit",
|
|
12
|
+
"lint": "eslint src/",
|
|
13
|
+
"test": "vitest run",
|
|
14
|
+
"test:watch": "vitest",
|
|
15
|
+
"gate": "npm run typecheck && npm run lint && npm run test && npm run build",
|
|
16
|
+
"prepublishOnly": "npm run gate"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist/",
|
|
20
|
+
"rules/"
|
|
21
|
+
],
|
|
22
|
+
"keywords": [
|
|
23
|
+
"security",
|
|
24
|
+
"scanner",
|
|
25
|
+
"secrets",
|
|
26
|
+
"pii",
|
|
27
|
+
"mcp",
|
|
28
|
+
"injection",
|
|
29
|
+
"prompt-injection",
|
|
30
|
+
"ai-security",
|
|
31
|
+
"claude",
|
|
32
|
+
"llm"
|
|
33
|
+
],
|
|
34
|
+
"author": "",
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"type": "commonjs",
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"chalk": "^5.6.2",
|
|
39
|
+
"commander": "^14.0.3",
|
|
40
|
+
"glob": "^13.0.3",
|
|
41
|
+
"pdfkit": "^0.17.2"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@types/node": "^25.2.3",
|
|
45
|
+
"@types/pdfkit": "^0.17.5",
|
|
46
|
+
"@typescript-eslint/eslint-plugin": "^8.55.0",
|
|
47
|
+
"@typescript-eslint/parser": "^8.55.0",
|
|
48
|
+
"eslint": "^9.39.2",
|
|
49
|
+
"typescript": "^5.9.3",
|
|
50
|
+
"vitest": "^4.0.18"
|
|
51
|
+
}
|
|
52
|
+
}
|