pastoralist 1.8.2 → 1.8.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/LICENSE +55 -21
- package/dist/cli/index.d.ts +8 -2
- package/dist/cli/parser/constants.d.ts +1 -1
- package/dist/core/packageJSON.d.ts +1 -1
- package/dist/core/update/types.d.ts +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +33 -32
- package/dist/types.d.ts +20 -0
- package/dist/utils/spinner.d.ts +1 -0
- package/dist/utils/types.d.ts +2 -0
- package/package.json +4 -4
package/LICENSE
CHANGED
|
@@ -1,21 +1,55 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
1
|
+
Elastic License 2.0
|
|
2
|
+
|
|
3
|
+
URL: https://www.elastic.co/licensing/elastic-license
|
|
4
|
+
|
|
5
|
+
## Acceptance
|
|
6
|
+
|
|
7
|
+
By using the software, you agree to all of the terms and conditions below.
|
|
8
|
+
|
|
9
|
+
## Copyright License
|
|
10
|
+
|
|
11
|
+
The licensor grants you a non-exclusive, royalty-free, worldwide, non-sublicensable, non-transferable license to use, copy, distribute, make available, and prepare derivative works of the software, in each case subject to the limitations and conditions below.
|
|
12
|
+
|
|
13
|
+
## Limitations
|
|
14
|
+
|
|
15
|
+
You may not provide the software to third parties as a hosted or managed service, where the service provides users with access to any substantial set of the features or functionality of the software.
|
|
16
|
+
|
|
17
|
+
You may not move, change, disable, or circumvent the license key functionality in the software, and you may not remove or obscure any functionality in the software that is protected by the license key.
|
|
18
|
+
|
|
19
|
+
You may not alter, remove, or obscure any licensing, copyright, or other notices of the licensor in the software. Any use of the licensor's trademarks is subject to applicable law.
|
|
20
|
+
|
|
21
|
+
## Patents
|
|
22
|
+
|
|
23
|
+
The licensor grants you a license, under any patent claims the licensor can license, or becomes able to license, to make, have made, use, sell, offer for sale, import and have imported the software, subject to the limitations and conditions in this license. This license does not cover any patent claims that you cause to be infringed by modifications or additions to the software. If you or your company make any written claim that the software infringes or contributes to infringement of any patent, your patent license for the software granted under these terms ends immediately. If your company makes such a claim, your patent license ends immediately for work on behalf of your company.
|
|
24
|
+
|
|
25
|
+
## Notices
|
|
26
|
+
|
|
27
|
+
You must ensure that anyone who gets a copy of any part of the software from you also gets a copy of these terms.
|
|
28
|
+
|
|
29
|
+
If you modify the software, you must include in any modified copies of the software prominent notices stating that you have modified the software.
|
|
30
|
+
|
|
31
|
+
## No Other Rights
|
|
32
|
+
|
|
33
|
+
These terms do not imply any licenses other than those expressly granted in these terms.
|
|
34
|
+
|
|
35
|
+
## Termination
|
|
36
|
+
|
|
37
|
+
If you use the software in violation of these terms, such use is not licensed, and your licenses will automatically terminate. If the licensor provides you with a notice of your violation, and you cease all violation of this license no later than 30 days after you receive that notice, your licenses will be reinstated retroactively. However, if you violate these terms after such reinstatement, any additional violation of these terms will cause your licenses to terminate automatically and permanently.
|
|
38
|
+
|
|
39
|
+
## No Liability
|
|
40
|
+
|
|
41
|
+
*As far as the law allows, the software comes as is, without any warranty or condition, and the licensor will not be liable to you for any damages arising out of these terms or the use or nature of the software, under any kind of legal claim.*
|
|
42
|
+
|
|
43
|
+
## Definitions
|
|
44
|
+
|
|
45
|
+
The **licensor** is the entity offering these terms, and the **software** is the software the licensor makes available under these terms, including any portion of it.
|
|
46
|
+
|
|
47
|
+
**you** refers to the individual or entity agreeing to these terms.
|
|
48
|
+
|
|
49
|
+
**your company** is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. **control** means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect.
|
|
50
|
+
|
|
51
|
+
**your licenses** are all the licenses granted to you for the software under these terms.
|
|
52
|
+
|
|
53
|
+
**use** means anything you do with the software requiring one of your licenses.
|
|
54
|
+
|
|
55
|
+
**trademark** means trademarks, service marks, and similar rights.
|
package/dist/cli/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createSpinner } from "../utils";
|
|
3
|
-
import { Options, PastoralistJSON, SecurityAlert, SecurityOverride, SecurityOverrideDetail } from "../types";
|
|
3
|
+
import { Options, PastoralistJSON, PastoralistResult, SecurityAlert, SecurityOverride, SecurityOverrideDetail } from "../types";
|
|
4
|
+
import { update } from "../core/update";
|
|
4
5
|
import { logger as createLogger } from "../utils";
|
|
5
6
|
import { SecurityChecker } from "../core/security";
|
|
6
7
|
import { initCommand } from "./cmds/init/index";
|
|
@@ -25,6 +26,11 @@ export declare const runSecurityCheck: (config: PastoralistJSON, mergedOptions:
|
|
|
25
26
|
export declare const handleSecurityResults: (alerts: SecurityAlert[], securityOverrides: SecurityOverride[], securityChecker: SecurityChecker, spinner: ReturnType<typeof createSpinner>, mergedOptions: Options, updates?: import("../types").OverrideUpdate[]) => void;
|
|
26
27
|
export declare const formatUpdateReport: (updates: import("../types").OverrideUpdate[]) => string;
|
|
27
28
|
export declare function determineSecurityScanPaths(config: PastoralistJSON | undefined, mergedOptions: Options, log?: ReturnType<typeof createLogger>): string[];
|
|
29
|
+
export declare const createEmptyResult: () => PastoralistResult;
|
|
30
|
+
export declare const createErrorResult: (error: unknown) => PastoralistResult;
|
|
31
|
+
export declare const buildSecurityResult: (alerts: SecurityAlert[]) => Pick<PastoralistResult, "hasSecurityIssues" | "securityAlertCount" | "securityAlerts">;
|
|
32
|
+
export declare const buildUpdateResult: (updateResult: ReturnType<typeof update>, config: PastoralistJSON | undefined, isDryRun: boolean) => Pick<PastoralistResult, "overrideCount" | "appliedOverrides" | "updated">;
|
|
33
|
+
export declare const outputResult: (result: PastoralistResult, isJsonOutput: boolean) => void;
|
|
28
34
|
export declare function action(options?: Options, deps?: {
|
|
29
35
|
createLogger: ({ file, isLogging }: import("../utils").LoggerOptions) => {
|
|
30
36
|
debug: (msg: string, caller?: string, ...args: unknown[]) => void;
|
|
@@ -54,5 +60,5 @@ export declare function action(options?: Options, deps?: {
|
|
|
54
60
|
green: (text: string) => string;
|
|
55
61
|
update: (options: Options) => import("../types").UpdateContext;
|
|
56
62
|
processExit: (code: number) => never;
|
|
57
|
-
}): Promise<
|
|
63
|
+
}): Promise<PastoralistResult>;
|
|
58
64
|
export declare const run: (argv?: string[]) => Promise<void>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { OptionDefinition } from "./types";
|
|
2
2
|
export declare const OPTION_DEFINITIONS: OptionDefinition[];
|
|
3
|
-
export declare const HELP_TEXT = "\nPastoralist - A utility CLI to manage your dependency overrides\n\nUsage: pastoralist [command] [options]\n\nCommands:\n init Initialize Pastoralist configuration interactively\n\nOptions:\n --debug Enable debug mode\n --dry-run Preview changes without writing to package.json\n -p, --path <path> Specifies a path to a package.json (default: \"package.json\")\n -d, --depPaths [paths...] Specifies glob paths to package.jsons\n --ignore [paths...] Specifies glob paths to ignore\n -r, --root <root> Specifies a root path\n -t, --isTestingCLI Enable CLI testing (no scripts run)\n --isTesting Enable testing mode (no scripts run)\n --init Initialize Pastoralist configuration interactively\n --checkSecurity Check for security vulnerabilities and generate overrides\n --forceSecurityRefactor Automatically apply security overrides without prompting\n --securityProvider <provider...> Security provider(s) to use (osv, github, snyk, npm, socket)\n --securityProviderToken <token> Security provider token for API access\n --interactive Run security checks in interactive mode\n --hasWorkspaceSecurityChecks Include workspace packages in security scan\n --promptForReasons Prompt for reasons when adding manual overrides\n";
|
|
3
|
+
export declare const HELP_TEXT = "\nPastoralist - A utility CLI to manage your dependency overrides\n\nUsage: pastoralist [command] [options]\n\nCommands:\n init Initialize Pastoralist configuration interactively\n\nOptions:\n --debug Enable debug mode\n --dry-run Preview changes without writing to package.json\n --outputFormat <format> Output format: text (default) or json\n -p, --path <path> Specifies a path to a package.json (default: \"package.json\")\n -d, --depPaths [paths...] Specifies glob paths to package.jsons\n --ignore [paths...] Specifies glob paths to ignore\n -r, --root <root> Specifies a root path\n -t, --isTestingCLI Enable CLI testing (no scripts run)\n --isTesting Enable testing mode (no scripts run)\n --init Initialize Pastoralist configuration interactively\n --checkSecurity Check for security vulnerabilities and generate overrides\n --forceSecurityRefactor Automatically apply security overrides without prompting\n --securityProvider <provider...> Security provider(s) to use (osv, github, snyk, npm, socket)\n --securityProviderToken <token> Security provider token for API access\n --interactive Run security checks in interactive mode\n --hasWorkspaceSecurityChecks Include workspace packages in security scan\n --promptForReasons Prompt for reasons when adding manual overrides\n";
|
|
4
4
|
export declare const ARGS_START_INDEX = 2;
|
|
@@ -10,7 +10,7 @@ export declare const getExistingOverrideField: (config: PastoralistJSON) => "res
|
|
|
10
10
|
export declare const getOverrideFieldForPackageManager: (packageManager: "npm" | "yarn" | "pnpm" | "bun") => "resolutions" | "overrides" | "pnpm";
|
|
11
11
|
export declare const applyOverridesToConfig: (config: PastoralistJSON, overrides: Record<string, OverrideValue> | Record<string, string>, fieldType: "resolutions" | "overrides" | "pnpm" | null) => PastoralistJSON;
|
|
12
12
|
export declare const resolveJSON: (path: string) => PastoralistJSON | undefined;
|
|
13
|
-
export declare const updatePackageJSON: ({ appendix, path, config, overrides, isTesting, dryRun, }: UpdatePackageJSONOptions) => PastoralistJSON | void;
|
|
13
|
+
export declare const updatePackageJSON: ({ appendix, path, config, overrides, isTesting, dryRun, silent, }: UpdatePackageJSONOptions) => PastoralistJSON | void;
|
|
14
14
|
export declare const parseNpmLsOutput: (stdout: string) => Record<string, boolean>;
|
|
15
15
|
export declare const executeNpmLs: () => Promise<string>;
|
|
16
16
|
export declare const getDependencyTree: () => Promise<Record<string, boolean>>;
|
package/dist/index.d.ts
CHANGED
|
@@ -8,5 +8,5 @@ export { detectPatches, attachPatchesToAppendix, findUnusedPatches, } from "./co
|
|
|
8
8
|
export { SecurityChecker } from "./core/security";
|
|
9
9
|
export { loadConfig, loadExternalConfig, mergeConfigs, clearConfigCache, } from "./config";
|
|
10
10
|
export { logMethod, logger } from "./utils";
|
|
11
|
-
export type { Options, PastoralistJSON, PastoralistConfig, Appendix, AppendixItem, OverridesType, OverrideValue, SecurityOverrideDetail, UpdatePackageJSONOptions, SecurityAlert, SecurityCheckOptions, SecurityOverride, SecurityProvider, } from "./types";
|
|
11
|
+
export type { Options, PastoralistJSON, PastoralistConfig, PastoralistResult, Appendix, AppendixItem, OverridesType, OverrideValue, SecurityOverrideDetail, UpdatePackageJSONOptions, SecurityAlert, SecurityCheckOptions, SecurityOverride, SecurityProvider, } from "./types";
|
|
12
12
|
export declare const findRemovableAppendixItems: (appendix: import("./types").Appendix) => Array<string>;
|
package/dist/index.js
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{createRequire as
|
|
3
|
-
`)},
|
|
4
|
-
`},
|
|
5
|
-
`).length},
|
|
6
|
-
[DRY RUN] Would write to package.json:`),console.log(
|
|
7
|
-
${
|
|
2
|
+
import{createRequire as Pn}from"node:module";var mn=Object.create;var{getPrototypeOf:bn,defineProperty:G,getOwnPropertyNames:yt,getOwnPropertyDescriptor:vn}=Object,mt=Object.prototype.hasOwnProperty;var Sn=(e,t,r)=>{r=e!=null?mn(bn(e)):{};let n=t||!e||!e.__esModule?G(r,"default",{value:e,enumerable:!0}):r;for(let i of yt(e))if(!mt.call(n,i))G(n,i,{get:()=>e[i],enumerable:!0});return n},ft=new WeakMap,On=(e)=>{var t=ft.get(e),r;if(t)return t;if(t=G({},"__esModule",{value:!0}),e&&typeof e==="object"||typeof e==="function")yt(e).map((n)=>!mt.call(t,n)&&G(t,n,{get:()=>e[n],enumerable:!(r=vn(e,n))||r.enumerable}));return ft.set(e,t),t};var bt=(e,t)=>{for(var r in t)G(e,r,{get:t[r],enumerable:!0,configurable:!0,set:(n)=>t[r]=()=>n})};var f=(e,t)=>()=>(e&&(t=e(e=0)),t);var vt=Pn(import.meta.url);var x,St="\uD83D\uDC11 \uD83D\uDC69\uD83C\uDFFD\uD83C\uDF3E Pastoralist:",ne,Ce,we,An,xn,kn,Cn,wn,Rn,Tn,Ot,Pt,At,Re;var T=f(()=>{x=process.env.DEBUG==="true"||!1,ne={MOCK_MODE:"PASTORALIST_MOCK_SECURITY",FORCE_VULNERABLE:"MOCK_FORCE_VULNERABLE",MOCK_FILE:"MOCK_ALERTS_FILE",GITHUB_TOKEN:"GITHUB_TOKEN"},Ce={ecosystem:"npm",name:"lodash"},we={ecosystem:"npm",name:"minimist"},An={package:Ce,manifest_path:"package.json",scope:"runtime"},xn={package:Ce,vulnerable_version_range:"< 4.17.21",first_patched_version:{identifier:"4.17.21"}},kn={package:we,vulnerable_version_range:"< 1.2.6",first_patched_version:{identifier:"1.2.6"}},Cn={severity:"high",summary:"Mock vulnerability in lodash",description:"Mock description",vulnerabilities:[xn]},wn={severity:"medium",summary:"Mock vulnerability in minimist",description:"Mock description",vulnerabilities:[kn]},Rn={package:Ce,severity:"high",vulnerable_version_range:"< 4.17.21",first_patched_version:{identifier:"4.17.21"}},Tn={package:we,severity:"medium",vulnerable_version_range:"< 1.2.6",first_patched_version:{identifier:"1.2.6"}},Ot={url:"https://mock.url",html_url:"https://mock.url",created_at:"2021-01-01T00:00:00Z",updated_at:"2021-01-01T00:00:00Z"},Pt={number:1,state:"open",dependency:An,security_advisory:Cn,security_vulnerability:Rn,...Ot},At={number:2,state:"open",dependency:{package:we,manifest_path:"package.json",scope:"runtime"},security_advisory:wn,security_vulnerability:Tn,...Ot},Re={OVERRIDE_TO_KEEP:{packageName:"fake-pastoralist-check-2",fromVersion:"1.0.0",toVersion:"2.1.0",key:"fake-pastoralist-check-2@2.1.0",dependents:{"fake-pastoralist-check-1":"1.0.0"},ledger:{addedDate:"2024-01-15T10:00:00.000Z",reason:"Security fix: Critical vulnerability in fake-pastoralist-check-1 transitive dependency (critical)",securityChecked:!0,securityCheckDate:"2024-01-15T10:00:00.000Z",securityProvider:"osv"}},OVERRIDE_TO_REMOVE:{packageName:"fake-pastoralist-check-3",fromVersion:"0.8.0",toVersion:"1.0.0",key:"fake-pastoralist-check-3@1.0.0",dependents:{},ledger:{addedDate:"2023-06-01T10:00:00.000Z",reason:"Manual override for compatibility testing"}},ALERT_TO_RESOLVE:{packageName:"fake-pastoralist-check-2",currentVersion:"1.0.0",vulnerableVersions:"< 2.1.0",patchedVersion:"2.1.0",severity:"critical",title:"Critical vulnerability in fake-pastoralist-check-2 (transitive from fake-pastoralist-check-1)",cve:"CVE-FAKE-PASTORALIST-2024-0001",fixAvailable:!0,description:"Fake critical security vulnerability in fake-pastoralist-check-2. Used by fake-pastoralist-check-1@1.0.0.",url:"https://example.com/fake-pastoralist-advisory-0001"},ALERT_TO_CAPTURE:{packageName:"fake-pastoralist-check-4",currentVersion:"0.5.0",vulnerableVersions:"< 1.0.0",patchedVersion:void 0,severity:"high",title:"High severity issue in fake-pastoralist-check-4 with no patch available",cve:"CVE-FAKE-PASTORALIST-2024-0002",fixAvailable:!1,description:"Fake high severity vulnerability with no available patch for testing alert capture functionality.",url:"https://example.com/fake-pastoralist-advisory-0002"}}});var xt,kt=()=>{process.stdout.write("\x1B[?25l")},j=()=>{process.stdout.write("\x1B[?25h")},ie=()=>{process.stdout.write("\r\x1B[K")},Ct=(e,t,r)=>{let n=e[t];ie(),process.stdout.write(`${n} ${r}`)},L=(e)=>{let t=e.interval;if(t!==null)clearInterval(t);return Object.assign({},e,{interval:null,isSpinning:!1})},wt=(e,t)=>{return Object.assign({},e,{text:t})},Rt=(e)=>{let t=(e.frameIndex+1)%xt.length;return Object.assign({},e,{frameIndex:t})},Tt=(e)=>{let t=setInterval(()=>{Ct(xt,e.frameIndex,e.text),Object.assign(e,Rt(e))},80);return Object.assign({},e,{interval:t,isSpinning:!0})},H=(e,t)=>{ie(),process.stdout.write(`${e} ${t}
|
|
3
|
+
`)},Vt=(e)=>{if(e.isSpinning)return w(e);kt();let r=Tt(e);return Object.assign(e,r),w(e)},It=(e)=>{if(!e.isSpinning)return w(e);let r=L(e);return Object.assign(e,r),ie(),j(),w(e)},$t=(e,t)=>{let r=L(e);Object.assign(e,r);let n=t||e.text;return H("✔",n),j(),w(e)},Ft=(e,t)=>{let r=L(e);Object.assign(e,r);let n=t||e.text;return H("✖",n),j(),w(e)},Nt=(e,t)=>{let r=L(e);Object.assign(e,r);let n=t||e.text;return H("ℹ",n),j(),w(e)},Et=(e,t)=>{let r=L(e);Object.assign(e,r);let n=t||e.text;return H("⚠",n),j(),w(e)},Vn=(e,t)=>{let r=wt(e,t);return Object.assign(e,r),w(e)},w=(e)=>{return{start:()=>Vt(e),stop:()=>It(e),succeed:(t)=>$t(e,t),fail:(t)=>Ft(e,t),info:(t)=>Nt(e,t),warn:(t)=>Et(e,t),update:(t)=>Vn(e,t)}},In=(e)=>{return w({text:e,isSpinning:!1,frameIndex:0,interval:null})},se;var Te=f(()=>{xt=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"],se=In});var C=(e)=>{return`\x1B[32m${e}\x1B[0m`},K=(e)=>{return`\x1B[31m${e}\x1B[0m`},Ve=(e)=>{return`\x1B[33m${e}\x1B[0m`},Ie=(e)=>{return`\x1B[36m${e}\x1B[0m`},jt=(e)=>{return`\x1B[90m${e}\x1B[0m`};var B=(e,t,r)=>{return(n,i,...s)=>{if(!t)return;let o=i?`[${i}]`:"",a=`${St}[${r}]${o} ${n}`;if(e==="debug")console.debug(a,...s);else if(e==="error")console.error(a,...s);else if(e==="info")console.info(a,...s)}},y=({file:e,isLogging:t=!1})=>({debug:B("debug",t,e),error:B("error",t,e),info:B("info",t,e)});var Lt=f(()=>{T()});function I(e,t){let r=e.split(".").map(Number),n=t.split(".").map(Number),i=Math.max(r.length,n.length);return Array.from({length:i}).reduce((s,o,a)=>{if(s!==0)return s;let c=r[a]||0,l=n[a]||0;return c-l},0)}class oe{max;ttl;cache;head;tail;constructor(e){this.max=e.max,this.ttl=e.ttl,this.cache=new Map,this.head=null,this.tail=null}get(e){let t=this.cache.get(e);if(!t)return;if(this.isExpired(t)){this.delete(e);return}return this.moveToFront(t),t.value}set(e,t){let r=this.cache.get(e);if(r){r.value=t,r.timestamp=Date.now(),this.moveToFront(r);return}let n={key:e,value:t,prev:null,next:null,timestamp:Date.now()};if(this.cache.set(e,n),this.addToFront(n),this.cache.size>this.max)this.evictLRU()}has(e){let t=this.cache.get(e);if(!t)return!1;if(this.isExpired(t))return this.delete(e),!1;return!0}delete(e){let t=this.cache.get(e);if(!t)return!1;return this.removeNode(t),this.cache.delete(e),!0}clear(){this.cache.clear(),this.head=null,this.tail=null}get size(){return this.cache.size}keys(){return Array.from(this.cache.keys())}values(){let e=[],t=this.head;while(t){if(!this.isExpired(t))e.push(t.value);t=t.next}return e}isExpired(e){if(!this.ttl)return!1;return Date.now()-e.timestamp>this.ttl}moveToFront(e){if(e===this.head)return;this.removeNode(e),this.addToFront(e)}addToFront(e){if(e.next=this.head,e.prev=null,this.head)this.head.prev=e;if(this.head=e,!this.tail)this.tail=e}removeNode(e){if(e.prev)e.prev.next=e.next;else this.head=e.next;if(e.next)e.next.prev=e.prev;else this.tail=e.prev}evictLRU(){if(!this.tail)return;this.cache.delete(this.tail.key),this.removeNode(this.tail)}}var ae,$n=(e,t,r)=>{let n=e;return n.attemptNumber=t,n.retriesLeft=r,n},Fn=(e,t,r,n)=>{let i=r*Math.pow(t,e-1);return Math.min(i,n)},Nn=(e)=>{return new Promise((t)=>setTimeout(t,e))},U=async(e,t={})=>{let{retries:r=ae.retries,factor:n=ae.factor,minTimeout:i=ae.minTimeout,maxTimeout:s=ae.maxTimeout,onFailedAttempt:o,onRetry:a}=t,c=0,l=async()=>{c++;try{return await e()}catch(u){let d=r-c,h=d>=0,p=Math.max(0,d),g=$n(u instanceof Error?u:Error(String(u)),c,p);if(!h)throw g;if(o)await o(g);if(a)a(c,p);let m=Fn(c,n,i,s);return await Nn(m),l()}};return l()};var Ut=f(()=>{ae={retries:3,factor:2,minTimeout:1000,maxTimeout:30000}});var P=f(()=>{Te();Te();Lt();Ut()});import{globSync as En}from"node:fs";import{glob as jn}from"node:fs/promises";import{resolve as Dt,relative as _t}from"node:path";function ce(e,t={}){let{cwd:r=process.cwd(),ignore:n=[],absolute:i=!1}=t,s=Array.isArray(e)?e:[e],o=new Set;for(let a of s){let c=En(a,{cwd:r,exclude:n});for(let l of c){let u=Dt(r,l),d=i?u:_t(r,u);o.add(d)}}return Array.from(o).sort()}async function Mt(e,t={}){let{cwd:r=process.cwd(),ignore:n=[],absolute:i=!1}=t,s=Array.isArray(e)?e:[e],o=new Set;for(let a of s){let c=jn(a,{cwd:r,exclude:n});for await(let l of c){let u=Dt(r,l),d=i?u:_t(r,u);o.add(d)}}return Array.from(o).sort()}var ue=()=>{};import*as D from"fs";import{resolve as q}from"path";import{execFile as Ln}from"node:child_process";import{promisify as Un}from"util";var Dn,J,le=null,V,_n=()=>{return{size:V.size,keys:Array.from(V.keys())}},Mn=()=>{let e=V.size;return V.clear(),J.debug(`Cache cleared. Had ${e} entries`,"forceClearCache"),e},$e=(e)=>{let t=process.cwd(),r=q(t,e);return D.existsSync(r)},Gt=()=>{if($e("bun.lockb"))return"bun";if($e("yarn.lock"))return"yarn";if($e("pnpm-lock.yaml"))return"pnpm";return"npm"},Wn=(e)=>{return e?.resolutions!==void 0},Gn=(e)=>{return e?.overrides!==void 0},Hn=(e)=>{return e?.pnpm?.overrides!==void 0},Ht=(e)=>{if(Wn(e))return"resolutions";if(Gn(e))return"overrides";if(Hn(e))return"pnpm";return null},Kt=(e)=>{return{yarn:"resolutions",pnpm:"pnpm",npm:"overrides",bun:"overrides"}[e]},Kn=(e,t)=>{return{...e,resolutions:t}},Bn=(e,t)=>{let r=e.pnpm||{};return{...e,pnpm:{...r,overrides:t}}},qn=(e,t)=>{return{...e,overrides:t}},Bt=(e,t,r)=>{if(r==="resolutions")return Kn(e,t);if(r==="pnpm")return Bn(e,t);if(r==="overrides")return qn(e,t);return e},Jn=(e)=>{try{let t=D.readFileSync(e,"utf8");return JSON.parse(t)}catch(t){J.error(`Invalid JSON at: ${e}`,"parseJsonFile",t);return}},R=(e)=>{let t=q(e),r=V.get(t);if(r)return r;let n=Jn(t);if(n)V.set(t,n);return n},zn=(e)=>{let t=Boolean(e.pastoralist?.overridePaths),r=Boolean(e.pastoralist?.resolutionPaths),n=Boolean(e.pastoralist?.security),i=Boolean(e.pastoralist?.depPaths);return t||r||n||i},Fe=(e)=>{let t=e.pastoralist?.depPaths,r=e.pastoralist?.overridePaths,n=e.pastoralist?.resolutionPaths,i=e.pastoralist?.security;return{...t&&{depPaths:t},...r&&{overridePaths:r},...n&&{resolutionPaths:n},...i&&{security:i}}},Yn=(e)=>{let{resolutions:t,overrides:r,pnpm:n,...i}=e;if(!n)return i;let{overrides:s,...o}=n,a=Object.keys(o).length>0;return{...i,...a&&{pnpm:o}}},Xn=(e)=>{if(!zn(e)){let{pastoralist:n,...i}=e;return i}let r=Fe(e);return{...e,pastoralist:r}},Qn=(e,t)=>{let r=Fe(e);return{...e,pastoralist:{appendix:t,...r}}},Zn=(e)=>{let t=Yn(e);return Xn(t)},ei=(e,t,r,n)=>{let i=t&&Object.keys(t).length>0,s;if(i)s=Qn(e,t);else{let l=Fe(e),u=Object.keys(l).length>0,{pastoralist:d,...h}=e;s=u?{...h,pastoralist:l}:h}if(!(r&&Object.keys(r).length>0))return s;let c=Ht(s)||(n?null:Kt(Gt()));return Bt(s,r,c)},ti=(e)=>{return JSON.stringify(e,null,2)+`
|
|
4
|
+
`},ri=(e)=>{if(!e.pastoralist)return 0;return JSON.stringify(e.pastoralist,null,2).split(`
|
|
5
|
+
`).length},ni=(e)=>{return ri(e)>10},ii=(e,t)=>{let r=q(e),n=q(process.cwd(),"package.json");if(r===n)try{let s=JSON.parse(t);if(!Boolean(s.name))return}catch{return}D.writeFileSync(r,t)},Ne=({appendix:e,path:t,config:r,overrides:n,isTesting:i=!1,dryRun:s=!1,silent:o=!1})=>{let a=n&&Object.keys(n).length>0,c=e&&Object.keys(e).length>0,u=a||c?ei(r,e,n||{},i):Zn(r);if(i)return u;let d=ti(u);if(s&&!o)console.log(`
|
|
6
|
+
[DRY RUN] Would write to package.json:`),console.log(d);if(s)return u;if(x)J.debug(`Writing updated package.json:
|
|
7
|
+
${d}`,"updatePackageJSON");ii(t,d);let p=q(t);if(V.delete(p),ni(u))console.log(`
|
|
8
8
|
\uD83D\uDCA1 Tip: Your pastoralist config is getting large (>10 lines).`),console.log(" Consider moving it to a .pastoralistrc file using:"),console.log(` pastoralist init --useRcConfigFile
|
|
9
|
-
`)},qn=(e)=>{let t=JSON.parse(e),r={},n=(s)=>{if(!(s&&typeof s==="object"))return;Object.entries(s).forEach(([a,c])=>{if(r[a]=!0,c&&typeof c==="object"&&"dependencies"in c)n(c.dependencies)})};if(t.dependencies)n(t.dependencies);return r},Jn=async()=>{try{let{stdout:e}=await wn("npm",["ls","--json","--all"],{encoding:"utf8",maxBuffer:10485760,timeout:3000});return e}catch(e){let t=e;if(t.code===1&&t.stdout)return t.stdout;throw e}},Wt=async()=>{if(ce!==null)return ce;try{let t=await Jn(),r=qn(t);return ce=r,r}catch(t){return q.debug("Failed to get dependency tree","getDependencyTree",t),{}}},Fe=()=>{ce=null},Ne=(e,t=[],r="./",n=q)=>{if(e.length===0)throw n.error("No depPaths provided","findPackageJsonFiles"),Error("No depPaths provided to findPackageJsonFiles");try{n.debug(`Searching with patterns: ${e.join(", ")}, ignoring: ${t.join(", ")}, cwd: ${r}`,"findPackageJsonFiles");let s=oe(e,{cwd:r,ignore:t,absolute:!1,onlyFiles:!0});if(s.length===0){let a=`No package.json files found matching patterns: ${e.join(", ")} in directory: ${r}`;throw n.error(a,"findPackageJsonFiles"),Error(a)}return n.debug(`Found ${s.length} files`,"findPackageJsonFiles"),s}catch(s){throw n.error("Error finding package.json files","findPackageJsonFiles",s),s}};var I=f(()=>{ae();R();P();wn=Cn(xn),q=y({file:"packageJSON.ts",isLogging:k}),V=new Map});var le,zn=(e,t)=>{return Boolean(t[e])},Yn=(e,t)=>{return e.filter((r)=>!zn(r,t))},Xn=(e,t)=>{return e>0&&!t},Ee=(e,t,r,n)=>{let i=Object.keys(e),s=Yn(i,t),o=Boolean(n?.depPaths);if(Xn(s.length,o))r.info(`\uD83D\uDC11 Found overrides for packages not in root dependencies: ${s.join(", ")}`,"checkMonorepoOverrides"),r.info("\uD83D\uDCA1 For monorepo support, use --depPaths flag or add depPaths configuration in package.json","checkMonorepoOverrides");return s},Qn=(e)=>{let t=e?.dependencies||{},r=e?.devDependencies||{},n=e?.peerDependencies||{};return{...t,...r,...n}},Zn=(e)=>{return e.map((r)=>w(r)).reduce((r,n)=>{if(!Boolean(n))return r;let s=Qn(n);return{...r,...s}},{})},Gt=(e,t,r,n)=>{let i=n(e,t,r),s=Zn(e);return{appendix:i,allWorkspaceDeps:s}},ei=(e,t)=>{let r=Boolean(e),n=t.length>0;return r&&n},ti=(e,t)=>{return{...e,dependents:{...e.dependents,...t.dependents}}},Le=(e,t,r,n)=>{if(!ei(t,r))return e;return n.debug("Using overridePaths configuration for monorepo support","mergeOverridePaths"),Object.values(t).forEach((s)=>{Object.entries(s).forEach(([o,a])=>{if(e[o])e[o]=ti(e[o],a);else e[o]=a})}),e},Ht=(e,t)=>{return typeof t[e]==="object"},Bt=(e,t)=>{return Boolean(t[e])},ri=(e,t,r)=>{if(!Ht(e,t))return!1;if(Bt(e,r))return!1;return le.debug(`Found unused nested override for ${e}: parent package not in dependencies`,"isUnusedNestedOverride"),!0},ni=async(e,t,r)=>{if(Ht(e,t))return!1;if(Bt(e,r))return!1;if(!(Object.keys(r).length>0))return le.debug(`Found unused override for ${e}: no dependencies at all`,"isUnusedSimpleOverride"),!0;let o=await Wt();if(Boolean(o[e]))return le.debug(`Keeping override for ${e}: found in dependency tree`,"isUnusedSimpleOverride"),!1;return le.debug(`Found unused override for ${e}: not in dependency tree`,"isUnusedSimpleOverride"),!0},ii=async(e,t,r)=>{if(ri(e,t,r))return!0;return ni(e,t,r)},Kt=async(e,t)=>{let r=Object.keys(e),n=await Promise.all(r.map((i)=>ii(i,e,t)));return r.filter((i,s)=>n[s])},si=(e,t)=>{if(!t)return!1;return Object.values(t).some((r)=>Object.keys(r).some((n)=>n.startsWith(`${e}@`)))},oi=(e,t)=>{return e.filter((r)=>si(r,t))},ai=(e,t)=>{return e.filter((r)=>!t.includes(r))},ci=(e,t,r)=>{return t.reduce((n,i)=>{return Object.keys(n).filter((o)=>o.startsWith(`${i}@`)).reduce((o,a)=>{r.debug(`Removed appendix entry for ${a}`,"removeAppendixEntries");let{[a]:c,...l}=o;return l},n)},e)},li=async(e,t,r,n,i,s,o,a)=>{let c=await Kt(e,n);if(c.length===0)return{finalOverrides:e,finalAppendix:r};let u=oi(i,s),d=ai(c,u);if(d.length>0){o.debug(`Found ${d.length} packages to remove from overrides: ${d.join(", ")}`,"cleanupUnusedOverrides");let g=a(t,d)||e,b=ci(r,d,o);return{finalOverrides:g,finalAppendix:b}}if(u.length>0)o.info(`\uD83D\uDC11 Keeping overrides for packages tracked in overridePaths: ${u.join(", ")}`,"cleanupUnusedOverrides");return{finalOverrides:e,finalAppendix:r}};var je=f(()=>{R();P();I();le=y({file:"workspace.ts",isLogging:k})});var Ue,ui,di=(e)=>{return e.split("/").pop()||""},pi=(e)=>{return e.replace(".patch","")},hi=(e)=>{return e.length>=2?`${e[0]}/${e[1]}`:e[0]},gi=(e)=>{return e[0]},fi=(e)=>{if(!e.includes("+"))return e;let r=e.split("+");return e.startsWith("@")?hi(r):gi(r)},yi=(e,t,r)=>{let n=e[t]||[];return{...e,[t]:[...n,r]}},mi=(e,t)=>{let r=di(e);if(!r.endsWith(".patch"))return t;let i=pi(r),s=fi(i);if(!Boolean(s))return t;return Ue.debug(`Found patch for ${s}: ${e}`,"processPatchFile"),yi(t,s,e)},bi=(e)=>{return e.reduce((t,r)=>mi(r,t),{})},De=(e="./")=>{try{let t=oe(ui,{cwd:e});return bi(t)}catch(t){return Ue.error("Error detecting patches","detectPatches",t),{}}},vi=(e,t)=>{return t[e]||[]},Si=(e,t)=>{return Boolean(t[e])},Oi=(e,t)=>{return e.flatMap(([r,n])=>{if(Si(r,t))return[];return Ue.debug(`Found unused patches for ${r}: ${n.join(", ")}`,"collectUnusedPatches"),n})},_e=(e,t)=>{let r=Object.entries(e);return Oi(r,t)},Pi=(e)=>{return e.split("@")[0]},Ai=(e,t,r)=>{let n=Pi(t),i=vi(n,r);if(!(i.length>0))return e;return{...e,[t]:{...e[t],patches:i}}},Me=(e,t)=>{return Object.keys(e).reduce((n,i)=>Ai(n,i,t),e)};var We=f(()=>{ae();R();P();Ue=y({file:"patches.ts",isLogging:k}),ui=["patches/*.patch",".patches/*.patch","*.patch","patches/**/*.patch"]});var Jt={};gt(Jt,{updateOverrides:()=>qt,resolveOverrides:()=>ue,getOverridesByType:()=>F,defineOverride:()=>Ge});var J,ki=(e)=>{return Object.keys(e).length>0},xi=(e)=>{let t=e?.overrides||{};return Object.keys(t).length>0},Ci=(e)=>{return Object.keys(e).length>0},wi=(e,t,r)=>{return e||t||r},Ri=(e,t,r)=>{let n=t?.overrides||{};return[{type:"overrides",overrides:e},{type:"pnpmOverrides",overrides:n},{type:"resolutions",overrides:r}]},Ti=(e)=>{return e.filter(({overrides:t})=>Object.keys(t).length>0)},Vi=(e)=>{return e.length>1},Ge=({overrides:e={},pnpm:t={},resolutions:r={}}={})=>{let n=ki(e),i=xi(t),s=Ci(r);if(!wi(n,i,s))return;let a=Ri(e,t,r),c=Ti(a);if(Vi(c)){J.error("Only 1 override object allowed","defineOverride");return}return c[0]},$i=(e)=>{return Object.keys(e).reduce((r,n)=>{let i=e[n];return r[n]=i,r},{})},Ii=(e)=>{return{type:"pnpm",pnpm:{overrides:e}}},Fi=(e)=>{return{type:"resolutions",resolutions:e}},Ni=(e)=>{return{type:"npm",overrides:e}},Ei=(e,t)=>{if(e==="pnpmOverrides")return Ii(t);if(e==="resolutions")return Fi(t);return Ni(t)},ue=({config:e={}})=>{let t=Ge(e);if(!t){J.debug("No overrides configuration found","resolveOverrides");return}let{type:n,overrides:i}=t,s=Object.keys(i).length>0,o=Boolean(n);if(!(s&&o)){J.debug("No active overrides found","resolveOverrides");return}let c=$i(i);return Ei(n,c)},Li=(e)=>{return e?.resolutions},ji=(e)=>{return e?.pnpm?.overrides},Ui=(e)=>{return e?.overrides},F=(e)=>{let t=e?.type;if(!t){J.error("no type found","getOverridesByType");return}if(t==="resolutions")return Li(e);if(t==="pnpm")return ji(e);return Ui(e)},Di=(e,t)=>{return!t.includes(e)},_i=(e,t)=>{return Object.entries(e).reduce((r,[n,i])=>{if(Di(n,t))r[n]=i;return r},{})},qt=(e,t)=>{if(!e)return;let n=F(e);if(!n||Object.keys(n).length===0){J.debug("No overrides found to update","updateOverrides");return}return _i(n,t)};var z=f(()=>{R();P();J=y({file:"overrides.ts",isLogging:k})});var Mi=(e,t)=>{return t?.find((r)=>r.packageName===e)?.reason},Wi=(e,t)=>{return t?.[e]},He=(e,t,r,n)=>{if(t)return t;let i=Mi(e,r);if(i)return i;return Wi(e,n)},Gi=(e,t)=>{if(!Boolean(t))return!1;return t.some((n)=>n.packageName===e)},Hi=(e,t)=>{return t?.find((r)=>r.packageName===e)},Bi=()=>({securityChecked:!0,securityCheckDate:new Date().toISOString()}),Ki=(e,t)=>{if(!Boolean(t))return e;return{...e,securityProvider:t}},qi=(e,t)=>{if(!t?.cve)return e;return{...e,cve:t.cve}},Ji=(e,t)=>{if(!t?.severity)return e;return{...e,severity:t.severity}},zi=(e,t)=>{if(!t?.url)return e;return{...e,url:t.url}},Be=(e,t,r)=>{if(!Gi(e,t))return{};let i=Hi(e,t),s=Bi();return s=Ki(s,r),s=qi(s,i),s=Ji(s,i),s=zi(s,i),s},Yi=(e,t)=>{let r={addedDate:new Date().toISOString()};return{...e?{...r,reason:e}:r,...t}},Ke=(e,t,r,n)=>{let s=Boolean(t)?t:Yi(r,n);return{dependents:e,ledger:s}},qe=(e,t,r)=>{return{...e,[t]:r}},zt=(e,t,r)=>{if(!e)return`${t} (transitive dependency)`;return`${t}@${r}`},Yt=(e)=>{return typeof e==="object"},Xi=(e)=>{if(!Boolean(e?.dependents))return!0;return Object.keys(e.dependents).length===0},Xt=(e)=>{return Object.keys(e).reduce((r,n)=>{let i=e[n],s=!i,o=Xi(i);if(s||o)return r;return{...r,[n]:i}},{})},Qt=(e)=>{let t=e?.dependencies||{},r=e?.devDependencies||{},n=e?.peerDependencies||{};return{...t,...r,...n}},Zt=(e,t)=>{return e.some((r)=>t.includes(r))},er=(e,t)=>{if(!Boolean(e))return!1;return Object.keys(e).length>0&&t},de=(e)=>{if(!e)return!1;return Object.keys(e).length>0},tr=(e,t,r)=>{let n=e[t]?.dependents||{};return{...e,[t]:{dependents:{...n,...r.dependents}}}};var Qi=(e,t,r,n,i,s,o,a,c,l=!1)=>{let u=i.includes(e);if(l&&!u)return s;let d=`${e}@${t}`;if(c.has(d))return{...s,[d]:c.get(d)};let p=s?.[d]?.dependents||{},g=n[e],b=zt(u,e,g),v=qe(p,r,b),m=s?.[d]?.ledger,x=Ke(v,m,o,a);return c.set(d,x),{...s,[d]:x}},Zi=(e,t,r,n,i,s,o,a,c,l,u)=>{let d=`${e}@${t}`;if(u.has(d))return{...s,[d]:u.get(d)};let p=s?.[d]?.dependents||{},g=`${n}@${i[n]} (nested override)`,b=qe(p,r,g),v=s?.[d]?.ledger,m=He(e,void 0,a,l)||o,x=Be(e,a,c),ut=Ke(b,v,m,x);return u.set(d,ut),{...s,[d]:ut}},es=(e,t,r,n,i,s,o,a,c,l,u)=>{if(!i.includes(e))return s;return Object.entries(t).reduce((h,[p,g])=>Zi(p,g,r,e,n,h,o,a,c,l,u),s)},ts=(e,t,r,n,i,s,o,a,c,l,u,d=!1)=>{let h=t[e],p=He(e,o,a,l),g=Be(e,a,c);if(Yt(h))return es(e,h,r,n,i,s,p,a,c,l,u);return Qi(e,h,r,n,i,s,p,g,u,d)},_=({overrides:e={},appendix:t={},dependencies:r={},devDependencies:n={},peerDependencies:i={},packageName:s="",reason:o,securityOverrideDetails:a,securityProvider:c,manualOverrideReasons:l,cache:u=new Map,onlyUsedOverrides:d=!1})=>{let h=Object.keys(e),p={...r,...n,...i},g=Object.keys(p),b=h.reduce((v,m)=>ts(m,e,s,p,g,v,o,a,c,l,u,d),t);return Xt(b)},rr=(e,t,r,n=!0)=>{let i=w(e);if(!Boolean(i))return;let{name:o,dependencies:a={},devDependencies:c={},peerDependencies:l={}}=i,u=Qt(i),d=Object.keys(u);if(!Zt(d,r))return;let p=_({overrides:t,dependencies:a,devDependencies:c,peerDependencies:l,packageName:o,securityOverrideDetails:void 0,manualOverrideReasons:void 0,onlyUsedOverrides:!0});if(er(p,n)){let{writeFileSync:b}=ft("fs");i.pastoralist={appendix:p},b(e,JSON.stringify(i,null,2))}return{name:o,dependencies:a,devDependencies:c,appendix:p}},rs=(e)=>{return Boolean(e)},ns=(e)=>{if(!rs(e))return null;return F(e)||null},is=(e,t)=>{let r=w(e);if(!Boolean(r))return null;let{resolveOverrides:i}=(z(),un(Jt)),s=i({config:r}),o=F(s)||null,a=de(o);if(a)t.debug(`Found ${Object.keys(o).length} overrides in ${e}`,"constructAppendix");return a?o:null},ss=(e,t)=>{return e.map((r)=>is(r,t))},os=(e,t)=>{let r=e.filter((i)=>i!==null),n=de(t)?{...t}:{};return r.reduce((i,s)=>({...i,...s}),n)},as=(e,t,r)=>{return e.map((n)=>rr(n,t,r,!1))},cs=(e,t,r)=>{return tr(e,t,r)},ls=(e,t)=>{return Object.entries(t).reduce((n,[i,s])=>cs(n,i,s),e)},us=(e)=>{return e.filter((r)=>r!==null&&r!==void 0&&Boolean(r.appendix)).reduce((r,n)=>ls(r,n.appendix),{})},Je=(e,t,r)=>{let n=ns(t);if(de(n))r.debug(`Found ${Object.keys(n).length} overrides in root package.json`,"constructAppendix");let s=ss(e,r),o=os(s,n);if(!(Object.keys(o).length>0))return r.debug("No overrides found in root or workspace packages","constructAppendix"),{};let c=Object.keys(o);r.debug(`Processing ${c.length} total unique overrides across all packages`,"constructAppendix");let l=as(e,o,c);return us(l)};var pe=f(()=>{I();z()});var nr=(e,t,r,n)=>{return Ne(e,r,t,n)},ir=(e)=>{Ie({appendix:e.finalAppendix,path:e.path,config:e.config,overrides:e.finalOverrides,dryRun:e.options?.dryRun||!1,isTesting:e.isTesting})},sr=(e,t,r,n)=>{let i=t.pastoralist?.depPaths,s=e?.depPaths&&e.depPaths.length>0,o=!s&&i,a=ds(e,t);return{mode:s||o?"workspace":"root",depPaths:a,hasRootOverrides:r,missingInRoot:n}},ds=(e,t)=>{if(e?.depPaths)return e.depPaths;let r=t.pastoralist?.depPaths;if(r==="workspace"||r==="workspaces")return t.workspaces?.map((n)=>`${n}/package.json`)||null;if(Array.isArray(r))return r;if(t.workspaces&&!r)return t.workspaces.map((n)=>`${n}/package.json`);return null};var or=f(()=>{I()});var ps=(e)=>{let t=De(e.root),r=Object.keys(t);if(r.length>0)e.log.debug(`Found patches for packages: ${r.join(", ")}`,"stepDetectPatches");return{...e,patchMap:t}},hs=(e)=>{if(!e.config)return e;let t=ue({options:e.options,config:e.config}),r=F(t)||{};if(e.options?.securityOverrides)e.log.debug("Merging security overrides","stepPrepareOverrides"),r={...r,...e.options.securityOverrides};return{...e,overridesData:t,overrides:r}},gs=(e)=>{if(!e.config)return e;let t=e.overrides||{},r=Object.keys(t).length>0,n={...e.config.dependencies,...e.config.devDependencies,...e.config.peerDependencies},i=Ee(t,n,e.log,e.options),s=sr(e.options,e.config,r,i);return{...e,hasRootOverrides:r,rootDeps:n,missingInRoot:i,mode:s}},fs=(e)=>{if(!e.config||!e.mode||!e.overridesData)return e;let t=e.mode.depPaths;if(!(t&&t.length>0))return e;let n=e.options?.ignore||[],i=nr(t,e.root,n,e.log);if(i.length===0)return e;e.log.debug(`Processing ${i.length} workspace packages`,"stepProcessWorkspaces");let{appendix:s,allWorkspaceDeps:o}=Gt(i,e.overridesData,e.log,Je);return{...e,workspaceAppendix:s,allWorkspaceDeps:o}},ys=(e)=>{if(!e.config||!e.overrides)return e;let t=e.config.pastoralist?.appendix||{};return{...e,existingAppendix:t}},ms=(e)=>{if(!e.config||!e.overrides)return e;let{dependencies:t={},devDependencies:r={},peerDependencies:n={}}=e.config,i=_({overrides:e.overrides,dependencies:t,devDependencies:r,peerDependencies:n,packageName:e.config.name||"root",securityOverrideDetails:e.options?.securityOverrideDetails,securityProvider:e.options?.securityProvider,manualOverrideReasons:e.options?.manualOverrideReasons});if(!e.workspaceAppendix)return{...e,appendix:i};return e.log.debug("Merging workspace appendix with root appendix","stepBuildAppendix"),Object.entries(e.workspaceAppendix).forEach(([s,o])=>{let a=i[s];if(!a)i[s]=o;else a.dependents={...a.dependents,...o.dependents}}),{...e,appendix:i}},bs=(e)=>{if(!e.appendix||!e.patchMap)return e;let t=Me(e.appendix,e.patchMap);return{...e,appendix:t}},vs=(e)=>{if(!e.config||!e.appendix||!e.missingInRoot)return e;let t=e.config.pastoralist?.overridePaths||e.config.pastoralist?.resolutionPaths;return Le(e.appendix,t,e.missingInRoot,e.log),{...e,overridePaths:t}},Ss=(e)=>{if(!e.patchMap||!e.rootDeps)return e;let t=_e(e.patchMap,e.rootDeps);if(t.length>0)e.log.info(`Found ${t.length} potentially unused patch files:`,"stepLogUnusedPatches"),t.forEach((r)=>e.log.info(` - ${r}`,"stepLogUnusedPatches")),e.log.info("Consider removing these patches if the packages are no longer used.","stepLogUnusedPatches");return{...e,allDeps:e.rootDeps}},Os=(e)=>{if(e.finalOverrides!==void 0&&e.finalAppendix!==void 0)return e;let t=e.overrides||{},r=e.appendix||{};if(!e.overrides||!e.overridesData||!e.appendix)return{...e,finalOverrides:t,finalAppendix:r};return{...e,finalOverrides:e.overrides,finalAppendix:e.appendix}},Ps=(e)=>{if(e.isTesting)return e;if(!e.config||e.finalAppendix===void 0||e.finalOverrides===void 0)return e.log.debug(`Skipping write: config=${!!e.config}, appendix=${e.finalAppendix!==void 0}, overrides=${e.finalOverrides!==void 0}`,"stepWriteResult"),e;return e.log.debug(`Writing results: appendix keys=${Object.keys(e.finalAppendix||{}).length}, override keys=${Object.keys(e.finalOverrides||{}).length}`,"stepWriteResult"),ir({path:e.path,config:e.config,finalAppendix:e.finalAppendix,finalOverrides:e.finalOverrides,options:e.options,isTesting:e.isTesting}),e},As=(e,...t)=>{return t.reduce((r,n)=>n(r),e)},ks=(e)=>{let t=!e.mode?.hasRootOverrides,r=e.mode?.mode==="root",n=Boolean(e.config);if(!(t&&r&&n))return e;return e.log.debug("No overrides found","update"),{...e,finalOverrides:{},finalAppendix:{}}},ze=(e)=>{let t=e?.path||"package.json",r=e?.root||"./",n=e?.isTesting||!1,i=k||e?.debug||!1,s=y({file:"update",isLogging:i});if(Fe(),V.clear(),!e.config)return s.debug("No config provided","update"),{options:e,path:t,root:r,isTesting:n,log:s};let o={options:e,path:t,root:r,isTesting:n,log:s,config:e.config},a=As(o,ps,hs,gs,fs,ks,ys,ms,bs,vs,Ss,Os,Ps);if(k)a.log.debug("Update complete","update");return a};var Ye=f(()=>{R();P();I();je();We();z();pe();or()});class Y{debug;isIRLFix;isIRLCatch;log;retryOptions;constructor(e={}){this.debug=e.debug||!1,this.isIRLFix=e.isIRLFix||!1,this.isIRLCatch=e.isIRLCatch||!1,this.log=y({file:"security/osv.ts",isLogging:this.debug}),this.retryOptions=e.retryOptions||{retries:3,factor:2,minTimeout:1000}}async isAvailable(){try{return(await fetch("https://api.osv.dev/v1/query",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({package:{name:"test",ecosystem:"npm"}})})).ok}catch{return!1}}async fetchFromOSVBatchAPI(e){let t=e.map((i)=>({package:{name:i.name,ecosystem:"npm"},version:i.version})),r=await fetch("https://api.osv.dev/v1/querybatch",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({queries:t})});if(!r.ok)throw Error(`HTTP ${r.status}`);return(await r.json()).results||[]}async fetchAlerts(e){if(this.log.debug(`OSV checking ${e.length} packages`,"fetchAlerts"),e.length===0)return[];let t=await U(async()=>{return this.fetchFromOSVBatchAPI(e)},{...this.retryOptions,onFailedAttempt:(s)=>{this.log.debug(`Batch API attempt ${s.attemptNumber} failed`,"fetchAlerts")}}).catch((s)=>{return this.log.debug("Failed to fetch batch results after retries","fetchAlerts",{error:s}),[]}),r=e.map((s,o)=>{let a=t[o];return a?.vulns&&a.vulns.length>0?this.convertOSVAlerts(s,a.vulns):[]}).flat(),n=this.isIRLFix?[Ce.ALERT_TO_RESOLVE]:[],i=this.isIRLCatch?[Ce.ALERT_TO_CAPTURE]:[];return r.concat(n).concat(i)}convertOSVAlerts(e,t){return t.map((r)=>({packageName:e.name,currentVersion:e.version,vulnerableVersions:this.extractVersionRange(r),patchedVersion:this.extractPatchedVersion(r),severity:this.extractSeverity(r),title:r.summary||r.details||`Vulnerability in ${e.name}`,description:r.details,cve:this.extractCVE(r),url:r.references?.[0]?.url||`https://osv.dev/vulnerability/${r.id}`,fixAvailable:!!this.extractPatchedVersion(r)}))}extractVersionRange(e){let t=e.affected?.[0];if(t?.ranges?.[0]?.events){let r=t.ranges[0].events,n=r.find((s)=>s.introduced)?.introduced||"0",i=r.find((s)=>s.fixed)?.fixed;return i?`>= ${n} < ${i}`:`>= ${n}`}return""}extractPatchedVersion(e){return(e.affected?.[0]?.ranges?.[0]?.events||[]).find((i)=>i.fixed)?.fixed}extractSeverity(e){let t=e.database_specific?.severity||e.severity?.[0]?.score||"medium";if(typeof t==="string"){let r=t.toLowerCase();if(["low","medium","high","critical"].includes(r))return r}return"medium"}extractCVE(e){return e.aliases?.find((t)=>t.startsWith("CVE-"))}}var ar=f(()=>{P();R()});import{execFile as xs}from"child_process";import{promisify as Cs}from"util";class ge{owner;repo;token;log;constructor(e){this.token=e.token||process.env.GITHUB_TOKEN,this.log=y({file:"github.ts",isLogging:e.debug}),this.log.debug(`Token provided: ${this.token?"yes (length: "+this.token.length+")":"no"}`,"constructor"),this.owner=e.owner||"",this.repo=e.repo||""}async initialize(){if(!this.owner)this.owner=await this.getRepoOwner();if(!this.repo)this.repo=await this.getRepoName()}async getRepoOwner(){try{let{stdout:e}=await he("git",["config","--get","remote.origin.url"]),t=e.trim();if(this.isGitHubUrl(t)){let r=t.match(/github\.com[:/]([^/]+)\//);if(r)return r[1]}}catch{this.log.debug("Failed to get repo owner from git","getRepoOwner")}throw Error("Unable to determine GitHub repository owner")}async getRepoName(){try{let{stdout:e}=await he("git",["config","--get","remote.origin.url"]),t=e.trim();if(this.isGitHubUrl(t)){let r=t.match(/github\.com[:/][^/]+\/([^/.]+)/);if(r)return r[1]}}catch{this.log.debug("Failed to get repo name from git","getRepoName")}throw Error("Unable to determine GitHub repository name")}isGitHubUrl(e){if(e.startsWith("git@github.com:"))return!0;try{return new URL(e).hostname==="github.com"}catch{return!1}}async fetchAlerts(){this.log.debug("Fetching GitHub Dependabot alerts","fetchAlerts");let e=await this.fetchDependabotAlerts();this.log.debug(`Found ${e.length} Dependabot alerts`,"fetchAlerts");let t=this.convertToSecurityAlerts(e);return this.log.debug(`Converted to ${t.length} security alerts`,"fetchAlerts"),t}async fetchDependabotAlerts(){if(await this.initialize(),this.isMockMode())return this.fetchMockAlerts();return this.fetchRealAlerts()}isMockMode(){return process.env[te.MOCK_MODE]==="true"}async fetchRealAlerts(){if(this.token)return this.log.debug("Using GitHub API with provided token","fetchRealAlerts"),this.fetchAlertsWithApi();if(await this.isGhCliAvailable())return this.log.debug("Using gh CLI (no token provided)","fetchRealAlerts"),this.fetchAlertsWithGhCli();throw Error("GitHub CLI not found and no GITHUB_TOKEN provided. Please install gh CLI or set GITHUB_TOKEN environment variable.")}async fetchMockAlerts(){if(this.log.debug("Using mock Dependabot alerts","fetchMockAlerts"),this.shouldForceVulnerable())return this.getMockVulnerableAlerts();return[]}shouldForceVulnerable(){return process.env[te.FORCE_VULNERABLE]==="true"}async getMockVulnerableAlerts(){let e=process.env[te.MOCK_FILE];if(e){let t=await this.loadMockFile(e);if(t)return t}return this.getDefaultMockAlerts()}async loadMockFile(e){try{let{readFileSync:t}=await import("fs"),r=t(e,"utf-8");return JSON.parse(r)}catch(t){return this.log.debug("Failed to read mock file","loadMockFile",{error:t}),null}}getDefaultMockAlerts(){return[bt,vt]}async isGhCliAvailable(){try{return await he("gh",["--version"]),!0}catch{return!1}}async executeGhCli(){let e=["api",`repos/${this.owner}/${this.repo}/dependabot/alerts`,"--paginate"];this.log.debug(`Fetching alerts with gh CLI: gh ${e.join(" ")}`,"executeGhCli");let{stdout:t}=await he("gh",e);return this.log.debug(`gh CLI stdout length: ${t.length}`,"executeGhCli"),t}async fetchAlertsWithGhCli(){try{let e=await U(()=>this.executeGhCli(),{retries:3,factor:2,minTimeout:1000,onFailedAttempt:(r)=>{this.log.debug(`gh CLI attempt ${r.attemptNumber} failed`,"fetchAlertsWithGhCli")}}),t=JSON.parse(e);return this.log.debug(`Parsed ${Array.isArray(t)?t.length:"non-array"} alerts`,"fetchAlertsWithGhCli"),Array.isArray(t)?t:[]}catch(e){throw this.log.error("Failed to fetch alerts with gh CLI","fetchAlertsWithGhCli",{error:e}),Error(`Failed to fetch Dependabot alerts: ${e}`)}}async fetchFromGitHubAPI(){let e=`https://api.github.com/repos/${this.owner}/${this.repo}/dependabot/alerts`,t=await fetch(e,{headers:{Authorization:`Bearer ${this.token}`,Accept:"application/vnd.github.v3+json"}});if(!t.ok){let n=await t.json();throw Error(`GitHub API error: ${n.message||t.statusText}`)}let r=await t.json();return Array.isArray(r)?r:[]}async fetchAlertsWithApi(){try{return await U(()=>this.fetchFromGitHubAPI(),{retries:3,factor:2,minTimeout:1000,onFailedAttempt:(e)=>{this.log.debug(`GitHub API attempt ${e.attemptNumber} failed`,"fetchAlertsWithApi")}})}catch(e){throw this.log.error("Failed to fetch alerts with API","fetchAlertsWithApi",{error:e}),Error(`Failed to fetch Dependabot alerts: ${e}`)}}convertToSecurityAlerts(e){return e.filter((t)=>t.state==="open").map((t)=>{let{security_vulnerability:r,security_advisory:n}=t,i=this.extractCurrentVersion(t);return{packageName:r.package.name,currentVersion:i,vulnerableVersions:r.vulnerable_version_range,patchedVersion:r.first_patched_version?.identifier,severity:this.normalizeSeverity(r.severity),title:n.summary,description:n.description,cve:n.cve_id,url:t.html_url,fixAvailable:!!r.first_patched_version}})}extractCurrentVersion(e){let t=e.security_vulnerability.vulnerable_version_range;if(t.includes(">=")&&t.includes("<=")){let r=t.match(/>= ?([^\s,]+)/);return r?r[1]:"unknown"}if(t.includes(">=")){let r=t.match(/>= ?([^\s,]+)/);return r?r[1]:"unknown"}return"unknown"}normalizeSeverity(e){let t=e.toLowerCase();switch(t){case"low":case"medium":case"high":case"critical":return t;default:return"medium"}}}var he;var cr=f(()=>{P();R();he=Cs(xs)});import{execFile as ws}from"child_process";import{promisify as Rs}from"util";import*as ur from"readline/promises";class X{log;constructor(e={}){this.log=y({file:"security/cli-installer.ts",isLogging:e.debug})}async isInstalled(e){try{return await fe("which",[e]),!0}catch{return!1}}async isInstalledGlobally(e){try{let{stdout:t}=await fe("npm",["list","-g",e,"--depth=0"]);return t.includes(e)}catch{return!1}}async installGlobally(e){this.log.info(`Installing ${e} globally...`,"installGlobally");try{await fe("npm",["install","-g",e],{timeout:120000}),this.log.info(`Successfully installed ${e}`,"installGlobally")}catch(t){throw this.log.error(`Failed to install ${e}`,"installGlobally",{error:t}),Error(`Failed to install ${e}: ${t}`)}}async ensureInstalled(e){let{packageName:t,cliCommand:r}=e;if(await this.isInstalled(r))return this.log.debug(`${r} is already installed`,"ensureInstalled"),!0;if(await this.isInstalledGlobally(t))return this.log.debug(`${t} is installed globally but command not in PATH`,"ensureInstalled"),!0;this.log.info(`${r} not found, installing ${t}...`,"ensureInstalled");try{if(await this.installGlobally(t),!await this.isInstalled(r))return this.log.info(`${t} was installed but ${r} is still not available. Please ensure it's in your PATH.`,"ensureInstalled"),!1;return!0}catch(s){return this.log.error(`Could not install ${t}`,"ensureInstalled",{error:s}),!1}}async getVersion(e){try{let{stdout:t}=await fe(e,["--version"]);return t.trim()}catch{return}}}class Qe{prompts;constructor(e={confirm:Vs,select:$s,input:Is}){this.prompts=e}async promptForSecurityActions(e,t){if(e.length===0)return[];console.log(`
|
|
9
|
+
`)},si=(e)=>{let t=JSON.parse(e),r={},n=(s)=>{if(!(s&&typeof s==="object"))return;Object.entries(s).forEach(([a,c])=>{if(r[a]=!0,c&&typeof c==="object"&&"dependencies"in c)n(c.dependencies)})};if(t.dependencies)n(t.dependencies);return r},oi=async()=>{try{let{stdout:e}=await Dn("npm",["ls","--json","--all"],{encoding:"utf8",maxBuffer:10485760,timeout:3000});return e}catch(e){let t=e;if(t.code===1&&t.stdout)return t.stdout;throw e}},qt=async()=>{if(le!==null)return le;try{let t=await oi(),r=si(t);return le=r,r}catch(t){return J.debug("Failed to get dependency tree","getDependencyTree",t),{}}},Ee=()=>{le=null},je=(e,t=[],r="./",n=J)=>{if(e.length===0)throw n.error("No depPaths provided","findPackageJsonFiles"),Error("No depPaths provided to findPackageJsonFiles");try{n.debug(`Searching with patterns: ${e.join(", ")}, ignoring: ${t.join(", ")}, cwd: ${r}`,"findPackageJsonFiles");let s=ce(e,{cwd:r,ignore:t,absolute:!1,onlyFiles:!0});if(s.length===0){let a=`No package.json files found matching patterns: ${e.join(", ")} in directory: ${r}`;throw n.error(a,"findPackageJsonFiles"),Error(a)}return n.debug(`Found ${s.length} files`,"findPackageJsonFiles"),s}catch(s){throw n.error("Error finding package.json files","findPackageJsonFiles",s),s}};var $=f(()=>{ue();T();P();Dn=Un(Ln),J=y({file:"packageJSON.ts",isLogging:x}),V=new Map});var de,ai=(e,t)=>{return Boolean(t[e])},ci=(e,t)=>{return e.filter((r)=>!ai(r,t))},ui=(e,t)=>{return e>0&&!t},Le=(e,t,r,n)=>{let i=Object.keys(e),s=ci(i,t),o=Boolean(n?.depPaths);if(ui(s.length,o))r.info(`\uD83D\uDC11 Found overrides for packages not in root dependencies: ${s.join(", ")}`,"checkMonorepoOverrides"),r.info("\uD83D\uDCA1 For monorepo support, use --depPaths flag or add depPaths configuration in package.json","checkMonorepoOverrides");return s},li=(e)=>{let t=e?.dependencies||{},r=e?.devDependencies||{},n=e?.peerDependencies||{};return{...t,...r,...n}},di=(e)=>{return e.map((r)=>R(r)).reduce((r,n)=>{if(!Boolean(n))return r;let s=li(n);return{...r,...s}},{})},Jt=(e,t,r,n)=>{let i=n(e,t,r),s=di(e);return{appendix:i,allWorkspaceDeps:s}},pi=(e,t)=>{let r=Boolean(e),n=t.length>0;return r&&n},gi=(e,t)=>{return{...e,dependents:{...e.dependents,...t.dependents}}},Ue=(e,t,r,n)=>{if(!pi(t,r))return e;return n.debug("Using overridePaths configuration for monorepo support","mergeOverridePaths"),Object.values(t).forEach((s)=>{Object.entries(s).forEach(([o,a])=>{if(e[o])e[o]=gi(e[o],a);else e[o]=a})}),e},zt=(e,t)=>{return typeof t[e]==="object"},Yt=(e,t)=>{return Boolean(t[e])},hi=(e,t,r)=>{if(!zt(e,t))return!1;if(Yt(e,r))return!1;return de.debug(`Found unused nested override for ${e}: parent package not in dependencies`,"isUnusedNestedOverride"),!0},fi=async(e,t,r)=>{if(zt(e,t))return!1;if(Yt(e,r))return!1;if(!(Object.keys(r).length>0))return de.debug(`Found unused override for ${e}: no dependencies at all`,"isUnusedSimpleOverride"),!0;let o=await qt();if(Boolean(o[e]))return de.debug(`Keeping override for ${e}: found in dependency tree`,"isUnusedSimpleOverride"),!1;return de.debug(`Found unused override for ${e}: not in dependency tree`,"isUnusedSimpleOverride"),!0},yi=async(e,t,r)=>{if(hi(e,t,r))return!0;return fi(e,t,r)},Xt=async(e,t)=>{let r=Object.keys(e),n=await Promise.all(r.map((i)=>yi(i,e,t)));return r.filter((i,s)=>n[s])},mi=(e,t)=>{if(!t)return!1;return Object.values(t).some((r)=>Object.keys(r).some((n)=>n.startsWith(`${e}@`)))},bi=(e,t)=>{return e.filter((r)=>mi(r,t))},vi=(e,t)=>{return e.filter((r)=>!t.includes(r))},Si=(e,t,r)=>{return t.reduce((n,i)=>{return Object.keys(n).filter((o)=>o.startsWith(`${i}@`)).reduce((o,a)=>{r.debug(`Removed appendix entry for ${a}`,"removeAppendixEntries");let{[a]:c,...l}=o;return l},n)},e)},Oi=async(e,t,r,n,i,s,o,a)=>{let c=await Xt(e,n);if(c.length===0)return{finalOverrides:e,finalAppendix:r};let u=bi(i,s),d=vi(c,u);if(d.length>0){o.debug(`Found ${d.length} packages to remove from overrides: ${d.join(", ")}`,"cleanupUnusedOverrides");let g=a(t,d)||e,m=Si(r,d,o);return{finalOverrides:g,finalAppendix:m}}if(u.length>0)o.info(`\uD83D\uDC11 Keeping overrides for packages tracked in overridePaths: ${u.join(", ")}`,"cleanupUnusedOverrides");return{finalOverrides:e,finalAppendix:r}};var De=f(()=>{T();P();$();de=y({file:"workspace.ts",isLogging:x})});var _e,Pi,Ai=(e)=>{return e.split("/").pop()||""},xi=(e)=>{return e.replace(".patch","")},ki=(e)=>{return e.length>=2?`${e[0]}/${e[1]}`:e[0]},Ci=(e)=>{return e[0]},wi=(e)=>{if(!e.includes("+"))return e;let r=e.split("+");return e.startsWith("@")?ki(r):Ci(r)},Ri=(e,t,r)=>{let n=e[t]||[];return{...e,[t]:[...n,r]}},Ti=(e,t)=>{let r=Ai(e);if(!r.endsWith(".patch"))return t;let i=xi(r),s=wi(i);if(!Boolean(s))return t;return _e.debug(`Found patch for ${s}: ${e}`,"processPatchFile"),Ri(t,s,e)},Vi=(e)=>{return e.reduce((t,r)=>Ti(r,t),{})},Me=(e="./")=>{try{let t=ce(Pi,{cwd:e});return Vi(t)}catch(t){return _e.error("Error detecting patches","detectPatches",t),{}}},Ii=(e,t)=>{return t[e]||[]},$i=(e,t)=>{return Boolean(t[e])},Fi=(e,t)=>{return e.flatMap(([r,n])=>{if($i(r,t))return[];return _e.debug(`Found unused patches for ${r}: ${n.join(", ")}`,"collectUnusedPatches"),n})},We=(e,t)=>{let r=Object.entries(e);return Fi(r,t)},Ni=(e)=>{return e.split("@")[0]},Ei=(e,t,r)=>{let n=Ni(t),i=Ii(n,r);if(!(i.length>0))return e;return{...e,[t]:{...e[t],patches:i}}},Ge=(e,t)=>{return Object.keys(e).reduce((n,i)=>Ei(n,i,t),e)};var He=f(()=>{ue();T();P();_e=y({file:"patches.ts",isLogging:x}),Pi=["patches/*.patch",".patches/*.patch","*.patch","patches/**/*.patch"]});var Zt={};bt(Zt,{updateOverrides:()=>Qt,resolveOverrides:()=>pe,getOverridesByType:()=>F,defineOverride:()=>Ke});var z,ji=(e)=>{return Object.keys(e).length>0},Li=(e)=>{let t=e?.overrides||{};return Object.keys(t).length>0},Ui=(e)=>{return Object.keys(e).length>0},Di=(e,t,r)=>{return e||t||r},_i=(e,t,r)=>{let n=t?.overrides||{};return[{type:"overrides",overrides:e},{type:"pnpmOverrides",overrides:n},{type:"resolutions",overrides:r}]},Mi=(e)=>{return e.filter(({overrides:t})=>Object.keys(t).length>0)},Wi=(e)=>{return e.length>1},Ke=({overrides:e={},pnpm:t={},resolutions:r={}}={})=>{let n=ji(e),i=Li(t),s=Ui(r);if(!Di(n,i,s))return;let a=_i(e,t,r),c=Mi(a);if(Wi(c)){z.error("Only 1 override object allowed","defineOverride");return}return c[0]},Gi=(e)=>{return Object.keys(e).reduce((r,n)=>{let i=e[n];return r[n]=i,r},{})},Hi=(e)=>{return{type:"pnpm",pnpm:{overrides:e}}},Ki=(e)=>{return{type:"resolutions",resolutions:e}},Bi=(e)=>{return{type:"npm",overrides:e}},qi=(e,t)=>{if(e==="pnpmOverrides")return Hi(t);if(e==="resolutions")return Ki(t);return Bi(t)},pe=({config:e={}})=>{let t=Ke(e);if(!t){z.debug("No overrides configuration found","resolveOverrides");return}let{type:n,overrides:i}=t,s=Object.keys(i).length>0,o=Boolean(n);if(!(s&&o)){z.debug("No active overrides found","resolveOverrides");return}let c=Gi(i);return qi(n,c)},Ji=(e)=>{return e?.resolutions},zi=(e)=>{return e?.pnpm?.overrides},Yi=(e)=>{return e?.overrides},F=(e)=>{let t=e?.type;if(!t){z.error("no type found","getOverridesByType");return}if(t==="resolutions")return Ji(e);if(t==="pnpm")return zi(e);return Yi(e)},Xi=(e,t)=>{return!t.includes(e)},Qi=(e,t)=>{return Object.entries(e).reduce((r,[n,i])=>{if(Xi(n,t))r[n]=i;return r},{})},Qt=(e,t)=>{if(!e)return;let n=F(e);if(!n||Object.keys(n).length===0){z.debug("No overrides found to update","updateOverrides");return}return Qi(n,t)};var Y=f(()=>{T();P();z=y({file:"overrides.ts",isLogging:x})});var Zi=(e,t)=>{return t?.find((r)=>r.packageName===e)?.reason},es=(e,t)=>{return t?.[e]},Be=(e,t,r,n)=>{if(t)return t;let i=Zi(e,r);if(i)return i;return es(e,n)},ts=(e,t)=>{if(!Boolean(t))return!1;return t.some((n)=>n.packageName===e)},rs=(e,t)=>{return t?.find((r)=>r.packageName===e)},ns=()=>({securityChecked:!0,securityCheckDate:new Date().toISOString()}),is=(e,t)=>{if(!Boolean(t))return e;return{...e,securityProvider:t}},ss=(e,t)=>{if(!t?.cve)return e;return{...e,cve:t.cve}},os=(e,t)=>{if(!t?.severity)return e;return{...e,severity:t.severity}},as=(e,t)=>{if(!t?.url)return e;return{...e,url:t.url}},qe=(e,t,r)=>{if(!ts(e,t))return{};let i=rs(e,t),s=ns();return s=is(s,r),s=ss(s,i),s=os(s,i),s=as(s,i),s},cs=(e,t)=>{let r={addedDate:new Date().toISOString()};return{...e?{...r,reason:e}:r,...t}},Je=(e,t,r,n)=>{let s=Boolean(t)?t:cs(r,n);return{dependents:e,ledger:s}},ze=(e,t,r)=>{return{...e,[t]:r}},er=(e,t,r)=>{if(!e)return`${t} (transitive dependency)`;return`${t}@${r}`},tr=(e)=>{return typeof e==="object"},us=(e)=>{if(!Boolean(e?.dependents))return!0;return Object.keys(e.dependents).length===0},rr=(e)=>{return Object.keys(e).reduce((r,n)=>{let i=e[n],s=!i,o=us(i);if(s||o)return r;return{...r,[n]:i}},{})},nr=(e)=>{let t=e?.dependencies||{},r=e?.devDependencies||{},n=e?.peerDependencies||{};return{...t,...r,...n}},ir=(e,t)=>{return e.some((r)=>t.includes(r))},sr=(e,t)=>{if(!Boolean(e))return!1;return Object.keys(e).length>0&&t},ge=(e)=>{if(!e)return!1;return Object.keys(e).length>0},or=(e,t,r)=>{let n=e[t]?.dependents||{};return{...e,[t]:{dependents:{...n,...r.dependents}}}};var ls=(e,t,r,n,i,s,o,a,c,l=!1)=>{let u=i.includes(e);if(l&&!u)return s;let d=`${e}@${t}`;if(c.has(d))return{...s,[d]:c.get(d)};let p=s?.[d]?.dependents||{},g=n[e],m=er(u,e,g),b=ze(p,r,m),v=s?.[d]?.ledger,k=Je(b,v,o,a);return c.set(d,k),{...s,[d]:k}},ds=(e,t,r,n,i,s,o,a,c,l,u)=>{let d=`${e}@${t}`;if(u.has(d))return{...s,[d]:u.get(d)};let p=s?.[d]?.dependents||{},g=`${n}@${i[n]} (nested override)`,m=ze(p,r,g),b=s?.[d]?.ledger,v=Be(e,void 0,a,l)||o,k=qe(e,a,c),W=Je(m,b,v,k);return u.set(d,W),{...s,[d]:W}},ps=(e,t,r,n,i,s,o,a,c,l,u)=>{if(!i.includes(e))return s;return Object.entries(t).reduce((h,[p,g])=>ds(p,g,r,e,n,h,o,a,c,l,u),s)},gs=(e,t,r,n,i,s,o,a,c,l,u,d=!1)=>{let h=t[e],p=Be(e,o,a,l),g=qe(e,a,c);if(tr(h))return ps(e,h,r,n,i,s,p,a,c,l,u);return ls(e,h,r,n,i,s,p,g,u,d)},_=({overrides:e={},appendix:t={},dependencies:r={},devDependencies:n={},peerDependencies:i={},packageName:s="",reason:o,securityOverrideDetails:a,securityProvider:c,manualOverrideReasons:l,cache:u=new Map,onlyUsedOverrides:d=!1})=>{let h=Object.keys(e),p={...r,...n,...i},g=Object.keys(p),m=h.reduce((b,v)=>gs(v,e,s,p,g,b,o,a,c,l,u,d),t);return rr(m)},ar=(e,t,r,n=!0)=>{let i=R(e);if(!Boolean(i))return;let{name:o,dependencies:a={},devDependencies:c={},peerDependencies:l={}}=i,u=nr(i),d=Object.keys(u);if(!ir(d,r))return;let p=_({overrides:t,dependencies:a,devDependencies:c,peerDependencies:l,packageName:o,securityOverrideDetails:void 0,manualOverrideReasons:void 0,onlyUsedOverrides:!0});if(sr(p,n)){let{writeFileSync:m}=vt("fs");i.pastoralist={appendix:p},m(e,JSON.stringify(i,null,2))}return{name:o,dependencies:a,devDependencies:c,appendix:p}},hs=(e)=>{return Boolean(e)},fs=(e)=>{if(!hs(e))return null;return F(e)||null},ys=(e,t)=>{let r=R(e);if(!Boolean(r))return null;let{resolveOverrides:i}=(Y(),On(Zt)),s=i({config:r}),o=F(s)||null,a=ge(o);if(a)t.debug(`Found ${Object.keys(o).length} overrides in ${e}`,"constructAppendix");return a?o:null},ms=(e,t)=>{return e.map((r)=>ys(r,t))},bs=(e,t)=>{let r=e.filter((i)=>i!==null),n=ge(t)?{...t}:{};return r.reduce((i,s)=>({...i,...s}),n)},vs=(e,t,r)=>{return e.map((n)=>ar(n,t,r,!1))},Ss=(e,t,r)=>{return or(e,t,r)},Os=(e,t)=>{return Object.entries(t).reduce((n,[i,s])=>Ss(n,i,s),e)},Ps=(e)=>{return e.filter((r)=>r!==null&&r!==void 0&&Boolean(r.appendix)).reduce((r,n)=>Os(r,n.appendix),{})},Ye=(e,t,r)=>{let n=fs(t);if(ge(n))r.debug(`Found ${Object.keys(n).length} overrides in root package.json`,"constructAppendix");let s=ms(e,r),o=bs(s,n);if(!(Object.keys(o).length>0))return r.debug("No overrides found in root or workspace packages","constructAppendix"),{};let c=Object.keys(o);r.debug(`Processing ${c.length} total unique overrides across all packages`,"constructAppendix");let l=vs(e,o,c);return Ps(l)};var he=f(()=>{$();Y()});var cr=(e,t,r,n)=>{return je(e,r,t,n)},ur=(e)=>{let t=e.options?.outputFormat==="json";Ne({appendix:e.finalAppendix,path:e.path,config:e.config,overrides:e.finalOverrides,dryRun:e.options?.dryRun||!1,silent:t,isTesting:e.isTesting})},lr=(e,t,r,n)=>{let i=t.pastoralist?.depPaths,s=e?.depPaths&&e.depPaths.length>0,o=!s&&i,a=As(e,t);return{mode:s||o?"workspace":"root",depPaths:a,hasRootOverrides:r,missingInRoot:n}},As=(e,t)=>{if(e?.depPaths)return e.depPaths;let r=t.pastoralist?.depPaths;if(r==="workspace"||r==="workspaces")return t.workspaces?.map((n)=>`${n}/package.json`)||null;if(Array.isArray(r))return r;if(t.workspaces&&!r)return t.workspaces.map((n)=>`${n}/package.json`);return null};var dr=f(()=>{$()});var xs=(e)=>{let t=Me(e.root),r=Object.keys(t);if(r.length>0)e.log.debug(`Found patches for packages: ${r.join(", ")}`,"stepDetectPatches");return{...e,patchMap:t}},ks=(e)=>{if(!e.config)return e;let t=pe({options:e.options,config:e.config}),r=F(t)||{};if(e.options?.securityOverrides)e.log.debug("Merging security overrides","stepPrepareOverrides"),r={...r,...e.options.securityOverrides};return{...e,overridesData:t,overrides:r}},Cs=(e)=>{if(!e.config)return e;let t=e.overrides||{},r=Object.keys(t).length>0,n={...e.config.dependencies,...e.config.devDependencies,...e.config.peerDependencies},i=Le(t,n,e.log,e.options),s=lr(e.options,e.config,r,i);return{...e,hasRootOverrides:r,rootDeps:n,missingInRoot:i,mode:s}},ws=(e)=>{if(!e.config||!e.mode||!e.overridesData)return e;let t=e.mode.depPaths;if(!(t&&t.length>0))return e;let n=e.options?.ignore||[],i=cr(t,e.root,n,e.log);if(i.length===0)return e;e.log.debug(`Processing ${i.length} workspace packages`,"stepProcessWorkspaces");let{appendix:s,allWorkspaceDeps:o}=Jt(i,e.overridesData,e.log,Ye);return{...e,workspaceAppendix:s,allWorkspaceDeps:o}},Rs=(e)=>{if(!e.config||!e.overrides)return e;let t=e.config.pastoralist?.appendix||{};return{...e,existingAppendix:t}},Ts=(e)=>{if(!e.config||!e.overrides)return e;let{dependencies:t={},devDependencies:r={},peerDependencies:n={}}=e.config,i=_({overrides:e.overrides,dependencies:t,devDependencies:r,peerDependencies:n,packageName:e.config.name||"root",securityOverrideDetails:e.options?.securityOverrideDetails,securityProvider:e.options?.securityProvider,manualOverrideReasons:e.options?.manualOverrideReasons});if(!e.workspaceAppendix)return{...e,appendix:i};return e.log.debug("Merging workspace appendix with root appendix","stepBuildAppendix"),Object.entries(e.workspaceAppendix).forEach(([s,o])=>{let a=i[s];if(!a)i[s]=o;else a.dependents={...a.dependents,...o.dependents}}),{...e,appendix:i}},Vs=(e)=>{if(!e.appendix||!e.patchMap)return e;let t=Ge(e.appendix,e.patchMap);return{...e,appendix:t}},Is=(e)=>{if(!e.config||!e.appendix||!e.missingInRoot)return e;let t=e.config.pastoralist?.overridePaths||e.config.pastoralist?.resolutionPaths;return Ue(e.appendix,t,e.missingInRoot,e.log),{...e,overridePaths:t}},$s=(e)=>{if(!e.patchMap||!e.rootDeps)return e;let t=We(e.patchMap,e.rootDeps);if(t.length>0)e.log.info(`Found ${t.length} potentially unused patch files:`,"stepLogUnusedPatches"),t.forEach((r)=>e.log.info(` - ${r}`,"stepLogUnusedPatches")),e.log.info("Consider removing these patches if the packages are no longer used.","stepLogUnusedPatches");return{...e,allDeps:e.rootDeps}},Fs=(e)=>{if(e.finalOverrides!==void 0&&e.finalAppendix!==void 0)return e;let t=e.overrides||{},r=e.appendix||{};if(!e.overrides||!e.overridesData||!e.appendix)return{...e,finalOverrides:t,finalAppendix:r};return{...e,finalOverrides:e.overrides,finalAppendix:e.appendix}},Ns=(e)=>{if(e.isTesting)return e;if(!e.config||e.finalAppendix===void 0||e.finalOverrides===void 0)return e.log.debug(`Skipping write: config=${!!e.config}, appendix=${e.finalAppendix!==void 0}, overrides=${e.finalOverrides!==void 0}`,"stepWriteResult"),e;return e.log.debug(`Writing results: appendix keys=${Object.keys(e.finalAppendix||{}).length}, override keys=${Object.keys(e.finalOverrides||{}).length}`,"stepWriteResult"),ur({path:e.path,config:e.config,finalAppendix:e.finalAppendix,finalOverrides:e.finalOverrides,options:e.options,isTesting:e.isTesting}),e},Es=(e,...t)=>{return t.reduce((r,n)=>n(r),e)},js=(e)=>{let t=!e.mode?.hasRootOverrides,r=e.mode?.mode==="root",n=Boolean(e.config);if(!(t&&r&&n))return e;return e.log.debug("No overrides found","update"),{...e,finalOverrides:{},finalAppendix:{}}},Xe=(e)=>{let t=e?.path||"package.json",r=e?.root||"./",n=e?.isTesting||!1,i=x||e?.debug||!1,s=y({file:"update",isLogging:i});if(Ee(),V.clear(),!e.config)return s.debug("No config provided","update"),{options:e,path:t,root:r,isTesting:n,log:s};let o={options:e,path:t,root:r,isTesting:n,log:s,config:e.config},a=Es(o,xs,ks,Cs,ws,js,Rs,Ts,Vs,Is,$s,Fs,Ns);if(x)a.log.debug("Update complete","update");return a};var Qe=f(()=>{T();P();$();De();He();Y();he();dr()});class X{debug;isIRLFix;isIRLCatch;log;retryOptions;constructor(e={}){this.debug=e.debug||!1,this.isIRLFix=e.isIRLFix||!1,this.isIRLCatch=e.isIRLCatch||!1,this.log=y({file:"security/osv.ts",isLogging:this.debug}),this.retryOptions=e.retryOptions||{retries:3,factor:2,minTimeout:1000}}async isAvailable(){try{return(await fetch("https://api.osv.dev/v1/query",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({package:{name:"test",ecosystem:"npm"}})})).ok}catch{return!1}}async fetchFromOSVBatchAPI(e){let t=e.map((i)=>({package:{name:i.name,ecosystem:"npm"},version:i.version})),r=await fetch("https://api.osv.dev/v1/querybatch",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({queries:t})});if(!r.ok)throw Error(`HTTP ${r.status}`);return(await r.json()).results||[]}async fetchAlerts(e){if(this.log.debug(`OSV checking ${e.length} packages`,"fetchAlerts"),e.length===0)return[];let t=await U(async()=>{return this.fetchFromOSVBatchAPI(e)},{...this.retryOptions,onFailedAttempt:(s)=>{this.log.debug(`Batch API attempt ${s.attemptNumber} failed`,"fetchAlerts")}}).catch((s)=>{return this.log.debug("Failed to fetch batch results after retries","fetchAlerts",{error:s}),[]}),r=e.map((s,o)=>{let a=t[o];return a?.vulns&&a.vulns.length>0?this.convertOSVAlerts(s,a.vulns):[]}).flat(),n=this.isIRLFix?[Re.ALERT_TO_RESOLVE]:[],i=this.isIRLCatch?[Re.ALERT_TO_CAPTURE]:[];return r.concat(n).concat(i)}convertOSVAlerts(e,t){return t.map((r)=>({packageName:e.name,currentVersion:e.version,vulnerableVersions:this.extractVersionRange(r),patchedVersion:this.extractPatchedVersion(r),severity:this.extractSeverity(r),title:r.summary||r.details||`Vulnerability in ${e.name}`,description:r.details,cve:this.extractCVE(r),url:r.references?.[0]?.url||`https://osv.dev/vulnerability/${r.id}`,fixAvailable:!!this.extractPatchedVersion(r)}))}extractVersionRange(e){let t=e.affected?.[0];if(t?.ranges?.[0]?.events){let r=t.ranges[0].events,n=r.find((s)=>s.introduced)?.introduced||"0",i=r.find((s)=>s.fixed)?.fixed;return i?`>= ${n} < ${i}`:`>= ${n}`}return""}extractPatchedVersion(e){return(e.affected?.[0]?.ranges?.[0]?.events||[]).find((i)=>i.fixed)?.fixed}extractSeverity(e){let t=e.database_specific?.severity||e.severity?.[0]?.score||"medium";if(typeof t==="string"){let r=t.toLowerCase();if(["low","medium","high","critical"].includes(r))return r}return"medium"}extractCVE(e){return e.aliases?.find((t)=>t.startsWith("CVE-"))}}var pr=f(()=>{P();T()});import{execFile as Ls}from"child_process";import{promisify as Us}from"util";class ye{owner;repo;token;log;constructor(e){this.token=e.token||process.env.GITHUB_TOKEN,this.log=y({file:"github.ts",isLogging:e.debug}),this.log.debug(`Token provided: ${this.token?"yes (length: "+this.token.length+")":"no"}`,"constructor"),this.owner=e.owner||"",this.repo=e.repo||""}async initialize(){if(!this.owner)this.owner=await this.getRepoOwner();if(!this.repo)this.repo=await this.getRepoName()}async getRepoOwner(){try{let{stdout:e}=await fe("git",["config","--get","remote.origin.url"]),t=e.trim();if(this.isGitHubUrl(t)){let r=t.match(/github\.com[:/]([^/]+)\//);if(r)return r[1]}}catch{this.log.debug("Failed to get repo owner from git","getRepoOwner")}throw Error("Unable to determine GitHub repository owner")}async getRepoName(){try{let{stdout:e}=await fe("git",["config","--get","remote.origin.url"]),t=e.trim();if(this.isGitHubUrl(t)){let r=t.match(/github\.com[:/][^/]+\/([^/.]+)/);if(r)return r[1]}}catch{this.log.debug("Failed to get repo name from git","getRepoName")}throw Error("Unable to determine GitHub repository name")}isGitHubUrl(e){if(e.startsWith("git@github.com:"))return!0;try{return new URL(e).hostname==="github.com"}catch{return!1}}async fetchAlerts(){this.log.debug("Fetching GitHub Dependabot alerts","fetchAlerts");let e=await this.fetchDependabotAlerts();this.log.debug(`Found ${e.length} Dependabot alerts`,"fetchAlerts");let t=this.convertToSecurityAlerts(e);return this.log.debug(`Converted to ${t.length} security alerts`,"fetchAlerts"),t}async fetchDependabotAlerts(){if(await this.initialize(),this.isMockMode())return this.fetchMockAlerts();return this.fetchRealAlerts()}isMockMode(){return process.env[ne.MOCK_MODE]==="true"}async fetchRealAlerts(){if(this.token)return this.log.debug("Using GitHub API with provided token","fetchRealAlerts"),this.fetchAlertsWithApi();if(await this.isGhCliAvailable())return this.log.debug("Using gh CLI (no token provided)","fetchRealAlerts"),this.fetchAlertsWithGhCli();throw Error("GitHub CLI not found and no GITHUB_TOKEN provided. Please install gh CLI or set GITHUB_TOKEN environment variable.")}async fetchMockAlerts(){if(this.log.debug("Using mock Dependabot alerts","fetchMockAlerts"),this.shouldForceVulnerable())return this.getMockVulnerableAlerts();return[]}shouldForceVulnerable(){return process.env[ne.FORCE_VULNERABLE]==="true"}async getMockVulnerableAlerts(){let e=process.env[ne.MOCK_FILE];if(e){let t=await this.loadMockFile(e);if(t)return t}return this.getDefaultMockAlerts()}async loadMockFile(e){try{let{readFileSync:t}=await import("fs"),r=t(e,"utf-8");return JSON.parse(r)}catch(t){return this.log.debug("Failed to read mock file","loadMockFile",{error:t}),null}}getDefaultMockAlerts(){return[Pt,At]}async isGhCliAvailable(){try{return await fe("gh",["--version"]),!0}catch{return!1}}async executeGhCli(){let e=["api",`repos/${this.owner}/${this.repo}/dependabot/alerts`,"--paginate"];this.log.debug(`Fetching alerts with gh CLI: gh ${e.join(" ")}`,"executeGhCli");let{stdout:t}=await fe("gh",e,{timeout:_s});return this.log.debug(`gh CLI stdout length: ${t.length}`,"executeGhCli"),t}async fetchAlertsWithGhCli(){try{let e=await U(()=>this.executeGhCli(),{retries:3,factor:2,minTimeout:1000,onFailedAttempt:(r)=>{this.log.debug(`gh CLI attempt ${r.attemptNumber} failed`,"fetchAlertsWithGhCli")}}),t=JSON.parse(e);return this.log.debug(`Parsed ${Array.isArray(t)?t.length:"non-array"} alerts`,"fetchAlertsWithGhCli"),Array.isArray(t)?t:[]}catch(e){throw this.log.error("Failed to fetch alerts with gh CLI","fetchAlertsWithGhCli",{error:e}),Error(`Failed to fetch Dependabot alerts: ${e}`)}}async fetchFromGitHubAPI(){let e=`https://api.github.com/repos/${this.owner}/${this.repo}/dependabot/alerts`,t=new AbortController,r=setTimeout(()=>t.abort(),Ds);try{let n=await fetch(e,{headers:{Authorization:`Bearer ${this.token}`,Accept:"application/vnd.github.v3+json"},signal:t.signal});if(!n.ok){let s=await n.json();throw Error(`GitHub API error: ${s.message||n.statusText}`)}let i=await n.json();return Array.isArray(i)?i:[]}finally{clearTimeout(r)}}async fetchAlertsWithApi(){try{return await U(()=>this.fetchFromGitHubAPI(),{retries:3,factor:2,minTimeout:1000,onFailedAttempt:(e)=>{this.log.debug(`GitHub API attempt ${e.attemptNumber} failed`,"fetchAlertsWithApi")}})}catch(e){throw this.log.error("Failed to fetch alerts with API","fetchAlertsWithApi",{error:e}),Error(`Failed to fetch Dependabot alerts: ${e}`)}}convertToSecurityAlerts(e){return e.filter((t)=>t.state==="open").map((t)=>{let{security_vulnerability:r,security_advisory:n}=t,i=this.extractCurrentVersion(t);return{packageName:r.package.name,currentVersion:i,vulnerableVersions:r.vulnerable_version_range,patchedVersion:r.first_patched_version?.identifier,severity:this.normalizeSeverity(r.severity),title:n.summary,description:n.description,cve:n.cve_id,url:t.html_url,fixAvailable:!!r.first_patched_version}})}extractCurrentVersion(e){let t=e.security_vulnerability.vulnerable_version_range;if(t.includes(">=")&&t.includes("<=")){let r=t.match(/>= ?([^\s,]+)/);return r?r[1]:"unknown"}if(t.includes(">=")){let r=t.match(/>= ?([^\s,]+)/);return r?r[1]:"unknown"}return"unknown"}normalizeSeverity(e){let t=e.toLowerCase();switch(t){case"low":case"medium":case"high":case"critical":return t;default:return"medium"}}}var fe,Ds=30000,_s=60000;var gr=f(()=>{P();T();fe=Us(Ls)});import{execFile as Ms}from"child_process";import{promisify as Ws}from"util";import*as fr from"readline/promises";class Q{log;constructor(e={}){this.log=y({file:"security/cli-installer.ts",isLogging:e.debug})}async isInstalled(e){try{return await me("which",[e]),!0}catch{return!1}}async isInstalledGlobally(e){try{let{stdout:t}=await me("npm",["list","-g",e,"--depth=0"]);return t.includes(e)}catch{return!1}}async installGlobally(e){this.log.info(`Installing ${e} globally...`,"installGlobally");try{await me("npm",["install","-g",e],{timeout:120000}),this.log.info(`Successfully installed ${e}`,"installGlobally")}catch(t){throw this.log.error(`Failed to install ${e}`,"installGlobally",{error:t}),Error(`Failed to install ${e}: ${t}`)}}async ensureInstalled(e){let{packageName:t,cliCommand:r}=e;if(await this.isInstalled(r))return this.log.debug(`${r} is already installed`,"ensureInstalled"),!0;if(await this.isInstalledGlobally(t))return this.log.debug(`${t} is installed globally but command not in PATH`,"ensureInstalled"),!0;this.log.info(`${r} not found, installing ${t}...`,"ensureInstalled");try{if(await this.installGlobally(t),!await this.isInstalled(r))return this.log.info(`${t} was installed but ${r} is still not available. Please ensure it's in your PATH.`,"ensureInstalled"),!1;return!0}catch(s){return this.log.error(`Could not install ${t}`,"ensureInstalled",{error:s}),!1}}async getVersion(e){try{let{stdout:t}=await me(e,["--version"]);return t.trim()}catch{return}}}class et{prompts;constructor(e={confirm:Hs,select:Ks,input:Bs}){this.prompts=e}async promptForSecurityActions(e,t){if(e.length===0)return[];console.log(`
|
|
10
10
|
\uD83D\uDD12 Security Vulnerabilities Found
|
|
11
11
|
`),console.log("═".repeat(50));let r=this.generateSummary(e);if(console.log(r),!await this.prompts.confirm("Would you like to review and apply security fixes?",!0))return[];let i=[];for(let o of t){let a=e.find((l)=>l.packageName===o.packageName);if(!a)continue;if(console.log(`
|
|
12
12
|
\uD83D\uDCE6 ${o.packageName}`),console.log(` Current: ${o.fromVersion}`),console.log(` ${this.getSeverityEmoji(a.severity)} ${a.title}`),a.cve)console.log(` CVE: ${a.cve}`);let c=await this.prompts.select("How would you like to handle this vulnerability?",[{name:`✅ Apply fix: Update to ${o.toVersion}`,value:"apply"},{name:"⏭️ Skip this vulnerability",value:"skip"},{name:"\uD83D\uDCDD Enter custom version",value:"custom"}]);if(c==="apply")i.push(o);else if(c==="custom"){let l=await this.prompts.input("Enter the version to use:",o.toVersion);i.push(Object.assign({},o,{toVersion:l}))}}if(i.length>0){if(console.log(`
|
|
13
13
|
\uD83D\uDCCB Selected Overrides:
|
|
14
14
|
`),i.forEach((a)=>{console.log(` ${a.packageName}: ${a.fromVersion} → ${a.toVersion}`)}),!await this.prompts.confirm("Apply these overrides to your package.json?",!0))return[]}return i}generateSummary(e){let t=e.reduce((n,i)=>{return n[i.severity]++,n},{critical:0,high:0,medium:0,low:0}),r=`Found ${e.length} vulnerable package(s):
|
|
15
|
-
`;if(t.critical>0)r+=` ${
|
|
16
|
-
`;if(t.high>0)r+=` ${
|
|
17
|
-
`;if(t.medium>0)r+=` ${
|
|
18
|
-
`;if(t.low>0)r+=` ${
|
|
19
|
-
`;return r}getSeverityEmoji(e){switch(e.toLowerCase()){case"critical":return H("[!]");case"high":return H("[!]");case"medium":return Re("[*]");case"low":return Te("[i]");default:return $t("[*]")}}}var fe,lr=(e)=>{return{low:1,medium:2,high:3,critical:4}[e.toLowerCase()]||0},dr=(e)=>{let t=e.reduce((r,n)=>{let i=`${n.packageName}@${n.currentVersion}:${n.cve||n.title}`,s=r.get(i);if(!s||lr(n.severity)>lr(s.severity))r.set(i,n);return r},new Map);return Array.from(t.values())},pr=(e)=>{let t=Object.assign({},e.dependencies,e.devDependencies,e.peerDependencies);return Object.entries(t).map(([r,n])=>({name:r,version:n.replace(/^[\^~]/,"")}))},Ts=(e,t)=>{try{let r=e.replace(/^[\^~]/,"");if(t.includes(">=")&&t.includes("<")){let[,n]=t.match(/>= ?([^\s,]+)/)||[],[,i]=t.match(/< ?([^\s,]+)/)||[];if(n&&i)return $(r,n)>=0&&$(r,i)<0}if(t.startsWith("<")){let n=t.replace(/< ?/,"");return $(r,n)<0}if(t.startsWith("<=")){let n=t.replace(/<= ?/,"");return $(r,n)<=0}return!1}catch{return!1}},hr=(e,t)=>{let r=Object.assign({},e.dependencies,e.devDependencies,e.peerDependencies);return t.filter((n)=>{let i=r[n.packageName];if(!i)return!1;return n.currentVersion=i,Ts(i,n.vulnerableVersions)})},Xe=()=>{return ur.createInterface({input:process.stdin,output:process.stdout})},Vs=async(e,t=!0)=>{let r=Xe(),n=t?"Y/n":"y/N",i=await r.question(`${e} (${n}): `);r.close();let s=i.trim();if(s==="")return t;return s.toLowerCase().startsWith("y")},$s=async(e,t)=>{let r=Xe();console.log(e),t.forEach((i,s)=>{console.log(` ${s+1}) ${i.name}`)});let n=null;while(n===null){let i=await r.question(`Select (1-${t.length}): `),s=parseInt(i.trim(),10);if(s>=1&&s<=t.length)n=t[s-1].value;else console.log("Invalid selection. Please try again.")}return r.close(),n},Is=async(e,t="")=>{let r=Xe(),n=t?`${e} (${t}): `:`${e}: `,i=await r.question(n);return r.close(),i.trim()||t};var ye=f(()=>{P();fe=Rs(ws)});import{execFile as Fs}from"child_process";import{promisify as Ns}from"util";class me{log;installer;token;constructor(e={}){this.log=y({file:"security/snyk.ts",isLogging:e.debug||!1}),this.installer=new X({debug:e.debug}),this.token=e.token||process.env.SNYK_TOKEN}async ensureInstalled(){return this.installer.ensureInstalled({packageName:"snyk",cliCommand:"snyk"})}async isAuthenticated(){if(!this.token)try{return await Ze("snyk",["config","get","api"]),!0}catch{return!1}return!0}async authenticate(){if(this.token)await Ze("snyk",["config","set",`api=${this.token}`]),this.log.debug("Authenticated with Snyk using provided token","authenticate");else throw Error("Snyk requires authentication. Set SNYK_TOKEN or provide --securityProviderToken")}async validatePrerequisites(){if(!await this.ensureInstalled())return this.log.info("Snyk CLI not available, skipping Snyk scan","validatePrerequisites"),!1;if(!await this.isAuthenticated())try{return await this.authenticate(),!0}catch(r){return this.log.info("Snyk authentication failed, skipping Snyk scan","validatePrerequisites",{error:r}),!1}return!0}async runSnykScan(){let{stdout:e}=await Ze("snyk",["test","--json"],{timeout:60000});return JSON.parse(e)}async fetchAlerts(){if(!await this.validatePrerequisites())return[];try{let t=await this.runSnykScan();return this.convertSnykVulnerabilities(t)}catch(t){let r=t;if(r.stdout)try{let n=JSON.parse(r.stdout);return this.convertSnykVulnerabilities(n)}catch{this.log.debug("Failed to parse Snyk error output","fetchAlerts",{error:t})}return this.log.debug("Snyk scan failed","fetchAlerts",{error:t}),[]}}convertSnykVulnerabilities(e){if(!e.vulnerabilities||!Array.isArray(e.vulnerabilities))return[];return e.vulnerabilities.map((t)=>this.convertVulnToAlert(t))}convertVulnToAlert(e){let t=e.packageName||e.name||"",r=e.version,n=e.semver?.vulnerable||"",i=this.extractPatchedVersion(e),s=this.normalizeSeverity(e.severity),o=e.title,a=e.description,c=e.identifiers?.CVE?.[0],l=e.url||`https://snyk.io/vuln/${e.id}`;return{packageName:t,currentVersion:r,vulnerableVersions:n,patchedVersion:i,severity:s,title:o,description:a,cve:c,url:l,fixAvailable:!!i}}extractPatchedVersion(e){if(e.fixedIn&&e.fixedIn.length>0)return e.fixedIn[0];if(e.upgradePath&&e.upgradePath.length>1){let t=e.upgradePath[e.upgradePath.length-1];if(typeof t==="string")return t.split("@")[1]}return}normalizeSeverity(e){let t=e.toLowerCase();switch(t){case"low":case"medium":case"high":case"critical":return t;default:return"medium"}}}var Ze;var gr=f(()=>{P();ye();Ze=Ns(Fs)});import{execFile as Es}from"child_process";import{promisify as Ls}from"util";class be{log;installer;token;constructor(e={}){this.log=y({file:"security/socket.ts",isLogging:e.debug||!1}),this.installer=new X({debug:e.debug}),this.token=e.token||process.env.SOCKET_SECURITY_API_KEY}async ensureInstalled(){return this.installer.ensureInstalled({packageName:"@socketsecurity/cli",cliCommand:"socket"})}async isAuthenticated(){return!!this.token}async validatePrerequisites(){if(!await this.ensureInstalled())return this.log.info("Socket CLI not available, skipping Socket scan","validatePrerequisites"),!1;if(!await this.isAuthenticated())return this.log.info("Socket requires authentication. Set SOCKET_SECURITY_API_KEY or provide --securityProviderToken","validatePrerequisites"),!1;return!0}async runSocketScan(){let e={...process.env,SOCKET_SECURITY_API_KEY:this.token},{stdout:t}=await js("socket",["report","create","--format","json"],{timeout:60000,env:e});return JSON.parse(t)}async fetchAlerts(){if(!await this.validatePrerequisites())return[];try{let t=await this.runSocketScan();return this.convertSocketAlerts(t)}catch(t){return this.log.debug("Socket scan failed","fetchAlerts",{error:t}),[]}}convertSocketAlerts(e){if(!e?.packages)return[];return e.packages.filter((t)=>t.issues&&t.issues.length>0).flatMap((t)=>t.issues.map((r)=>this.convertIssueToAlert(t,r)))}convertIssueToAlert(e,t){let r=t.type==="vulnerability",n=e.name,i=e.version,s=r?`<= ${i}`:"",o=void 0,a=this.mapSocketSeverity(t.severity),c=t.title||t.type,l=t.description,u=r?t.cve:void 0,d=t.url||`https://socket.dev/npm/package/${n}/overview/${i}`,h=!1;return{packageName:n,currentVersion:i,vulnerableVersions:s,patchedVersion:void 0,severity:a,title:c,description:l,cve:u,url:d,fixAvailable:!1}}mapSocketSeverity(e){switch(e.toLowerCase()){case"critical":return"critical";case"high":return"high";case"medium":case"moderate":return"medium";case"low":case"info":return"low";default:return"medium"}}}var js;var fr=f(()=>{P();ye();js=Ls(Es)});var ve=f(()=>{ar();cr();gr();fr()});var yr=()=>{};import{readFileSync as mr,copyFileSync as br,writeFileSync as Us,existsSync as Q}from"fs";import{resolve as Z}from"path";class Se{providers;log;cache;constructor(e){this.log=y({file:"security/index.ts",isLogging:e.debug}),this.providers=this.createProviders(e),this.cache=new ie({max:500,ttl:3600000})}createProviders(e){return(Array.isArray(e.provider)?e.provider:[e.provider||"osv"]).map((r)=>this.createProvider(r,e))}createProvider(e,t){switch(e){case"osv":return new Y({debug:t.debug,isIRLFix:t.isIRLFix,isIRLCatch:t.isIRLCatch});case"github":return new ge({debug:t.debug,token:t.token});case"snyk":return new me({debug:t.debug,token:t.token});case"socket":return new be({debug:t.debug,token:t.token});default:return this.log.debug(`Provider ${e} not yet implemented, using OSV`,"createProvider"),new Y({debug:t.debug,isIRLFix:t.isIRLFix,isIRLCatch:t.isIRLCatch})}}generateCacheKey(e){let t=e.map((n)=>`${n.name}@${n.version}`).sort().join("|");return`${this.providers.map((n)=>n.constructor.name).sort().join("|")}:${t}`}async checkSecurity(e,t={}){this.log.debug("Starting security check","checkSecurity");try{let r=pr(e);if(r.length===0)return this.log.debug("No packages to check","checkSecurity"),{alerts:[],overrides:[],updates:[]};let n=this.generateCacheKey(r),i=this.cache.get(n),s;if(i)this.log.debug("Using cached security results","checkSecurity"),s=i;else s=(await Promise.all(this.providers.map((h)=>h.fetchAlerts(r)))).flat(),this.cache.set(n,s);this.log.debug(`Found ${s.length} security alerts from ${this.providers.length} provider(s)`,"checkSecurity");let o=dr(s);if(t.depPaths&&t.depPaths.length>0){this.log.debug("Scanning workspace packages for vulnerabilities","checkSecurity");let d=await this.findWorkspaceVulnerabilities(t.depPaths,t.root||"./",s);o=[...o,...d]}this.log.debug(`Found ${o.length} vulnerable packages in dependencies`,"checkSecurity");let c=this.generateOverrides(o),l=await this.checkOverrideUpdates(e,s);if(t.interactive&&o.length>0)c=await new Qe().promptForSecurityActions(o,c);return{alerts:o,overrides:c,updates:l}}catch(r){throw this.log.error("Security check failed","checkSecurity",{error:r}),r}}readPackageFile(e){try{let t=mr(e,"utf-8"),r=JSON.parse(t);if(!(r&&typeof r==="object"))return this.log.debug(`Invalid package.json format in ${e}`,"readPackageFile"),null;return r}catch(t){return this.log.debug(`Failed to check ${e}`,"readPackageFile",{error:t}),null}}isNewVulnerability(e,t){return!t.find((n)=>n.packageName===e.packageName&&n.currentVersion===e.currentVersion)}extractNewVulnerabilities(e,t,r){return hr(e,t).filter((i)=>this.isNewVulnerability(i,r))}async findWorkspaceVulnerabilities(e,t,r){try{let n=e.map((a)=>Z(t,a)),i=await Lt(n,{ignore:["**/node_modules/**"],absolute:!0});return(await Promise.all(i.map(async(a)=>{let c=this.readPackageFile(a);if(!c)return[];return this.extractNewVulnerabilities(c,r,[])}))).flat()}catch(n){return this.log.error("Failed to find workspace vulnerabilities","findWorkspaceVulnerabilities",{error:n}),[]}}async checkOverrideUpdates(e,t){let r=e.overrides||e.pnpm?.overrides||e.resolutions||{},n=e.pastoralist?.appendix||{},s=Object.entries(r).filter(([a,c])=>typeof c==="string").map(([a,c])=>{let l=`${a}@${c}`,u=n[l];if(!u?.ledger?.securityChecked)return null;let p=t.filter((v)=>v.packageName===a&&v.patchedVersion).find((v)=>$(v.patchedVersion,c)>0);if(!p)return null;return{packageName:a,currentOverride:c,newerVersion:p.patchedVersion,reason:`Newer security patch available: ${p.title}`,addedDate:u.ledger?.addedDate}}).filter((a)=>a!==null);if(s.length>0)this.log.debug(`Found ${s.length} override updates available`,"checkOverrideUpdates");return s}generateOverrides(e){return e.filter((t)=>t.fixAvailable&&t.patchedVersion).map((t)=>{let r={packageName:t.packageName,fromVersion:t.currentVersion,toVersion:t.patchedVersion,reason:`Security fix: ${t.title} (${t.severity})`,severity:t.severity},n=t.cve?{cve:t.cve}:{},i=t.description?{description:t.description}:{},s=t.url?{url:t.url}:{};return Object.assign({},r,n,i,s)})}generatePackageOverrides(e){return e.reduce((t,r)=>{let n=t[r.packageName];if(n&&typeof n==="string"){if($(r.toVersion,n)>0)return Object.assign({},t,{[r.packageName]:r.toVersion});return t}return Object.assign({},t,{[r.packageName]:r.toVersion})},{})}formatVulnerabilityEntry(e){let t=[];if(t.push(`[${e.severity.toUpperCase()}] ${e.packageName}@${e.currentVersion}
|
|
15
|
+
`;if(t.critical>0)r+=` ${K("[CRITICAL]")} ${t.critical}
|
|
16
|
+
`;if(t.high>0)r+=` ${K("[HIGH] ")} ${t.high}
|
|
17
|
+
`;if(t.medium>0)r+=` ${Ve("[MEDIUM] ")} ${t.medium}
|
|
18
|
+
`;if(t.low>0)r+=` ${Ie("[LOW] ")} ${t.low}
|
|
19
|
+
`;return r}getSeverityEmoji(e){switch(e.toLowerCase()){case"critical":return K("[!]");case"high":return K("[!]");case"medium":return Ve("[*]");case"low":return Ie("[i]");default:return jt("[*]")}}}var me,hr=(e)=>{return{low:1,medium:2,high:3,critical:4}[e.toLowerCase()]||0},yr=(e)=>{let t=e.reduce((r,n)=>{let i=`${n.packageName}@${n.currentVersion}:${n.cve||n.title}`,s=r.get(i);if(!s||hr(n.severity)>hr(s.severity))r.set(i,n);return r},new Map);return Array.from(t.values())},mr=(e)=>{let t=Object.assign({},e.dependencies,e.devDependencies,e.peerDependencies);return Object.entries(t).map(([r,n])=>({name:r,version:n.replace(/^[\^~]/,"")}))},Gs=(e,t)=>{try{let r=e.replace(/^[\^~]/,"");if(t.includes(">=")&&t.includes("<")){let[,n]=t.match(/>= ?([^\s,]+)/)||[],[,i]=t.match(/< ?([^\s,]+)/)||[];if(n&&i)return I(r,n)>=0&&I(r,i)<0}if(t.startsWith("<")){let n=t.replace(/< ?/,"");return I(r,n)<0}if(t.startsWith("<=")){let n=t.replace(/<= ?/,"");return I(r,n)<=0}return!1}catch{return!1}},br=(e,t)=>{let r=Object.assign({},e.dependencies,e.devDependencies,e.peerDependencies);return t.filter((n)=>{let i=r[n.packageName];if(!i)return!1;return n.currentVersion=i,Gs(i,n.vulnerableVersions)})},Ze=()=>{return fr.createInterface({input:process.stdin,output:process.stdout})},Hs=async(e,t=!0)=>{let r=Ze(),n=t?"Y/n":"y/N",i=await r.question(`${e} (${n}): `);r.close();let s=i.trim();if(s==="")return t;return s.toLowerCase().startsWith("y")},Ks=async(e,t)=>{let r=Ze();console.log(e),t.forEach((i,s)=>{console.log(` ${s+1}) ${i.name}`)});let n=null;while(n===null){let i=await r.question(`Select (1-${t.length}): `),s=parseInt(i.trim(),10);if(s>=1&&s<=t.length)n=t[s-1].value;else console.log("Invalid selection. Please try again.")}return r.close(),n},Bs=async(e,t="")=>{let r=Ze(),n=t?`${e} (${t}): `:`${e}: `,i=await r.question(n);return r.close(),i.trim()||t};var be=f(()=>{P();me=Ws(Ms)});import{execFile as qs}from"child_process";import{promisify as Js}from"util";class ve{log;installer;token;constructor(e={}){this.log=y({file:"security/snyk.ts",isLogging:e.debug||!1}),this.installer=new Q({debug:e.debug}),this.token=e.token||process.env.SNYK_TOKEN}async ensureInstalled(){return this.installer.ensureInstalled({packageName:"snyk",cliCommand:"snyk"})}async isAuthenticated(){if(!this.token)try{return await tt("snyk",["config","get","api"]),!0}catch{return!1}return!0}async authenticate(){if(this.token)await tt("snyk",["config","set",`api=${this.token}`]),this.log.debug("Authenticated with Snyk using provided token","authenticate");else throw Error("Snyk requires authentication. Set SNYK_TOKEN or provide --securityProviderToken")}async validatePrerequisites(){if(!await this.ensureInstalled())return this.log.info("Snyk CLI not available, skipping Snyk scan","validatePrerequisites"),!1;if(!await this.isAuthenticated())try{return await this.authenticate(),!0}catch(r){return this.log.info("Snyk authentication failed, skipping Snyk scan","validatePrerequisites",{error:r}),!1}return!0}async runSnykScan(){let{stdout:e}=await tt("snyk",["test","--json"],{timeout:60000});return JSON.parse(e)}async fetchAlerts(){if(!await this.validatePrerequisites())return[];try{let t=await this.runSnykScan();return this.convertSnykVulnerabilities(t)}catch(t){let r=t;if(r.stdout)try{let n=JSON.parse(r.stdout);return this.convertSnykVulnerabilities(n)}catch{this.log.debug("Failed to parse Snyk error output","fetchAlerts",{error:t})}return this.log.debug("Snyk scan failed","fetchAlerts",{error:t}),[]}}convertSnykVulnerabilities(e){if(!e.vulnerabilities||!Array.isArray(e.vulnerabilities))return[];return e.vulnerabilities.map((t)=>this.convertVulnToAlert(t))}convertVulnToAlert(e){let t=e.packageName||e.name||"",r=e.version,n=e.semver?.vulnerable||"",i=this.extractPatchedVersion(e),s=this.normalizeSeverity(e.severity),o=e.title,a=e.description,c=e.identifiers?.CVE?.[0],l=e.url||`https://snyk.io/vuln/${e.id}`;return{packageName:t,currentVersion:r,vulnerableVersions:n,patchedVersion:i,severity:s,title:o,description:a,cve:c,url:l,fixAvailable:!!i}}extractPatchedVersion(e){if(e.fixedIn&&e.fixedIn.length>0)return e.fixedIn[0];if(e.upgradePath&&e.upgradePath.length>1){let t=e.upgradePath[e.upgradePath.length-1];if(typeof t==="string")return t.split("@")[1]}return}normalizeSeverity(e){let t=e.toLowerCase();switch(t){case"low":case"medium":case"high":case"critical":return t;default:return"medium"}}}var tt;var vr=f(()=>{P();be();tt=Js(qs)});import{execFile as zs}from"child_process";import{promisify as Ys}from"util";class Se{log;installer;token;constructor(e={}){this.log=y({file:"security/socket.ts",isLogging:e.debug||!1}),this.installer=new Q({debug:e.debug}),this.token=e.token||process.env.SOCKET_SECURITY_API_KEY}async ensureInstalled(){return this.installer.ensureInstalled({packageName:"@socketsecurity/cli",cliCommand:"socket"})}async isAuthenticated(){return!!this.token}async validatePrerequisites(){if(!await this.ensureInstalled())return this.log.info("Socket CLI not available, skipping Socket scan","validatePrerequisites"),!1;if(!await this.isAuthenticated())return this.log.info("Socket requires authentication. Set SOCKET_SECURITY_API_KEY or provide --securityProviderToken","validatePrerequisites"),!1;return!0}async runSocketScan(){let e={...process.env,SOCKET_SECURITY_API_KEY:this.token},{stdout:t}=await Xs("socket",["report","create","--format","json"],{timeout:60000,env:e});return JSON.parse(t)}async fetchAlerts(){if(!await this.validatePrerequisites())return[];try{let t=await this.runSocketScan();return this.convertSocketAlerts(t)}catch(t){return this.log.debug("Socket scan failed","fetchAlerts",{error:t}),[]}}convertSocketAlerts(e){if(!e?.packages)return[];return e.packages.filter((t)=>t.issues&&t.issues.length>0).flatMap((t)=>t.issues.map((r)=>this.convertIssueToAlert(t,r)))}convertIssueToAlert(e,t){let r=t.type==="vulnerability",n=e.name,i=e.version,s=r?`<= ${i}`:"",o=void 0,a=this.mapSocketSeverity(t.severity),c=t.title||t.type,l=t.description,u=r?t.cve:void 0,d=t.url||`https://socket.dev/npm/package/${n}/overview/${i}`,h=!1;return{packageName:n,currentVersion:i,vulnerableVersions:s,patchedVersion:void 0,severity:a,title:c,description:l,cve:u,url:d,fixAvailable:!1}}mapSocketSeverity(e){switch(e.toLowerCase()){case"critical":return"critical";case"high":return"high";case"medium":case"moderate":return"medium";case"low":case"info":return"low";default:return"medium"}}}var Xs;var Sr=f(()=>{P();be();Xs=Ys(zs)});var Oe=f(()=>{pr();gr();vr();Sr()});var Or=()=>{};import{readFileSync as Pr,copyFileSync as Ar,writeFileSync as Qs,existsSync as Z}from"fs";import{resolve as ee}from"path";class Pe{providers;log;cache;constructor(e){this.log=y({file:"security/index.ts",isLogging:e.debug}),this.providers=this.createProviders(e),this.cache=new oe({max:500,ttl:3600000})}createProviders(e){return(Array.isArray(e.provider)?e.provider:[e.provider||"osv"]).map((r)=>this.createProvider(r,e))}createProvider(e,t){switch(e){case"osv":return new X({debug:t.debug,isIRLFix:t.isIRLFix,isIRLCatch:t.isIRLCatch});case"github":return new ye({debug:t.debug,token:t.token});case"snyk":return new ve({debug:t.debug,token:t.token});case"socket":return new Se({debug:t.debug,token:t.token});default:return this.log.debug(`Provider ${e} not yet implemented, using OSV`,"createProvider"),new X({debug:t.debug,isIRLFix:t.isIRLFix,isIRLCatch:t.isIRLCatch})}}generateCacheKey(e){let t=e.map((n)=>`${n.name}@${n.version}`).sort().join("|");return`${this.providers.map((n)=>n.constructor.name).sort().join("|")}:${t}`}async checkSecurity(e,t={}){this.log.debug("Starting security check","checkSecurity");try{let r=mr(e);if(r.length===0)return this.log.debug("No packages to check","checkSecurity"),{alerts:[],overrides:[],updates:[]};let n=this.generateCacheKey(r),i=this.cache.get(n),s;if(i)this.log.debug("Using cached security results","checkSecurity"),s=i;else s=(await Promise.all(this.providers.map((h)=>h.fetchAlerts(r)))).flat(),this.cache.set(n,s);this.log.debug(`Found ${s.length} security alerts from ${this.providers.length} provider(s)`,"checkSecurity");let o=yr(s);if(t.depPaths&&t.depPaths.length>0){this.log.debug("Scanning workspace packages for vulnerabilities","checkSecurity");let d=await this.findWorkspaceVulnerabilities(t.depPaths,t.root||"./",s);o=[...o,...d]}this.log.debug(`Found ${o.length} vulnerable packages in dependencies`,"checkSecurity");let c=this.generateOverrides(o),l=await this.checkOverrideUpdates(e,s);if(t.interactive&&o.length>0)c=await new et().promptForSecurityActions(o,c);return{alerts:o,overrides:c,updates:l}}catch(r){throw this.log.error("Security check failed","checkSecurity",{error:r}),r}}readPackageFile(e){try{let t=Pr(e,"utf-8"),r=JSON.parse(t);if(!(r&&typeof r==="object"))return this.log.debug(`Invalid package.json format in ${e}`,"readPackageFile"),null;return r}catch(t){return this.log.debug(`Failed to check ${e}`,"readPackageFile",{error:t}),null}}isNewVulnerability(e,t){return!t.find((n)=>n.packageName===e.packageName&&n.currentVersion===e.currentVersion)}extractNewVulnerabilities(e,t,r){return br(e,t).filter((i)=>this.isNewVulnerability(i,r))}async findWorkspaceVulnerabilities(e,t,r){try{let n=e.map((a)=>ee(t,a)),i=await Mt(n,{ignore:["**/node_modules/**"],absolute:!0});return(await Promise.all(i.map(async(a)=>{let c=this.readPackageFile(a);if(!c)return[];return this.extractNewVulnerabilities(c,r,[])}))).flat()}catch(n){return this.log.error("Failed to find workspace vulnerabilities","findWorkspaceVulnerabilities",{error:n}),[]}}async checkOverrideUpdates(e,t){let r=e.overrides||e.pnpm?.overrides||e.resolutions||{},n=e.pastoralist?.appendix||{},s=Object.entries(r).filter(([a,c])=>typeof c==="string").map(([a,c])=>{let l=`${a}@${c}`,u=n[l];if(!u?.ledger?.securityChecked)return null;let p=t.filter((b)=>b.packageName===a&&b.patchedVersion).find((b)=>I(b.patchedVersion,c)>0);if(!p)return null;return{packageName:a,currentOverride:c,newerVersion:p.patchedVersion,reason:`Newer security patch available: ${p.title}`,addedDate:u.ledger?.addedDate}}).filter((a)=>a!==null);if(s.length>0)this.log.debug(`Found ${s.length} override updates available`,"checkOverrideUpdates");return s}generateOverrides(e){return e.filter((t)=>t.fixAvailable&&t.patchedVersion).map((t)=>{let r={packageName:t.packageName,fromVersion:t.currentVersion,toVersion:t.patchedVersion,reason:`Security fix: ${t.title} (${t.severity})`,severity:t.severity},n=t.cve?{cve:t.cve}:{},i=t.description?{description:t.description}:{},s=t.url?{url:t.url}:{};return Object.assign({},r,n,i,s)})}generatePackageOverrides(e){return e.reduce((t,r)=>{let n=t[r.packageName];if(n&&typeof n==="string"){if(I(r.toVersion,n)>0)return Object.assign({},t,{[r.packageName]:r.toVersion});return t}return Object.assign({},t,{[r.packageName]:r.toVersion})},{})}formatVulnerabilityEntry(e){let t=[];if(t.push(`[${e.severity.toUpperCase()}] ${e.packageName}@${e.currentVersion}
|
|
20
20
|
`),t.push(` ${e.title}
|
|
21
21
|
`),Boolean(e.cve))t.push(` CVE: ${e.cve}
|
|
22
22
|
`);if(e.fixAvailable&&e.patchedVersion)t.push(` Fix available: ${e.patchedVersion}
|
|
@@ -34,11 +34,11 @@ Security Check Report
|
|
|
34
34
|
`;if(e.length===0)return r+`No vulnerable packages found
|
|
35
35
|
`;let i=`Found ${e.length} vulnerable package(s):
|
|
36
36
|
|
|
37
|
-
`,s=e.map((a)=>this.formatVulnerabilityEntry(a)).join(""),o=this.formatOverridesSection(t);return[r,i,s,o].filter(Boolean).join("")}createBackup(e){let t=`${e}.backup-${Date.now()}`;return
|
|
37
|
+
`,s=e.map((a)=>this.formatVulnerabilityEntry(a)).join(""),o=this.formatOverridesSection(t);return[r,i,s,o].filter(Boolean).join("")}createBackup(e){let t=`${e}.backup-${Date.now()}`;return Ar(e,t),this.log.debug(`Created backup at ${t}`,"createBackup"),t}applyOverridesToPackageJson(e,t,r){if(t==="pnpm")return{...e,pnpm:{...e.pnpm||{},overrides:{...e.pnpm?.overrides||{},...r}}};let n=this.getOverrideField(t);return{...e,[n]:{...e[n]||{},...r}}}logInstallInstructions(e){console.log(`
|
|
38
38
|
⚠️ Don't forget to run your package manager install command:`);let t={yarn:"yarn install",pnpm:"pnpm install",bun:"bun install",npm:"npm install"};console.log(` ${t[e]||t.npm}`)}logSuccess(e,t,r,n,i){if(console.log(`
|
|
39
39
|
✅ Auto-fix applied successfully!`),console.log(`\uD83D\uDCDD Updated ${e} with ${Object.keys(r).length} security override(s)`),console.log(`\uD83D\uDCBE Backup saved to ${t}`),Object.keys(r).length>0)console.log(`
|
|
40
|
-
\uD83D\uDCCB Applied overrides:`),Object.entries(r).forEach(([o,a])=>{let c=n.find((l)=>l.packageName===o);console.log(` ${o}: ${a} (${c?.severity||"unknown"} severity)`)});this.logInstallInstructions(i)}applyAutoFix(e,t){try{let r=t||
|
|
41
|
-
`),this.logSuccess(r,n,o,e,s)}catch(r){throw this.log.error("Failed to apply auto-fix","applyAutoFix",{error:r}),Error(`Auto-fix failed: ${r}`)}}detectPackageManager(){try{let e=process.cwd();if(
|
|
40
|
+
\uD83D\uDCCB Applied overrides:`),Object.entries(r).forEach(([o,a])=>{let c=n.find((l)=>l.packageName===o);console.log(` ${o}: ${a} (${c?.severity||"unknown"} severity)`)});this.logInstallInstructions(i)}applyAutoFix(e,t){try{let r=t||ee(process.cwd(),"package.json");if(!Z(r))throw Error(`package.json not found at ${r}`);let n=this.createBackup(r),i=JSON.parse(Pr(r,"utf-8")),s=this.detectPackageManager(),o=this.generatePackageOverrides(e),a=e.map((v)=>{let k={packageName:v.packageName,reason:v.reason};if(v.cve)k.cve=v.cve;if(v.severity)k.severity=v.severity;if(v.description)k.description=v.description;if(v.url)k.url=v.url;return k}),c=this.providers[0]?.constructor.name.toLowerCase()||"",l="osv";if(c.includes("github"))l="github";else if(c.includes("snyk"))l="snyk";else if(c.includes("socket"))l="socket";let u=i.pastoralist?.appendix||{},d=i.dependencies||{},h=i.devDependencies||{},p=i.peerDependencies||{},g=i.name||"",m=_({overrides:o,appendix:u,dependencies:d,devDependencies:h,peerDependencies:p,packageName:g,securityOverrideDetails:a,securityProvider:l}),b=this.applyOverridesToPackageJson(i,s,o);b.pastoralist=b.pastoralist||{},b.pastoralist.appendix=m,Qs(r,JSON.stringify(b,null,2)+`
|
|
41
|
+
`),this.logSuccess(r,n,o,e,s)}catch(r){throw this.log.error("Failed to apply auto-fix","applyAutoFix",{error:r}),Error(`Auto-fix failed: ${r}`)}}detectPackageManager(){try{let e=process.cwd();if(Z(ee(e,"bun.lockb")))return"bun";if(Z(ee(e,"yarn.lock")))return"yarn";if(Z(ee(e,"pnpm-lock.yaml")))return"pnpm";return"npm"}catch{return"npm"}}getOverrideField(e){switch(e){case"yarn":return"resolutions";case"pnpm":case"npm":case"bun":default:return"overrides"}}rollbackAutoFix(e){try{if(!Z(e))throw Error(`Backup file not found at ${e}`);let t=e.replace(/\.backup-\d+$/,"");Ar(e,t),console.log(`✅ Rolled back to ${e}`)}catch(t){throw this.log.error("Failed to rollback","rollbackAutoFix",{error:t}),Error(`Rollback failed: ${t}`)}}}var rt=f(()=>{Oe();P();be();he();ue();Oe();Or();Oe()});function Cr(e){if(!oo(e))return;return e}var xr,N=(e)=>{return typeof e==="object"&&e!==null&&!Array.isArray(e)},E=(e)=>{return typeof e==="string"},M=(e)=>{return typeof e==="boolean"},kr=(e)=>{return Array.isArray(e)},Ae=(e)=>{return kr(e)&&e.every(E)},it=(e)=>{return E(e)&&["osv","github","snyk","npm","socket"].includes(e)},Zs=(e)=>{if(it(e))return!0;return kr(e)&&e.every(it)},eo=(e)=>{return E(e)&&["low","medium","high","critical"].includes(e)},to=(e)=>{return N(e)},ro=(e)=>{if(!N(e))return!1;if(!(("addedDate"in e)&&E(e.addedDate)))return!1;if("reason"in e&&e.reason!==void 0&&!E(e.reason))return!1;if("securityChecked"in e&&e.securityChecked!==void 0&&!M(e.securityChecked))return!1;if("securityCheckDate"in e&&e.securityCheckDate!==void 0&&!E(e.securityCheckDate))return!1;if("securityProvider"in e&&e.securityProvider!==void 0&&!it(e.securityProvider))return!1;return!0},no=(e)=>{if(!N(e))return!1;if("rootDeps"in e&&e.rootDeps!==void 0&&!Ae(e.rootDeps))return!1;if("dependents"in e&&e.dependents!==void 0&&!to(e.dependents))return!1;if("patches"in e&&e.patches!==void 0&&!Ae(e.patches))return!1;if("ledger"in e&&e.ledger!==void 0&&!ro(e.ledger))return!1;return!0},nt=(e)=>{if(!N(e))return!1;return Object.values(e).every(no)},io=(e)=>{if(!N(e))return!1;if("enabled"in e&&e.enabled!==void 0&&!M(e.enabled))return!1;if("provider"in e&&e.provider!==void 0&&!Zs(e.provider))return!1;if("autoFix"in e&&e.autoFix!==void 0&&!M(e.autoFix))return!1;if("interactive"in e&&e.interactive!==void 0&&!M(e.interactive))return!1;if("securityProviderToken"in e&&e.securityProviderToken!==void 0&&!E(e.securityProviderToken))return!1;if("severityThreshold"in e&&e.severityThreshold!==void 0&&!eo(e.severityThreshold))return!1;if("excludePackages"in e&&e.excludePackages!==void 0&&!Ae(e.excludePackages))return!1;if("hasWorkspaceSecurityChecks"in e&&e.hasWorkspaceSecurityChecks!==void 0&&!M(e.hasWorkspaceSecurityChecks))return!1;return!0},so=(e)=>{if(e==="workspace"||e==="workspaces")return!0;return Ae(e)},oo=(e)=>{if(!N(e))return!1;if("appendix"in e&&e.appendix!==void 0&&!nt(e.appendix))return!1;if("depPaths"in e&&e.depPaths!==void 0&&!so(e.depPaths))return!1;if("checkSecurity"in e&&e.checkSecurity!==void 0&&!M(e.checkSecurity))return!1;if("overridePaths"in e&&e.overridePaths!==void 0){if(!N(e.overridePaths))return!1;if(!Object.values(e.overridePaths).every(nt))return!1}if("resolutionPaths"in e&&e.resolutionPaths!==void 0){if(!N(e.resolutionPaths))return!1;if(!Object.values(e.resolutionPaths).every(nt))return!1}if("security"in e&&e.security!==void 0&&!io(e.security))return!1;return!0};var xe=f(()=>{xr=[".pastoralistrc",".pastoralistrc.json","pastoralist.json","pastoralist.config.js","pastoralist.config.ts"]});import{existsSync as ao,readFileSync as co}from"fs";import{resolve as wr}from"path";var st,uo=()=>{st.clear()},lo=(e)=>e.endsWith(".json")||e===".pastoralistrc",po=(e)=>{let t=co(e,"utf8");return JSON.parse(t)},go=async(e)=>{let r=await import(wr(e));return r.default||r},ho=async(e,t)=>{if(lo(e))return po(t);return await go(t)},fo=(e,t)=>{if(!t)return e;return Cr(e)||null},yo=async(e,t,r)=>{let n=wr(t,e);if(!ao(n))return null;try{let i=await ho(e,n);if(!i)return null;return fo(i,r)}catch(i){let s=i instanceof Error?i.message:String(i);return console.error(`Failed to load config from ${e}: ${s}`),null}},ke=async(e=process.cwd(),t=!0)=>{for(let r of xr){let n=await yo(r,e,t);if(n!==null)return n}return},mo=(e,t)=>{if(!e&&!t)return;if(!e)return t;if(!t)return e;let r=(n,i)=>{if(!e[n])return i;let s=e[n],o=Object.assign({},s.dependents,i.dependents),a=i.patches?(s.patches||[]).concat(i.patches):s.patches;return{dependents:o,patches:a,ledger:i.ledger||s.ledger}};return Object.entries(t).reduce((n,[i,s])=>({...n,[i]:r(i,s)}),{...e})},Rr=(e,t)=>{if(!e)return t;if(!t)return e;let r=mo(e.appendix,t.appendix),n=Object.assign({},e.overridePaths,t.overridePaths),i=Object.assign({},e.resolutionPaths,t.resolutionPaths),s=Object.assign({},e.security,t.security);return Object.assign({},e,t,{appendix:r,overridePaths:n,resolutionPaths:i,security:s})},bo=async(e=process.cwd(),t,r=!0)=>{let n=`${e}:${r}:${JSON.stringify(t)}`,i=st.get(n);if(i)return i;let s=await ke(e,r),o=Rr(s,t);if(o)st.set(n,o);return o};var ot=f(()=>{xe();xe();xe();st=new Map});var at,Tr=`
|
|
42
42
|
Pastoralist - A utility CLI to manage your dependency overrides
|
|
43
43
|
|
|
44
44
|
Usage: pastoralist [command] [options]
|
|
@@ -49,6 +49,7 @@ Commands:
|
|
|
49
49
|
Options:
|
|
50
50
|
--debug Enable debug mode
|
|
51
51
|
--dry-run Preview changes without writing to package.json
|
|
52
|
+
--outputFormat <format> Output format: text (default) or json
|
|
52
53
|
-p, --path <path> Specifies a path to a package.json (default: "package.json")
|
|
53
54
|
-d, --depPaths [paths...] Specifies glob paths to package.jsons
|
|
54
55
|
--ignore [paths...] Specifies glob paths to ignore
|
|
@@ -63,30 +64,30 @@ Options:
|
|
|
63
64
|
--interactive Run security checks in interactive mode
|
|
64
65
|
--hasWorkspaceSecurityChecks Include workspace packages in security scan
|
|
65
66
|
--promptForReasons Prompt for reasons when adding manual overrides
|
|
66
|
-
`,
|
|
67
|
+
`,Vr=2;var Ir=f(()=>{at=[{flags:["--debug"],hasValue:!1},{flags:["--dry-run"],hasValue:!1},{flags:["--outputFormat"],hasValue:!0,defaultValue:"text"},{flags:["-p","--path"],hasValue:!0,defaultValue:"package.json"},{flags:["-d","--depPaths"],hasValue:!0,isArray:!0},{flags:["--ignore"],hasValue:!0,isArray:!0},{flags:["-r","--root"],hasValue:!0},{flags:["-t","--isTestingCLI"],hasValue:!1},{flags:["--isTesting"],hasValue:!1},{flags:["--isIRLFix"],hasValue:!1},{flags:["--isIRLCatch"],hasValue:!1},{flags:["--init"],hasValue:!1},{flags:["--checkSecurity"],hasValue:!1},{flags:["--forceSecurityRefactor"],hasValue:!1},{flags:["--securityProvider"],hasValue:!0,isArray:!0},{flags:["--securityProviderToken"],hasValue:!0},{flags:["--interactive"],hasValue:!1},{flags:["--hasWorkspaceSecurityChecks"],hasValue:!1},{flags:["--promptForReasons"],hasValue:!1}]});var vo=(e)=>at.find((t)=>t.flags.includes(e)),$r=(e)=>{return(e.flags.find((r)=>r.startsWith("--"))||e.flags[0]).replace(/^--?/,"").replace(/-([a-z])/g,(r,n)=>n.toUpperCase())},So=(e)=>{let t=e.indexOf("=");return t>-1?{flag:e.slice(0,t),value:e.slice(t+1)}:{flag:e}},ct=(e)=>e.startsWith("-"),Oo=(e,t)=>{let r=[],n=t+1;while(n<e.length&&!ct(e[n]))r.push(e[n]),n++;let i=r.length>0,s=n-t-1;return{value:i?r:void 0,consumed:s}},Po=(e,t)=>{let r=e[t+1];return r&&!ct(r)?{value:r,consumed:1}:{value:!0,consumed:0}},Ao=(e,t,r)=>r.isArray?Oo(e,t):Po(e,t),xo=(e)=>at.reduce((t,r)=>{let n=$r(r);return t[n]===void 0&&r.defaultValue!==void 0?Object.assign({},t,{[n]:r.defaultValue}):t},e),ko=(e,t,r)=>{let n=e[t];if(!ct(n))return{nextIndex:t+1,options:r.options,command:n};let{flag:s,value:o}=So(n),a=vo(s);if(!a)return{nextIndex:t+1,options:r.options,command:r.command};let l=$r(a);if(o!==void 0){let m=Object.assign({},r.options,{[l]:o});return{nextIndex:t+1,options:m,command:r.command}}if(!a.hasValue){let m=Object.assign({},r.options,{[l]:!0});return{nextIndex:t+1,options:m,command:r.command}}let{value:h,consumed:p}=Ao(e,t,a),g=Object.assign({},r.options,{[l]:h});return{nextIndex:t+p+1,options:g,command:r.command}},Fr=(e)=>{let t=e.slice(Vr),r=0,n={options:{},command:void 0};while(r<t.length){let s=ko(t,r,n);r=s.nextIndex,n={options:s.options,command:s.command}}let i=xo(n.options);return{command:n.command,options:i}},Nr=()=>{console.log(Tr)};var Er=f(()=>{Ir()});import*as jr from"readline";class Lr{rl;constructor(){this.rl=jr.createInterface({input:process.stdin,output:process.stdout})}close(){this.rl.close()}ensureCookedMode(){if(process.stdin.isTTY)process.stdin.setRawMode(!1)}async input(e,t){return new Promise((r)=>{let n=t?`${e} (${t}): `:`${e}: `;this.ensureCookedMode(),this.rl.question(n,(i)=>{r(i.trim()||t||"")})})}async confirm(e,t=!0){return new Promise((r)=>{let n=t?"Y/n":"y/N";this.ensureCookedMode(),this.rl.question(`${e} (${n}): `,(i)=>{let s=i.trim().toLowerCase();if(s==="")r(t);else r(s==="y"||s==="yes")})})}async list(e,t){return console.log(`
|
|
67
68
|
${e}`),t.forEach((r,n)=>{console.log(` ${n+1}. ${r.name}`)}),new Promise((r)=>{let n=()=>{this.ensureCookedMode(),this.rl.question(`
|
|
68
|
-
Enter your choice (number): `,(i)=>{let s=parseInt(i.trim(),10);if(isNaN(s)||s<1||s>t.length)console.log("⚠️ Invalid choice. Please enter a number between 1 and "+t.length),n();else r(t[s-1].value)})};n()})}async prompt(e){let{type:t="input",message:r}=e;switch(t){case"confirm":return this.confirm(r,e.default??!0);case"list":return this.list(r,e.choices);case"input":default:return this.input(r,e.default??"")}}async promptMany(e){return e.reduce(async(t,r,n)=>{let i=await t,s=`answer${n}`,o=r.type==="confirm",a=r.type==="list";if(o)i[s]=await this.prompt(r);else if(a)i[s]=await this.prompt(r);else i[s]=await this.prompt(r);return i},Promise.resolve({}))}}async function
|
|
69
|
+
Enter your choice (number): `,(i)=>{let s=parseInt(i.trim(),10);if(isNaN(s)||s<1||s>t.length)console.log("⚠️ Invalid choice. Please enter a number between 1 and "+t.length),n();else r(t[s-1].value)})};n()})}async prompt(e){let{type:t="input",message:r}=e;switch(t){case"confirm":return this.confirm(r,e.default??!0);case"list":return this.list(r,e.choices);case"input":default:return this.input(r,e.default??"")}}async promptMany(e){return e.reduce(async(t,r,n)=>{let i=await t,s=`answer${n}`,o=r.type==="confirm",a=r.type==="list";if(o)i[s]=await this.prompt(r);else if(a)i[s]=await this.prompt(r);else i[s]=await this.prompt(r);return i},Promise.resolve({}))}}async function Ur(e){let t=new Lr;try{return await e(t)}finally{t.close()}}var Dr=()=>{};var _r,Mr,Wr,ut,lt,Gr="packages/*/package.json",O,te,S;var Hr=f(()=>{_r=[{name:"In package.json (recommended for simple setups)",value:"package.json"},{name:"In a separate config file (recommended for complex setups)",value:"external"}],Mr=[{name:".pastoralistrc.json (JSON format)",value:".pastoralistrc.json"},{name:"pastoralist.config.js (JavaScript module)",value:"pastoralist.config.js"},{name:"pastoralist.config.ts (TypeScript module)",value:"pastoralist.config.ts"}],Wr=[{name:'Use "workspace" keyword (auto-detect from package.json)',value:"workspace"},{name:"Specify custom paths",value:"custom"}],ut=[{name:"OSV (Open Source Vulnerabilities - free, recommended)",value:"osv"},{name:"GitHub Advisory Database",value:"github"},{name:"npm audit",value:"npm"},{name:"Snyk (requires token)",value:"snyk"},{name:"Socket.dev (requires token)",value:"socket"}],lt=[{name:"Low (all vulnerabilities)",value:"low"},{name:"Medium (medium and above)",value:"medium"},{name:"High (high and critical only)",value:"high"},{name:"Critical (critical only)",value:"critical"}],O={welcome:"This wizard will help you set up your Pastoralist configuration.",skipInfo:"You can skip any step by selecting the skip option.",existingConfigWarning:"⚠️ Existing Pastoralist configuration detected. Do you want to overwrite it?",existingFileWarning:(e)=>`⚠️ ${e} already exists. Overwrite?`,configNotSaved:"✅ Configuration not saved. File preserved.",configSaved:(e)=>`✅ Configuration saved to ${e}`,initCancelled:"✅ Initialization cancelled. Your existing configuration is preserved.",initComplete:"initialization complete!",packageJsonNotFound:"❌ Error: package.json not found",noTokenProvided:()=>"⚠️ No token provided. You can add it later to the config or use --securityProviderToken flag.",tokenCreationInfo:(e,t)=>`\uD83D\uDCA1 To create a ${e} token, visit: ${t}`,tokenRequiredWarning:(e)=>`⚠️ ${e} requires a token to function. Security scanning will not work without it.`,workspacesDetected:(e)=>`Detected workspaces in package.json: ${e.join(", ")}`,noWorkspacesDetected:"No workspaces detected in package.json.",savingConfig:"\uD83D\uDCBE Saving configuration...",nextSteps:"\uD83D\uDCDA Next Steps:"},te={configLocation:"\uD83D\uDCCD Step 1: Configuration Location",workspace:"\uD83D\uDCE6 Step 2: Workspace Configuration",security:"\uD83D\uDD12 Step 3: Security Configuration"},S={configLocation:"Where would you like to store your Pastoralist configuration?",configFormat:"Choose a config file format:",setupWorkspaces:"Do you want to configure workspace dependencies?",workspaceType:"How would you like to configure workspace dependencies?",customWorkspacePaths:"Enter workspace paths (comma-separated glob patterns)",setupSecurity:"Do you want to enable security vulnerability scanning?",securityProvider:"Choose a security provider:",hasToken:(e)=>`Do you have a ${e} API token?`,enterToken:(e)=>`Enter your ${e} API token (will be stored in config)`,securityInteractive:"Enable interactive mode for security fixes? (allows you to review/approve each fix)",securityAutoFix:"Enable auto-fix mode? (automatically applies security overrides without prompting)",severityThreshold:"What severity level should trigger alerts?",hasWorkspaceSecurityChecks:"Scan workspace packages for vulnerabilities?"}});function Kr(e){return e.split(",").map((t)=>t.trim()).filter((t)=>t.length>0)}function Br(e){let t={};if(e.setupWorkspaces){if(e.workspaceType==="workspace")t.depPaths="workspace";if(e.workspaceType==="custom"&&e.customWorkspacePaths?.length)t.depPaths=e.customWorkspacePaths}if(e.setupSecurity){if(t.checkSecurity=!0,t.security={enabled:!0,provider:e.securityProvider,interactive:e.securityInteractive,autoFix:e.securityAutoFix,severityThreshold:e.severityThreshold,hasWorkspaceSecurityChecks:e.hasWorkspaceSecurityChecks},Boolean(e.securityProviderToken))t.security.securityProviderToken=e.securityProviderToken}return t}function qr(e,t){if(t.endsWith(".json"))return JSON.stringify(e,null,2)+`
|
|
69
70
|
`;if(t.endsWith(".js"))return`module.exports = ${JSON.stringify(e,null,2)};
|
|
70
71
|
`;return`import type { PastoralistConfig } from 'pastoralist';
|
|
71
72
|
|
|
72
73
|
const config: PastoralistConfig = ${JSON.stringify(e,null,2)};
|
|
73
74
|
|
|
74
75
|
export default config;
|
|
75
|
-
`}import{writeFileSync as
|
|
76
|
-
${
|
|
77
|
-
${O.workspacesDetected(r)}`,"promptForWorkspaceType"),await e.list(S.workspaceType,
|
|
78
|
-
${
|
|
79
|
-
${O.noWorkspacesDetected}`,"collectWorkspaceAnswers");if(t.workspaceType=await
|
|
76
|
+
`}import{writeFileSync as Yr,existsSync as Co}from"fs";import{resolve as wo}from"path";async function Jr(e,t,r){if(r.info(`
|
|
77
|
+
${te.configLocation}`,"collectConfigLocationAnswers"),t.configLocation=await e.list(S.configLocation,_r),t.configLocation==="external")t.configFormat=await e.list(S.configFormat,Mr)}async function Ro(e){let t=await e.input(S.customWorkspacePaths,Gr);return Kr(t)}async function To(e,t,r,n){if(!t)return"custom";return n.info(`
|
|
78
|
+
${O.workspacesDetected(r)}`,"promptForWorkspaceType"),await e.list(S.workspaceType,Wr)}async function zr(e,t,r,n){if(n.info(`
|
|
79
|
+
${te.workspace}`,"collectWorkspaceAnswers"),t.setupWorkspaces=await e.confirm(S.setupWorkspaces,!0),!t.setupWorkspaces)return;let i=Boolean(r?.workspaces&&r.workspaces.length>0);if(!i)n.info(`
|
|
80
|
+
${O.noWorkspacesDetected}`,"collectWorkspaceAnswers");if(t.workspaceType=await To(e,i,r?.workspaces||[],n),t.workspaceType==="custom")t.customWorkspacePaths=await Ro(e)}async function Xr(e,t,r){let n=Vo(t);if(!n.required&&!n.optional)return;if(n.createUrl)r.info(`
|
|
80
81
|
${O.tokenCreationInfo(t,n.createUrl)}`,"promptForSecurityToken");if(!await e.confirm(S.hasToken(t),!1)){if(n.required)r.info(`
|
|
81
82
|
${O.tokenRequiredWarning(t)}`,"promptForSecurityToken");return}let s=await e.input(S.enterToken(t),"");if(!s){r.info(`
|
|
82
|
-
${O.noTokenProvided()}`,"promptForSecurityToken");return}return s}function
|
|
83
|
-
${
|
|
84
|
-
`);n.info(O.configSaved(t),"saveToPackageJson")}async function
|
|
85
|
-
${O.configNotSaved}`,"saveToExternalFile");return}}let c=
|
|
83
|
+
${O.noTokenProvided()}`,"promptForSecurityToken");return}return s}function Vo(e){switch(e){case"github":return{required:!1,optional:!0,createUrl:"https://github.com/settings/tokens/new?description=Pastoralist%20Security&scopes=repo",scopes:["repo"]};case"snyk":return{required:!0,optional:!1,createUrl:"https://app.snyk.io/account"};case"socket":return{required:!0,optional:!1,createUrl:"https://socket.dev/dashboard/settings"};default:return{required:!1,optional:!1}}}async function Io(e,t,r){if(r.info(`
|
|
84
|
+
${te.security}`,"collectSecurityAnswers"),t.setupSecurity=await e.confirm(S.setupSecurity,!0),!t.setupSecurity)return;if(t.securityProvider=await e.list(S.securityProvider,ut),t.securityProviderToken=await Xr(e,t.securityProvider,r),t.securityInteractive=await e.confirm(S.securityInteractive,!0),!t.securityInteractive)t.securityAutoFix=await e.confirm(S.securityAutoFix,!1);if(t.severityThreshold=await e.list(S.severityThreshold,lt),t.setupWorkspaces)t.hasWorkspaceSecurityChecks=await e.confirm(S.hasWorkspaceSecurityChecks,!0)}async function $o(e,t,r,n,i=!1){if(!r){n.info(O.packageJsonNotFound,"saveToPackageJson");return}if(r.pastoralist=e,!i)Yr(t,JSON.stringify(r,null,2)+`
|
|
85
|
+
`);n.info(O.configSaved(t),"saveToPackageJson")}async function Fo(e,t,r,n,i,s=!1){let o=wo(r,t);if(Co(o)){if(!await n.confirm(O.existingFileWarning(t),!1)){i.info(`
|
|
86
|
+
${O.configNotSaved}`,"saveToExternalFile");return}}let c=qr(e,t);if(!s)Yr(o,c);i.info(O.configSaved(o),"saveToExternalFile")}function No(e,t){if(t.info(`
|
|
86
87
|
${O.nextSteps}
|
|
87
88
|
`,"displayNextSteps"),t.info(` 1. Run ${C("pastoralist")} to check and update your dependencies`,"displayNextSteps"),e)t.info(` 2. Run ${C("pastoralist --checkSecurity")} to scan for security vulnerabilities`,"displayNextSteps");t.info(" 3. Check the documentation for advanced configuration options","displayNextSteps"),t.info(`
|
|
88
89
|
\uD83D\uDC69\uD83C\uDFFD\uD83C\uDF3E ${C("Pastoralist")} ${O.initComplete}
|
|
89
|
-
`,"displayNextSteps")}async function
|
|
90
|
+
`,"displayNextSteps")}async function Eo(e,t,r){let n=await ke(t,!1),i=await R(r);if(!(n||i?.pastoralist))return!0;return await e.confirm(O.existingConfigWarning,!1)}async function dt(e={}){let t=y({file:"init/index.ts",isLogging:!0}),r=!!(e.checkSecurity||e.securityProvider),n=!!e.hasWorkspaceSecurityChecks,i=r||n;if(r)t.info(`
|
|
90
91
|
\uD83D\uDC69\uD83C\uDFFD\uD83C\uDF3E ${C("Pastoralist")} security configuration wizard
|
|
91
92
|
`,"initCommand");else if(n)t.info(`
|
|
92
93
|
\uD83D\uDC69\uD83C\uDFFD\uD83C\uDF3E ${C("Pastoralist")} workspace configuration wizard
|
|
@@ -94,11 +95,11 @@ ${O.nextSteps}
|
|
|
94
95
|
\uD83D\uDC69\uD83C\uDFFD\uD83C\uDF3E ${C("Pastoralist")} initialization wizard
|
|
95
96
|
`,"initCommand"),t.info(`${O.welcome}
|
|
96
97
|
`,"initCommand"),t.info(`${O.skipInfo}
|
|
97
|
-
`,"initCommand");let s=e.path||"package.json",o=e.root||process.cwd();await
|
|
98
|
-
${O.initCancelled}`,"initCommand");return}let l=await
|
|
98
|
+
`,"initCommand");let s=e.path||"package.json",o=e.root||process.cwd();await Ur(async(a)=>{if(!await Eo(a,o,s)){t.info(`
|
|
99
|
+
${O.initCancelled}`,"initCommand");return}let l=await R(s),u={configLocation:"package.json",setupWorkspaces:!1,setupSecurity:!1};if(r){if(u.setupSecurity=!0,e.securityProvider)u.securityProvider=e.securityProvider}if(n)u.setupWorkspaces=!0,u.hasWorkspaceSecurityChecks=!0;if(!i)await Jr(a,u,t),await zr(a,u,l,t),await Io(a,u,t);else{if(await Jr(a,u,t),n)await zr(a,u,l,t);if(r)await jo(a,u,t)}let d=Br(u);t.info(`
|
|
99
100
|
${O.savingConfig}
|
|
100
|
-
`,"initCommand");let h=u.configLocation==="package.json",p=u.configLocation==="external"&&u.configFormat;if(h)await
|
|
101
|
-
${
|
|
101
|
+
`,"initCommand");let h=u.configLocation==="package.json",p=u.configLocation==="external"&&u.configFormat;if(h)await $o(d,s,l,t,e.isTesting);if(p)await Fo(d,u.configFormat,o,a,t,e.isTesting);No(u.setupSecurity,t)})}async function jo(e,t,r){if(r.info(`
|
|
102
|
+
${te.security}`,"collectSecurityAnswersWithContext"),!t.securityProvider)t.securityProvider=await e.list(S.securityProvider,ut);if(t.securityProviderToken=await Xr(e,t.securityProvider,r),t.securityInteractive=await e.confirm(S.securityInteractive,!0),!t.securityInteractive)t.securityAutoFix=await e.confirm(S.securityAutoFix,!1);if(t.severityThreshold=await e.list(S.severityThreshold,lt),t.setupWorkspaces&&!t.hasWorkspaceSecurityChecks)t.hasWorkspaceSecurityChecks=await e.confirm(S.hasWorkspaceSecurityChecks,!0)}var Qr=f(()=>{P();Dr();ot();$();P();Hr()});var pn={};bt(pn,{runSecurityCheck:()=>nn,run:()=>Uo,outputResult:()=>re,handleTestMode:()=>Zr,handleSecurityResults:()=>sn,handleInitMode:()=>en,formatUpdateReport:()=>on,determineSecurityScanPaths:()=>an,createErrorResult:()=>cn,createEmptyResult:()=>pt,buildUpdateResult:()=>ln,buildSecurityResult:()=>un,buildSecurityOverrideDetail:()=>rn,buildMergedOptions:()=>tn,action:()=>dn});function an(e,t,r=Lo){let n=e?.pastoralist?.depPaths,i=Array.isArray(n),s=e?.workspaces||[],o=s.length>0,a=n==="workspace",c=t.hasWorkspaceSecurityChecks||!1,l=t.checkSecurity||e?.pastoralist?.checkSecurity||!1,u=i&&l,p=a&&o&&l||c&&o;if(u)return r.debug(`Using depPaths configuration for security checks: ${n.join(", ")}`,"determineSecurityScanPaths"),n;if(p)return r.debug(`Using workspace configuration for security checks: ${s.join(", ")}`,"determineSecurityScanPaths"),s.map((g)=>`${g}/package.json`);return[]}async function dn(e={},t={createLogger:y,handleTestMode:Zr,handleInitMode:en,resolveJSON:R,buildMergedOptions:tn,runSecurityCheck:nn,handleSecurityResults:sn,createSpinner:se,green:C,update:Xe,processExit:(r)=>process.exit(r)}){let r=x||e.debug,n=e.outputFormat==="json",i=t.createLogger({file:"program.ts",isLogging:r}),{isTestingCLI:s=!1,init:o=!1,...a}=e,c=pt();if(t.handleTestMode(s,i,e))return re(c,n),c;if(await t.handleInitMode(o,e,a))return re(c,n),c;try{let l=e.path||"package.json",u=e.root&&!l.startsWith("/")?`${e.root}/${l}`:l,d=await t.resolveJSON(u),h=d?.pastoralist?.security||{},p=Array.isArray(h.provider)?h.provider[0]:h.provider,g=t.buildMergedOptions(e,a,h,p);if(g.config=d,g.path=u,e.root)g.root=e.root;let m={hasSecurityIssues:!1,securityAlertCount:0,securityAlerts:[]};if(g.checkSecurity){let{spinner:gt,securityChecker:hn,alerts:ht,securityOverrides:fn,updates:yn}=await t.runSecurityCheck(d,g,Boolean(r),i);if(m=un(ht),!n)t.handleSecurityResults(ht,fn,hn,gt,g,yn);else gt.stop()}let b=n?{start:()=>({succeed:()=>{},stop:()=>{}}),succeed:()=>{},stop:()=>{}}:t.createSpinner(`\uD83D\uDC69\uD83C\uDFFD\uD83C\uDF3E ${t.green("pastoralist")} checking herd...`).start();if(!n)b.start?.();let v=await t.update(g),k=ln(v,d,e.dryRun||!1);if(!n)b.succeed(`\uD83D\uDC69\uD83C\uDFFD\uD83C\uDF3E ${t.green("pastoralist")} the herd is safe!`);let W={...c,...m,...k};return re(W,n),W}catch(l){let u=cn(l);if(n)re(u,n);else i.error("action:fn","action",{error:l});return t.processExit(1),u}}var Lo,Zr=(e,t,r)=>{if(e)return t.debug("action:options:","action",{options:r}),!0;return!1},en=async(e,t,r,n={initCommand:dt})=>{if(e)return await n.initCommand({path:t.path,root:t.root,checkSecurity:r.checkSecurity,securityProvider:r.securityProvider,hasWorkspaceSecurityChecks:r.hasWorkspaceSecurityChecks}),!0;return!1},tn=(e,t,r,n)=>{return{...t,checkSecurity:e.checkSecurity??r.enabled,forceSecurityRefactor:e.forceSecurityRefactor??r.autoFix,securityProvider:e.securityProvider??n??"osv",securityProviderToken:e.securityProviderToken??r.securityProviderToken,interactive:e.interactive??r.interactive,hasWorkspaceSecurityChecks:e.hasWorkspaceSecurityChecks??r.hasWorkspaceSecurityChecks}},rn=(e)=>{let t=Boolean(e.cve),r=Boolean(e.severity),n=Boolean(e.description),i=Boolean(e.url);return{packageName:e.packageName,reason:e.reason,...t&&{cve:e.cve},...r&&{severity:e.severity},...n&&{description:e.description},...i&&{url:e.url}}},nn=async(e,t,r,n,i={createSpinner:se,SecurityChecker:Pe,determineSecurityScanPaths:an,green:C})=>{let s=i.createSpinner(`\uD83D\uDD12 ${i.green("pastoralist")} checking for security vulnerabilities...`).start();try{let o=new i.SecurityChecker({provider:t.securityProvider,forceRefactor:t.forceSecurityRefactor,interactive:t.interactive,token:t.securityProviderToken,debug:r,isIRLFix:t.isIRLFix,isIRLCatch:t.isIRLCatch}),a=i.determineSecurityScanPaths(e,t,n),{alerts:c,overrides:l,updates:u}=await o.checkSecurity(e,{...t,depPaths:a,root:t.root||"./"});return{spinner:s,securityChecker:o,alerts:c,securityOverrides:l,updates:u}}catch(o){throw s.fail(`\uD83D\uDD12 ${i.green("pastoralist")} security check failed: ${o instanceof Error?o.message:String(o)}`),o}},sn=(e,t,r,n,i,s=[])=>{let o=e.length>0,a=s.length>0,c=i.forceSecurityRefactor||i.interactive,l=o&&c,u=a&&c;if(o){let p=r.formatSecurityReport(e,t);n.info(p)}if(a){let p=on(s);n.info(p)}let d=[...t];if(u){let p=s.map((g)=>({packageName:g.packageName,fromVersion:g.currentOverride,toVersion:g.newerVersion,reason:g.reason,severity:"medium"}));d.push(...p)}if(l||u){let p=r.generatePackageOverrides(d);i.securityOverrides=p;let g=d.filter((b)=>{let v=p[b.packageName];return typeof v==="string"&&v===b.toVersion});if(i.securityOverrideDetails=g.map(rn),(l||u)&&g.length>0)r.applyAutoFix(g,i.path)}if(!o&&!a)n.succeed(`\uD83D\uDD12 ${C("pastoralist")} no security vulnerabilities found!`)},on=(e)=>{let t=`
|
|
102
103
|
Security Override Updates
|
|
103
104
|
`+"=".repeat(50)+`
|
|
104
105
|
|
|
@@ -109,4 +110,4 @@ Security Override Updates
|
|
|
109
110
|
Newer patch: ${i.newerVersion}
|
|
110
111
|
${i.reason}
|
|
111
112
|
|
|
112
|
-
`).join("");return t+r+n},
|
|
113
|
+
`).join("");return t+r+n},pt=()=>({success:!0,hasSecurityIssues:!1,hasUnusedOverrides:!1,updated:!1,securityAlertCount:0,unusedOverrideCount:0,overrideCount:0,errors:[],securityAlerts:[],unusedOverrides:[],appliedOverrides:{}}),cn=(e)=>{let t=e instanceof Error?e.message:String(e);return{...pt(),success:!1,errors:[t]}},un=(e)=>({hasSecurityIssues:e.length>0,securityAlertCount:e.length,securityAlerts:e.map((t)=>({packageName:t.packageName,severity:t.severity||"unknown",cve:t.cve,description:t.description}))}),ln=(e,t,r)=>{let n=e.finalOverrides||{},i=e.finalAppendix||{},s=Object.keys(n),o=Object.fromEntries(s.filter((u)=>typeof n[u]==="string").map((u)=>[u,n[u]])),a=t?.pastoralist?.appendix||{},c=t?.overrides||t?.resolutions||t?.pnpm?.overrides||{},l=JSON.stringify(i)!==JSON.stringify(a)||JSON.stringify(n)!==JSON.stringify(c);return{overrideCount:s.length,appliedOverrides:o,updated:l&&!r}},re=(e,t)=>{if(t)console.log(JSON.stringify(e))},Uo=async(e=process.argv)=>{let t=Fr(e),r=t.options;if(r.help||e.includes("-h")||e.includes("--help")){Nr();return}if(t.command==="init"){await dt(r);return}await dn(r)};var gn=f(()=>{Er();P();Qe();P();$();T();rt();Qr();Lo=y({file:"program.ts",isLogging:!1})});Qe();$();De();he();Y();He();rt();ot();P();import{realpathSync as Do}from"fs";import{fileURLToPath as _o}from"url";var hu=(e)=>{if(!e)return[];let t=Object.keys(e);if(t.length===0)return[];return t.filter((r)=>{let n=e[r]?.dependents;return!n||Object.keys(n).length===0}).map((r)=>r.split("@")[0])},Mo=_o(import.meta.url),Wo=process.argv[1]?Do(process.argv[1]):"",Go=Mo===Wo||process.argv[1]?.endsWith("/pastoralist")||process.argv[1]?.endsWith("\\pastoralist");if(Go){let{run:e}=await Promise.resolve().then(() => (gn(),pn));await e(process.argv)}export{Ne as updatePackageJSON,Qt as updateOverrides,_ as updateAppendix,Xe as update,pe as resolveOverrides,R as resolveJSON,ar as processPackageJSON,Ue as mergeOverridePaths,Rr as mergeConfigs,y as logger,B as logMethod,ke as loadExternalConfig,bo as loadConfig,V as jsonCache,F as getOverridesByType,Kt as getOverrideFieldForPackageManager,Ht as getExistingOverrideField,_n as getCacheStats,Mn as forceClearCache,We as findUnusedPatches,Xt as findUnusedOverrides,hu as findRemovableAppendixItems,je as findPackageJsonFiles,Me as detectPatches,Gt as detectPackageManager,Ke as defineOverride,Ye as constructAppendix,Ee as clearDependencyTreeCache,uo as clearConfigCache,Oi as cleanupUnusedOverrides,Le as checkMonorepoOverrides,Ge as attachPatchesToAppendix,Bt as applyOverridesToConfig,Pe as SecurityChecker};
|
package/dist/types.d.ts
CHANGED
|
@@ -86,6 +86,7 @@ export interface Options {
|
|
|
86
86
|
appendix?: Appendix;
|
|
87
87
|
debug?: boolean;
|
|
88
88
|
dryRun?: boolean;
|
|
89
|
+
outputFormat?: "text" | "json";
|
|
89
90
|
exec?: Exec;
|
|
90
91
|
help?: boolean;
|
|
91
92
|
isTesting?: boolean;
|
|
@@ -117,6 +118,7 @@ export interface UpdatePackageJSONOptions {
|
|
|
117
118
|
appendix?: Appendix;
|
|
118
119
|
debug?: boolean;
|
|
119
120
|
dryRun?: boolean;
|
|
121
|
+
silent?: boolean;
|
|
120
122
|
path: string;
|
|
121
123
|
config: PastoralistJSON;
|
|
122
124
|
overrides?: OverridesType;
|
|
@@ -156,5 +158,23 @@ type ConsoleMethodFunc = (msg: string, caller?: string, ...args: unknown[]) => v
|
|
|
156
158
|
export type ConsoleObject = {
|
|
157
159
|
[K in ConsoleMethod]: ConsoleMethodFunc;
|
|
158
160
|
};
|
|
161
|
+
export interface PastoralistResult {
|
|
162
|
+
success: boolean;
|
|
163
|
+
hasSecurityIssues: boolean;
|
|
164
|
+
hasUnusedOverrides: boolean;
|
|
165
|
+
updated: boolean;
|
|
166
|
+
securityAlertCount: number;
|
|
167
|
+
unusedOverrideCount: number;
|
|
168
|
+
overrideCount: number;
|
|
169
|
+
errors: string[];
|
|
170
|
+
securityAlerts?: Array<{
|
|
171
|
+
packageName: string;
|
|
172
|
+
severity: string;
|
|
173
|
+
cve?: string;
|
|
174
|
+
description?: string;
|
|
175
|
+
}>;
|
|
176
|
+
unusedOverrides?: string[];
|
|
177
|
+
appliedOverrides?: Record<string, string>;
|
|
178
|
+
}
|
|
159
179
|
export * from "./core/security/types";
|
|
160
180
|
export * from "./core/update/types";
|
package/dist/utils/spinner.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export declare const succeed: (state: SpinnerState, text?: string) => Spinner;
|
|
|
14
14
|
export declare const fail: (state: SpinnerState, text?: string) => Spinner;
|
|
15
15
|
export declare const info: (state: SpinnerState, text?: string) => Spinner;
|
|
16
16
|
export declare const warn: (state: SpinnerState, text?: string) => Spinner;
|
|
17
|
+
export declare const update: (state: SpinnerState, text: string) => Spinner;
|
|
17
18
|
export declare const createSpinnerMethods: (state: SpinnerState) => Spinner;
|
|
18
19
|
export declare const createSpinner: (text: string) => Spinner;
|
|
19
20
|
export default createSpinner;
|
package/dist/utils/types.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export type Spinner = {
|
|
|
11
11
|
fail: (text?: string) => Spinner;
|
|
12
12
|
info: (text?: string) => Spinner;
|
|
13
13
|
warn: (text?: string) => Spinner;
|
|
14
|
+
update: (text: string) => Spinner;
|
|
14
15
|
};
|
|
15
16
|
export type RGB = {
|
|
16
17
|
r: number;
|
|
@@ -41,6 +42,7 @@ export interface RetryOptions {
|
|
|
41
42
|
minTimeout?: number;
|
|
42
43
|
maxTimeout?: number;
|
|
43
44
|
onFailedAttempt?: (error: RetryError) => void | Promise<void>;
|
|
45
|
+
onRetry?: (attemptNumber: number, retriesLeft: number) => void;
|
|
44
46
|
}
|
|
45
47
|
export interface RetryError extends Error {
|
|
46
48
|
attemptNumber: number;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pastoralist",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.3",
|
|
4
4
|
"description": "A tool to watch over node module resolutions and overrides 🐑 👩🏽🌾",
|
|
5
5
|
"main": "dist/index.cjs",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"pnpm"
|
|
57
57
|
],
|
|
58
58
|
"author": "Jeff Wainwright <https:jeffry.in> (yowainwright@gmail.com)",
|
|
59
|
-
"license": "
|
|
59
|
+
"license": "Elastic-2.0",
|
|
60
60
|
"bugs": {
|
|
61
61
|
"url": "https://github.com/yowainwright/pastoralist/issues"
|
|
62
62
|
},
|
|
@@ -69,9 +69,9 @@
|
|
|
69
69
|
"@types/bun": "latest",
|
|
70
70
|
"codependence": "^0.3.1",
|
|
71
71
|
"oxlint": "^1.25.0",
|
|
72
|
-
"prettier": "3.
|
|
72
|
+
"prettier": "3.7.4",
|
|
73
73
|
"release-it": "19.0.6",
|
|
74
|
-
"turbo": "2.6.
|
|
74
|
+
"turbo": "2.6.3",
|
|
75
75
|
"typescript": "5.9.3"
|
|
76
76
|
},
|
|
77
77
|
"release-it": {
|