pastoralist 1.7.2 → 1.7.4
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 +165 -0
- package/dist/config/constants.d.ts +1 -0
- package/dist/config/index.d.ts +158 -0
- package/dist/config/loader.d.ts +4 -0
- package/dist/index.js +122 -100
- package/dist/interfaces.d.ts +4 -0
- package/dist/scripts.d.ts +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -294,6 +294,171 @@ For detailed information about using Pastoralist in workspace/monorepo environme
|
|
|
294
294
|
|
|
295
295
|
---
|
|
296
296
|
|
|
297
|
+
## Configuration
|
|
298
|
+
|
|
299
|
+
Pastoralist supports multiple configuration methods to fit your project's needs. Configuration can be defined in external files or directly in your `package.json`.
|
|
300
|
+
|
|
301
|
+
### Configuration Files
|
|
302
|
+
|
|
303
|
+
Pastoralist searches for configuration files in this order (first found wins):
|
|
304
|
+
|
|
305
|
+
1. `.pastoralistrc` (JSON format)
|
|
306
|
+
2. `.pastoralistrc.json`
|
|
307
|
+
3. `pastoralist.json`
|
|
308
|
+
4. `pastoralist.config.js`
|
|
309
|
+
5. `pastoralist.config.ts`
|
|
310
|
+
|
|
311
|
+
**Example `.pastoralistrc.json`:**
|
|
312
|
+
|
|
313
|
+
```json
|
|
314
|
+
{
|
|
315
|
+
"checkSecurity": true,
|
|
316
|
+
"depPaths": "workspaces",
|
|
317
|
+
"security": {
|
|
318
|
+
"provider": "osv",
|
|
319
|
+
"severityThreshold": "medium"
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
**Example `pastoralist.config.js`:**
|
|
325
|
+
|
|
326
|
+
```js
|
|
327
|
+
module.exports = {
|
|
328
|
+
checkSecurity: true,
|
|
329
|
+
depPaths: ["packages/*/package.json", "apps/*/package.json"],
|
|
330
|
+
security: {
|
|
331
|
+
provider: "osv",
|
|
332
|
+
severityThreshold: "high",
|
|
333
|
+
excludePackages: ["@types/*"]
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
**Example `pastoralist.config.ts`:**
|
|
339
|
+
|
|
340
|
+
```ts
|
|
341
|
+
import { PastoralistConfig } from 'pastoralist';
|
|
342
|
+
|
|
343
|
+
const config: PastoralistConfig = {
|
|
344
|
+
checkSecurity: true,
|
|
345
|
+
depPaths: "workspaces",
|
|
346
|
+
security: {
|
|
347
|
+
provider: "osv",
|
|
348
|
+
severityThreshold: "critical"
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
export default config;
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
### Configuration Priority
|
|
356
|
+
|
|
357
|
+
When both external config files and `package.json` configuration exist:
|
|
358
|
+
|
|
359
|
+
1. **External config** provides base settings
|
|
360
|
+
2. **`package.json`** overrides top-level fields
|
|
361
|
+
3. **Nested objects** (like `security`) are deep merged
|
|
362
|
+
|
|
363
|
+
**Example:**
|
|
364
|
+
|
|
365
|
+
```js
|
|
366
|
+
// .pastoralistrc.json
|
|
367
|
+
{
|
|
368
|
+
"checkSecurity": true,
|
|
369
|
+
"depPaths": "workspaces",
|
|
370
|
+
"security": {
|
|
371
|
+
"provider": "osv",
|
|
372
|
+
"severityThreshold": "medium"
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// package.json
|
|
377
|
+
{
|
|
378
|
+
"pastoralist": {
|
|
379
|
+
"security": {
|
|
380
|
+
"severityThreshold": "high" // Overrides "medium" from .pastoralistrc.json
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// Effective config:
|
|
386
|
+
{
|
|
387
|
+
"checkSecurity": true,
|
|
388
|
+
"depPaths": "workspaces",
|
|
389
|
+
"security": {
|
|
390
|
+
"provider": "osv",
|
|
391
|
+
"severityThreshold": "high" // From package.json
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
### Configuration Options
|
|
397
|
+
|
|
398
|
+
| Option | Type | Description |
|
|
399
|
+
|--------|------|-------------|
|
|
400
|
+
| `checkSecurity` | `boolean` | Enable security vulnerability scanning |
|
|
401
|
+
| `depPaths` | `"workspace"` \| `"workspaces"` \| `string[]` | Paths to scan for dependencies in monorepos |
|
|
402
|
+
| `appendix` | `object` | Auto-generated dependency tracking (managed by Pastoralist) |
|
|
403
|
+
| `overridePaths` | `object` | Manual override tracking for specific paths |
|
|
404
|
+
| `resolutionPaths` | `object` | Manual resolution tracking for specific paths |
|
|
405
|
+
| `security` | `object` | Security scanning configuration (see below) |
|
|
406
|
+
|
|
407
|
+
#### Security Configuration
|
|
408
|
+
|
|
409
|
+
| Option | Type | Description |
|
|
410
|
+
|--------|------|-------------|
|
|
411
|
+
| `enabled` | `boolean` | Enable/disable security checks |
|
|
412
|
+
| `provider` | `"osv"` \| `"github"` \| `"snyk"` \| `"npm"` \| `"socket"` | Security provider (currently only OSV) |
|
|
413
|
+
| `autoFix` | `boolean` | Automatically apply security fixes |
|
|
414
|
+
| `interactive` | `boolean` | Use interactive mode for security fixes |
|
|
415
|
+
| `securityProviderToken` | `string` | API token for providers that require auth |
|
|
416
|
+
| `severityThreshold` | `"low"` \| `"medium"` \| `"high"` \| `"critical"` | Minimum severity level to report |
|
|
417
|
+
| `excludePackages` | `string[]` | Packages to exclude from security checks |
|
|
418
|
+
| `hasWorkspaceSecurityChecks` | `boolean` | Include workspace packages in scans |
|
|
419
|
+
|
|
420
|
+
### Security Tracking in Appendix
|
|
421
|
+
|
|
422
|
+
When security vulnerabilities are detected and fixed, Pastoralist tracks this information in the appendix ledger:
|
|
423
|
+
|
|
424
|
+
```js
|
|
425
|
+
"pastoralist": {
|
|
426
|
+
"appendix": {
|
|
427
|
+
"lodash@4.17.21": {
|
|
428
|
+
"dependents": {
|
|
429
|
+
"my-app": "lodash@^4.17.0"
|
|
430
|
+
},
|
|
431
|
+
"ledger": {
|
|
432
|
+
"addedDate": "2024-01-15T10:30:00.000Z",
|
|
433
|
+
"reason": "Security vulnerability CVE-2021-23337",
|
|
434
|
+
"securityChecked": true,
|
|
435
|
+
"securityCheckDate": "2024-01-15T10:30:00.000Z",
|
|
436
|
+
"securityProvider": "osv"
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
The ledger tracks:
|
|
444
|
+
- `addedDate`: When the override was first added
|
|
445
|
+
- `reason`: Why the override was needed (e.g., security issue description)
|
|
446
|
+
- `securityChecked`: Whether a security check was performed
|
|
447
|
+
- `securityCheckDate`: When the last security check occurred
|
|
448
|
+
- `securityProvider`: Which provider detected the vulnerability
|
|
449
|
+
|
|
450
|
+
This allows you to see at a glance which packages were overridden due to security issues and when they were last verified.
|
|
451
|
+
|
|
452
|
+
### Best Practices
|
|
453
|
+
|
|
454
|
+
1. **Use external config files** for shared settings across teams
|
|
455
|
+
2. **Use `package.json`** for project-specific overrides
|
|
456
|
+
3. **Commit config files** to version control
|
|
457
|
+
4. **Use `depPaths: "workspaces"`** for most monorepos
|
|
458
|
+
5. **Enable security checks** in CI/CD pipelines with `--checkSecurity`
|
|
459
|
+
|
|
460
|
+
---
|
|
461
|
+
|
|
297
462
|
## Setup
|
|
298
463
|
|
|
299
464
|
> #### Okay! Hopefully the breakdowns above were clear enough on why you might want to use Pastoralist!
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const CONFIG_FILES: readonly [".pastoralistrc", ".pastoralistrc.json", "pastoralist.json", "pastoralist.config.js", "pastoralist.config.ts"];
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const AppendixItemSchema: z.ZodObject<{
|
|
3
|
+
rootDeps: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
4
|
+
dependents: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
5
|
+
patches: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
6
|
+
ledger: z.ZodOptional<z.ZodObject<{
|
|
7
|
+
addedDate: z.ZodString;
|
|
8
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
9
|
+
securityChecked: z.ZodOptional<z.ZodBoolean>;
|
|
10
|
+
securityCheckDate: z.ZodOptional<z.ZodString>;
|
|
11
|
+
securityProvider: z.ZodOptional<z.ZodEnum<{
|
|
12
|
+
npm: "npm";
|
|
13
|
+
osv: "osv";
|
|
14
|
+
github: "github";
|
|
15
|
+
snyk: "snyk";
|
|
16
|
+
socket: "socket";
|
|
17
|
+
}>>;
|
|
18
|
+
}, z.core.$strip>>;
|
|
19
|
+
}, z.core.$strip>;
|
|
20
|
+
export declare const AppendixSchema: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
21
|
+
rootDeps: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
22
|
+
dependents: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
23
|
+
patches: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
24
|
+
ledger: z.ZodOptional<z.ZodObject<{
|
|
25
|
+
addedDate: z.ZodString;
|
|
26
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
27
|
+
securityChecked: z.ZodOptional<z.ZodBoolean>;
|
|
28
|
+
securityCheckDate: z.ZodOptional<z.ZodString>;
|
|
29
|
+
securityProvider: z.ZodOptional<z.ZodEnum<{
|
|
30
|
+
npm: "npm";
|
|
31
|
+
osv: "osv";
|
|
32
|
+
github: "github";
|
|
33
|
+
snyk: "snyk";
|
|
34
|
+
socket: "socket";
|
|
35
|
+
}>>;
|
|
36
|
+
}, z.core.$strip>>;
|
|
37
|
+
}, z.core.$strip>>;
|
|
38
|
+
export declare const SecurityProviderSchema: z.ZodEnum<{
|
|
39
|
+
npm: "npm";
|
|
40
|
+
osv: "osv";
|
|
41
|
+
github: "github";
|
|
42
|
+
snyk: "snyk";
|
|
43
|
+
socket: "socket";
|
|
44
|
+
}>;
|
|
45
|
+
export declare const SeverityThresholdSchema: z.ZodEnum<{
|
|
46
|
+
high: "high";
|
|
47
|
+
medium: "medium";
|
|
48
|
+
low: "low";
|
|
49
|
+
critical: "critical";
|
|
50
|
+
}>;
|
|
51
|
+
export declare const SecurityConfigSchema: z.ZodObject<{
|
|
52
|
+
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
53
|
+
provider: z.ZodOptional<z.ZodEnum<{
|
|
54
|
+
npm: "npm";
|
|
55
|
+
osv: "osv";
|
|
56
|
+
github: "github";
|
|
57
|
+
snyk: "snyk";
|
|
58
|
+
socket: "socket";
|
|
59
|
+
}>>;
|
|
60
|
+
autoFix: z.ZodOptional<z.ZodBoolean>;
|
|
61
|
+
interactive: z.ZodOptional<z.ZodBoolean>;
|
|
62
|
+
securityProviderToken: z.ZodOptional<z.ZodString>;
|
|
63
|
+
severityThreshold: z.ZodOptional<z.ZodEnum<{
|
|
64
|
+
high: "high";
|
|
65
|
+
medium: "medium";
|
|
66
|
+
low: "low";
|
|
67
|
+
critical: "critical";
|
|
68
|
+
}>>;
|
|
69
|
+
excludePackages: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
70
|
+
hasWorkspaceSecurityChecks: z.ZodOptional<z.ZodBoolean>;
|
|
71
|
+
}, z.core.$strip>;
|
|
72
|
+
export declare const PastoralistConfigSchema: z.ZodObject<{
|
|
73
|
+
appendix: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
74
|
+
rootDeps: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
75
|
+
dependents: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
76
|
+
patches: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
77
|
+
ledger: z.ZodOptional<z.ZodObject<{
|
|
78
|
+
addedDate: z.ZodString;
|
|
79
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
80
|
+
securityChecked: z.ZodOptional<z.ZodBoolean>;
|
|
81
|
+
securityCheckDate: z.ZodOptional<z.ZodString>;
|
|
82
|
+
securityProvider: z.ZodOptional<z.ZodEnum<{
|
|
83
|
+
npm: "npm";
|
|
84
|
+
osv: "osv";
|
|
85
|
+
github: "github";
|
|
86
|
+
snyk: "snyk";
|
|
87
|
+
socket: "socket";
|
|
88
|
+
}>>;
|
|
89
|
+
}, z.core.$strip>>;
|
|
90
|
+
}, z.core.$strip>>>;
|
|
91
|
+
depPaths: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"workspace">, z.ZodLiteral<"workspaces">, z.ZodArray<z.ZodString>]>>;
|
|
92
|
+
checkSecurity: z.ZodOptional<z.ZodBoolean>;
|
|
93
|
+
overridePaths: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
94
|
+
rootDeps: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
95
|
+
dependents: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
96
|
+
patches: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
97
|
+
ledger: z.ZodOptional<z.ZodObject<{
|
|
98
|
+
addedDate: z.ZodString;
|
|
99
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
100
|
+
securityChecked: z.ZodOptional<z.ZodBoolean>;
|
|
101
|
+
securityCheckDate: z.ZodOptional<z.ZodString>;
|
|
102
|
+
securityProvider: z.ZodOptional<z.ZodEnum<{
|
|
103
|
+
npm: "npm";
|
|
104
|
+
osv: "osv";
|
|
105
|
+
github: "github";
|
|
106
|
+
snyk: "snyk";
|
|
107
|
+
socket: "socket";
|
|
108
|
+
}>>;
|
|
109
|
+
}, z.core.$strip>>;
|
|
110
|
+
}, z.core.$strip>>>>;
|
|
111
|
+
resolutionPaths: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
112
|
+
rootDeps: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
113
|
+
dependents: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
114
|
+
patches: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
115
|
+
ledger: z.ZodOptional<z.ZodObject<{
|
|
116
|
+
addedDate: z.ZodString;
|
|
117
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
118
|
+
securityChecked: z.ZodOptional<z.ZodBoolean>;
|
|
119
|
+
securityCheckDate: z.ZodOptional<z.ZodString>;
|
|
120
|
+
securityProvider: z.ZodOptional<z.ZodEnum<{
|
|
121
|
+
npm: "npm";
|
|
122
|
+
osv: "osv";
|
|
123
|
+
github: "github";
|
|
124
|
+
snyk: "snyk";
|
|
125
|
+
socket: "socket";
|
|
126
|
+
}>>;
|
|
127
|
+
}, z.core.$strip>>;
|
|
128
|
+
}, z.core.$strip>>>>;
|
|
129
|
+
security: z.ZodOptional<z.ZodObject<{
|
|
130
|
+
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
131
|
+
provider: z.ZodOptional<z.ZodEnum<{
|
|
132
|
+
npm: "npm";
|
|
133
|
+
osv: "osv";
|
|
134
|
+
github: "github";
|
|
135
|
+
snyk: "snyk";
|
|
136
|
+
socket: "socket";
|
|
137
|
+
}>>;
|
|
138
|
+
autoFix: z.ZodOptional<z.ZodBoolean>;
|
|
139
|
+
interactive: z.ZodOptional<z.ZodBoolean>;
|
|
140
|
+
securityProviderToken: z.ZodOptional<z.ZodString>;
|
|
141
|
+
severityThreshold: z.ZodOptional<z.ZodEnum<{
|
|
142
|
+
high: "high";
|
|
143
|
+
medium: "medium";
|
|
144
|
+
low: "low";
|
|
145
|
+
critical: "critical";
|
|
146
|
+
}>>;
|
|
147
|
+
excludePackages: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
148
|
+
hasWorkspaceSecurityChecks: z.ZodOptional<z.ZodBoolean>;
|
|
149
|
+
}, z.core.$strip>>;
|
|
150
|
+
}, z.core.$strip>;
|
|
151
|
+
export type AppendixItem = z.infer<typeof AppendixItemSchema>;
|
|
152
|
+
export type Appendix = z.infer<typeof AppendixSchema>;
|
|
153
|
+
export type SecurityProvider = z.infer<typeof SecurityProviderSchema>;
|
|
154
|
+
export type SeverityThreshold = z.infer<typeof SeverityThresholdSchema>;
|
|
155
|
+
export type SecurityConfig = z.infer<typeof SecurityConfigSchema>;
|
|
156
|
+
export type PastoralistConfig = z.infer<typeof PastoralistConfigSchema>;
|
|
157
|
+
export declare function validateConfig(config: unknown): PastoralistConfig;
|
|
158
|
+
export declare function safeValidateConfig(config: unknown): PastoralistConfig | undefined;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { PastoralistConfig } from "./index";
|
|
2
|
+
export declare const loadExternalConfig: (root?: string, validate?: boolean) => Promise<PastoralistConfig | undefined>;
|
|
3
|
+
export declare const mergeConfigs: (externalConfig: PastoralistConfig | undefined, packageJsonConfig: PastoralistConfig | undefined) => PastoralistConfig | undefined;
|
|
4
|
+
export declare const loadConfig: (root?: string, packageJsonConfig?: PastoralistConfig, validate?: boolean) => Promise<PastoralistConfig | undefined>;
|