depcurfew 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +140 -31
- package/dist/cli.js +24 -4
- package/dist/index.d.ts +244 -43
- package/dist/index.js +1 -1
- package/dist/{run-CvdVkFPn.js → run-BBZUJJq-.js} +5555 -623
- package/package.json +4 -1
- package/schema.json +11 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,35 +1,3 @@
|
|
|
1
|
-
type FetchLike = (url: string, init: {
|
|
2
|
-
headers: Record<string, string>;
|
|
3
|
-
signal: AbortSignal;
|
|
4
|
-
redirect?: 'manual';
|
|
5
|
-
}) => Promise<Response>;
|
|
6
|
-
declare const EXIT_OK = 0;
|
|
7
|
-
declare const EXIT_FAILURE = 1;
|
|
8
|
-
declare const EXIT_USAGE = 2;
|
|
9
|
-
interface CliIo {
|
|
10
|
-
stdout(text: string): void;
|
|
11
|
-
stderr(text: string): void;
|
|
12
|
-
/** Whether each stream may be colored (see color.ts); absent means plain text. */
|
|
13
|
-
colors?: {
|
|
14
|
-
stdout: boolean;
|
|
15
|
-
stderr: boolean;
|
|
16
|
-
};
|
|
17
|
-
/** Whether each stream is a terminal; absent means it is not. */
|
|
18
|
-
terminal?: {
|
|
19
|
-
stdout: boolean;
|
|
20
|
-
stderr: boolean;
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
interface CheckDependencies {
|
|
24
|
-
fetch: FetchLike;
|
|
25
|
-
now: () => Date;
|
|
26
|
-
/** The whole of stdin, for hook mode. */
|
|
27
|
-
stdin: () => Promise<string>;
|
|
28
|
-
/** The user's home directory, with the user's .npmrc. */
|
|
29
|
-
home?: () => string;
|
|
30
|
-
}
|
|
31
|
-
declare function run(argv: readonly string[], output: CliIo, dependencies?: CheckDependencies): Promise<number>;
|
|
32
|
-
declare function getVersion(): string;
|
|
33
1
|
type ToolId = 'npm' | 'pnpm' | 'yarn' | 'bun' | 'deno' | 'uv' | 'pip' | 'poetry' | 'pdm' | 'pipenv' | 'renovate' | 'dependabot';
|
|
34
2
|
type ToolKind = 'package-manager' | 'update-bot';
|
|
35
3
|
/** The registry a package manager installs from; package names in the policy are compared per ecosystem. */
|
|
@@ -129,6 +97,103 @@ interface ProjectKnowledge {
|
|
|
129
97
|
/** Key of the package list when the workspace declaration is an object instead of a list; `null` if only lists are accepted. */
|
|
130
98
|
workspacesObjectKey: Fact<string | null>;
|
|
131
99
|
}
|
|
100
|
+
/** A platform family for user-level paths. */
|
|
101
|
+
type UserPlatform = 'linux' | 'darwin' | 'win32';
|
|
102
|
+
/** A base directory for a user-level file. */
|
|
103
|
+
interface UserDirectory {
|
|
104
|
+
/**
|
|
105
|
+
* Where it starts: an environment variable (used only when it is set and not empty, and with `absolute` only when
|
|
106
|
+
* it is an absolute path), or the home directory (HOME on Linux and macOS, USERPROFILE on Windows). With
|
|
107
|
+
* `relativeToCwd` the tool takes a relative value as it is, so it reads the file relative to the directory each
|
|
108
|
+
* command runs in; without it and without `absolute`, what the tool does with a relative value is not known.
|
|
109
|
+
*/
|
|
110
|
+
from: {
|
|
111
|
+
env: string;
|
|
112
|
+
absolute?: boolean;
|
|
113
|
+
relativeToCwd?: boolean;
|
|
114
|
+
} | 'home';
|
|
115
|
+
/** Path below it, with / separators; empty for the directory itself. */
|
|
116
|
+
path: string;
|
|
117
|
+
/** Use this directory only when it already exists (pip on macOS). */
|
|
118
|
+
ifExists?: boolean;
|
|
119
|
+
/** Skip this directory while this environment variable is set and not empty (pip 26.2+ on macOS and XDG_DATA_HOME). */
|
|
120
|
+
unlessEnv?: string;
|
|
121
|
+
}
|
|
122
|
+
/** Where the user file is on some platforms: the first directory that applies is used. */
|
|
123
|
+
interface UserLocation {
|
|
124
|
+
platforms: readonly UserPlatform[];
|
|
125
|
+
directories: readonly UserDirectory[];
|
|
126
|
+
file: string;
|
|
127
|
+
}
|
|
128
|
+
/** The user-level configuration file of a range of versions. */
|
|
129
|
+
interface UserFile {
|
|
130
|
+
format: 'ini' | 'yaml' | 'toml';
|
|
131
|
+
locations: readonly UserLocation[];
|
|
132
|
+
/** INI only: the [sections] whose keys the tool reads, '' for the keys above the first header; absent: every key. */
|
|
133
|
+
sections?: readonly string[];
|
|
134
|
+
/** Other user-level files this version reads the same settings from, whose keys win over this file's. */
|
|
135
|
+
overriddenBy?: readonly UserFile[];
|
|
136
|
+
/** INI only: the tool reads a key with underscores as the same key with dashes (pip: only_binary is only-binary). */
|
|
137
|
+
underscoresAsDashes?: boolean;
|
|
138
|
+
/** YAML only: the tool's loader applies merge keys (<<: *defaults), so merged keys count as keys of the map. */
|
|
139
|
+
mergeKeys?: boolean;
|
|
140
|
+
}
|
|
141
|
+
/** What depcurfew writes with a user-level setting. */
|
|
142
|
+
type UserSettingPurpose = 'cooldown' | 'cooldownExclude' | 'cooldownStrict' | 'scriptsAllow' | 'scriptsStrict' | 'buildsDeny' | 'buildsAllow' | 'sourceGit' | 'sourceRemote' | 'sourceFile' | 'sourceDirectory' | 'sourcesExotic';
|
|
143
|
+
/** A setting the tool reads from its user file: the key there and the versions that read it from that file. */
|
|
144
|
+
interface UserSetting {
|
|
145
|
+
purpose: UserSettingPurpose;
|
|
146
|
+
key: string;
|
|
147
|
+
since: string;
|
|
148
|
+
/** First version that no longer reads it from the user file. */
|
|
149
|
+
until?: string;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* The values of a switch that turns a protection off, given by the values the tool reads as off: every other value
|
|
153
|
+
* turns it on (fail closed), so a string "false" or "yes" that the tool takes for true is not missed. In INI files and
|
|
154
|
+
* environment variables values are compared as text after trimming, elsewhere with their type (false, 0, null, "").
|
|
155
|
+
*/
|
|
156
|
+
interface UnlessOff<T> {
|
|
157
|
+
except: readonly T[];
|
|
158
|
+
}
|
|
159
|
+
/** A value in the user file that weakens every project that does not set the key itself (doctor --user). */
|
|
160
|
+
interface UserWeakening {
|
|
161
|
+
key: string;
|
|
162
|
+
/** 'any' for every value, the values that weaken, or every value except those the tool reads as off. */
|
|
163
|
+
values: 'any' | readonly (string | number | boolean)[] | UnlessOff<string | number | boolean | null>;
|
|
164
|
+
/** What it does, for the message. */
|
|
165
|
+
effect: string;
|
|
166
|
+
}
|
|
167
|
+
/** An environment variable that bypasses or overrides the user file or the policy (doctor --user). */
|
|
168
|
+
interface UserVariable {
|
|
169
|
+
/** The variable name; matched without regard to case when `anyCase`. */
|
|
170
|
+
name: string;
|
|
171
|
+
anyCase?: boolean;
|
|
172
|
+
/** 'any' when every value matters, the values that weaken, or every value except those the tool reads as off. */
|
|
173
|
+
values: 'any' | readonly string[] | UnlessOff<string>;
|
|
174
|
+
effect: string;
|
|
175
|
+
/** First version that reads the variable; every version when absent. */
|
|
176
|
+
since?: string;
|
|
177
|
+
/** First version that no longer reads it. */
|
|
178
|
+
until?: string;
|
|
179
|
+
/** The file the tool reads when the variable is unset, from the home directory (~/.npmrc): naming it changes nothing. */
|
|
180
|
+
defaultPath?: string;
|
|
181
|
+
}
|
|
182
|
+
/** The tool's user-level configuration, for `depcurfew apply --user` and `doctor --user`. */
|
|
183
|
+
interface UserConfigKnowledge {
|
|
184
|
+
/** The user file per version, oldest first; null for versions without a user file. */
|
|
185
|
+
files: Fact<Versioned<UserFile | null>>;
|
|
186
|
+
/** Settings depcurfew can write there. */
|
|
187
|
+
settings: Fact<readonly UserSetting[]>;
|
|
188
|
+
/** What a version does with a key it does not know in the user file: ignore it, warn, or fail. */
|
|
189
|
+
unknownKeys: Fact<'ignore' | 'warn' | 'fail'>;
|
|
190
|
+
/** Whether a value the installed version cannot parse makes every command fail; depcurfew then needs the exact version. */
|
|
191
|
+
invalidValueFails: Fact<boolean>;
|
|
192
|
+
/** Values in the user file that weaken projects. */
|
|
193
|
+
weakening: Fact<readonly UserWeakening[]>;
|
|
194
|
+
/** Environment variables that move or skip the user file or override settings. */
|
|
195
|
+
variables: Fact<readonly UserVariable[]>;
|
|
196
|
+
}
|
|
132
197
|
interface ToolKnowledge {
|
|
133
198
|
id: ToolId;
|
|
134
199
|
name: string;
|
|
@@ -141,6 +206,8 @@ interface ToolKnowledge {
|
|
|
141
206
|
sources?: SourcesKnowledge;
|
|
142
207
|
/** Package managers only: how to recognize the tool in a repository. */
|
|
143
208
|
project?: ProjectKnowledge;
|
|
209
|
+
/** Package managers only: the user-level configuration (`--user`). */
|
|
210
|
+
user?: UserConfigKnowledge;
|
|
144
211
|
/** Further sourced facts that matter for generators and `doctor`, keyed by a short name. */
|
|
145
212
|
extra?: Readonly<Record<string, Fact<unknown>>>;
|
|
146
213
|
}
|
|
@@ -339,6 +406,25 @@ interface AnnotationLimitsKnowledge {
|
|
|
339
406
|
perJob: number;
|
|
340
407
|
}
|
|
341
408
|
/** The Markdown job summary of a step: the environment variable naming its file and its size limit. */
|
|
409
|
+
/** Creating a check run with the workflow token, so that the result shows in the pull request's Checks tab. */
|
|
410
|
+
interface CheckRunsKnowledge {
|
|
411
|
+
/** POST endpoint, with {repository} as owner/name. */
|
|
412
|
+
endpoint: string;
|
|
413
|
+
apiVersion: string;
|
|
414
|
+
/** The workflow permission the token needs. */
|
|
415
|
+
permission: Record<string, string>;
|
|
416
|
+
/** Limit of output.summary, in characters. */
|
|
417
|
+
summaryMaxLength: number;
|
|
418
|
+
/** Variables the runner sets: API URL, owner/name, commit and the event payload file. */
|
|
419
|
+
variables: {
|
|
420
|
+
apiUrl: string;
|
|
421
|
+
repository: string;
|
|
422
|
+
sha: string;
|
|
423
|
+
eventPath: string;
|
|
424
|
+
};
|
|
425
|
+
/** Path in the event payload of the commit a pull request check belongs to (GITHUB_SHA is the merge commit there). */
|
|
426
|
+
pullRequestHeadSha: readonly string[];
|
|
427
|
+
}
|
|
342
428
|
interface StepSummaryKnowledge {
|
|
343
429
|
variable: string;
|
|
344
430
|
maxBytes: number;
|
|
@@ -406,6 +492,7 @@ interface EnvironmentKnowledge {
|
|
|
406
492
|
annotations: Fact<AnnotationsKnowledge>;
|
|
407
493
|
annotationLimits: Fact<AnnotationLimitsKnowledge>;
|
|
408
494
|
stepSummary: Fact<StepSummaryKnowledge>;
|
|
495
|
+
checkRuns: Fact<CheckRunsKnowledge>;
|
|
409
496
|
};
|
|
410
497
|
npmRegistry: {
|
|
411
498
|
api: Fact<NpmRegistryKnowledge>;
|
|
@@ -522,6 +609,50 @@ interface Detection {
|
|
|
522
609
|
workflows: string[];
|
|
523
610
|
warnings: DetectionWarning[];
|
|
524
611
|
}
|
|
612
|
+
interface UserEnvironment {
|
|
613
|
+
platform: NodeJS.Platform;
|
|
614
|
+
/** HOME on Linux and macOS, USERPROFILE on Windows: what os.homedir() returns. */
|
|
615
|
+
home: string;
|
|
616
|
+
env: Readonly<Record<string, string | undefined>>;
|
|
617
|
+
/** The current directory, against which a tool resolves a relative XDG_CONFIG_HOME (relativeToCwd); process.cwd() by default. */
|
|
618
|
+
cwd?: string;
|
|
619
|
+
/** Whether a directory exists; replaceable in tests. */
|
|
620
|
+
isDirectory?: (path: string) => boolean;
|
|
621
|
+
}
|
|
622
|
+
type FetchLike = (url: string, init: {
|
|
623
|
+
headers: Record<string, string>;
|
|
624
|
+
signal: AbortSignal;
|
|
625
|
+
redirect?: 'manual';
|
|
626
|
+
}) => Promise<Response>;
|
|
627
|
+
declare const EXIT_OK = 0;
|
|
628
|
+
declare const EXIT_FAILURE = 1;
|
|
629
|
+
declare const EXIT_USAGE = 2;
|
|
630
|
+
interface CliIo {
|
|
631
|
+
stdout(text: string): void;
|
|
632
|
+
stderr(text: string): void;
|
|
633
|
+
/** Whether each stream may be colored (see color.ts); absent means plain text. */
|
|
634
|
+
colors?: {
|
|
635
|
+
stdout: boolean;
|
|
636
|
+
stderr: boolean;
|
|
637
|
+
};
|
|
638
|
+
/** Whether each stream is a terminal; absent means it is not. */
|
|
639
|
+
terminal?: {
|
|
640
|
+
stdout: boolean;
|
|
641
|
+
stderr: boolean;
|
|
642
|
+
};
|
|
643
|
+
}
|
|
644
|
+
interface CheckDependencies {
|
|
645
|
+
fetch: FetchLike;
|
|
646
|
+
now: () => Date;
|
|
647
|
+
/** The whole of stdin, for hook mode. */
|
|
648
|
+
stdin: () => Promise<string>;
|
|
649
|
+
/** The user's home directory, with the user's .npmrc. */
|
|
650
|
+
home?: () => string;
|
|
651
|
+
/** --user: platform, home directory and environment variables (tests replace them). */
|
|
652
|
+
userEnvironment?: () => UserEnvironment;
|
|
653
|
+
}
|
|
654
|
+
declare function run(argv: readonly string[], output: CliIo, dependencies?: CheckDependencies): Promise<number>;
|
|
655
|
+
declare function getVersion(): string;
|
|
525
656
|
interface Duration {
|
|
526
657
|
/** The duration as written in the policy. */
|
|
527
658
|
text: string;
|
|
@@ -592,6 +723,7 @@ declare const policyShape: Shape<{
|
|
|
592
723
|
installScripts?: {
|
|
593
724
|
default: "allow" | "deny";
|
|
594
725
|
allow?: readonly string[];
|
|
726
|
+
deny?: readonly string[];
|
|
595
727
|
};
|
|
596
728
|
sources?: {
|
|
597
729
|
git?: "allow" | "deny";
|
|
@@ -612,6 +744,7 @@ declare const policyShape: Shape<{
|
|
|
612
744
|
installScripts?: {
|
|
613
745
|
default: "allow" | "deny";
|
|
614
746
|
allow: readonly string[];
|
|
747
|
+
deny: readonly string[];
|
|
615
748
|
};
|
|
616
749
|
sources?: {
|
|
617
750
|
git?: "allow" | "deny";
|
|
@@ -626,24 +759,35 @@ type Policy = Input<typeof policyShape>;
|
|
|
626
759
|
type ResolvedPolicy = Output<typeof policyShape>;
|
|
627
760
|
declare const APPLY_WARNINGS: {
|
|
628
761
|
readonly 'nothing-to-configure': "depcurfew found no supported package manager or bot, so nothing is configured.";
|
|
762
|
+
readonly 'environment-overrides': "apply --user: an environment variable makes a tool read another user file or none, or overrides a value apply writes there.";
|
|
763
|
+
readonly 'depcurfew-outdated': "The project installs a newer depcurfew than the one running, which may not know settings that version writes.";
|
|
629
764
|
readonly 'file-unreadable': "A file that shows which tools a project uses cannot be read or parsed (too large, a symlink out of the repository, no read permission, invalid), so depcurfew may configure fewer tools than the project uses.";
|
|
630
|
-
readonly 'tool-not-supported': "A detected tool is not supported (Yarn Classic), so nothing is written for it.";
|
|
765
|
+
readonly 'tool-not-supported': "A detected or installed tool is not supported (Yarn Classic), so nothing is written for it.";
|
|
631
766
|
readonly 'tool-only-in-ci': "A tool appears only in a CI setup step, with no manifest, lockfile or configuration in the repository, so targets \"auto\" does not configure it.";
|
|
632
767
|
readonly 'version-not-pinned': "No exact version of a package manager is pinned, so depcurfew configures for the latest version it knows.";
|
|
633
|
-
readonly 'version-too-old': "The pinned version of a tool lacks a setting the policy needs, so that setting is not written.";
|
|
768
|
+
readonly 'version-too-old': "The pinned version of a tool (with apply --user, the installed one) lacks a setting the policy needs, so that setting is not written.";
|
|
769
|
+
readonly 'version-unknown': "apply --user: the installed version of a tool cannot be read from its files, and a value it does not understand would stop every command, so nothing is written for it.";
|
|
770
|
+
readonly 'no-user-config': "apply --user: the tool has no user-level configuration file, so nothing is written for it.";
|
|
771
|
+
readonly 'user-setting-project-only': "apply --user: the tool reads a part of the policy only from project files, so it is not written into the user file.";
|
|
772
|
+
readonly 'user-directory-relative': "apply --user: the environment variable that names the directory of the user file (XDG_CONFIG_HOME, APPDATA) is a relative path, so the tool looks in another place from each directory, or where it looks then is not known; nothing is written for it.";
|
|
773
|
+
readonly 'user-setting-overridden': "apply --user: a file the tool reads ahead of its user file (~/.npmrc for pnpm 10) sets a key apply writes there to another value, so the value written has no effect.";
|
|
774
|
+
readonly 'version-not-used': "apply --user: --for gives the version of a tool that apply --user does not configure (not in PATH with targets \"auto\", or not listed under targets).";
|
|
634
775
|
readonly 'cooldown-not-written': "The release-age delay cannot be written for a tool.";
|
|
635
776
|
readonly 'cooldown-shortened': "A release-age delay set outside depcurfew's markers (in JSON files also one an earlier apply wrote) is longer than the policy, and apply replaces it with the shorter one.";
|
|
636
777
|
readonly 'cooldown-environment-only': "pip reads no project configuration, so the release-age delay has to be set in the environment where pip runs.";
|
|
637
778
|
readonly 'exclude-pattern-unsupported': "A cooldown exception uses a wildcard the tool does not support, so it is not written.";
|
|
638
779
|
readonly 'exclude-unsupported': "The tool has no setting for cooldown exceptions, so the release-age delay applies to every package.";
|
|
639
780
|
readonly 'allow-pattern-unsupported': "An installScripts.allow entry is a pattern, but the tool takes package names only, so it is not written.";
|
|
781
|
+
readonly 'deny-pattern-unsupported': "An installScripts.deny entry is a pattern, but the tool records denials by package name only, so it is not written.";
|
|
640
782
|
readonly 'allow-all-unsupported': "The tool has no setting that allows every install script, so installScripts \"allow\" is not written.";
|
|
641
|
-
readonly 'allow-all-replaced': "A setting that allowed every install script was
|
|
642
|
-
readonly 'allow-list-entry-outside-policy': "An install-script allow-list in the repository lets a package run scripts the policy does not allow; apply does not remove it.";
|
|
783
|
+
readonly 'allow-all-replaced': "A setting that allowed every install script (with any value the tool reads as true, also one that a YAML merge key brings in, or pnpm 10's dangerously-allow-all-builds in .npmrc) was set to false, because the policy denies install scripts.";
|
|
784
|
+
readonly 'allow-list-entry-outside-policy': "An install-script allow-list in the repository (with apply --user, in a user file) lets a package run scripts the policy does not allow; apply does not remove it.";
|
|
785
|
+
readonly 'deny-conflicts-with-file': "An entry in a tool's own list lets a package of installScripts.deny run its install scripts, or blocks a package of installScripts.allow; apply does not change entries it did not write.";
|
|
786
|
+
readonly 'unexpected-value': "A setting apply adds to has a value of a type the tool does not accept there, so apply leaves it as it is and writes nothing into it.";
|
|
643
787
|
readonly 'built-in-list-replaced': "Bun's built-in list of trusted packages is replaced by the policy's allow-list.";
|
|
644
|
-
readonly 'scripts-not-enforceable': "The pinned npm or pnpm runs every install script and has no allow-list, so \"deny\" cannot be enforced.";
|
|
645
|
-
readonly 'before-overrides-cooldown': "before= in .npmrc takes the place of the release-age delay apply writes, or makes npm stop with an error next to it.";
|
|
646
|
-
readonly 'exact-version-gap': "The pinned pnpm skips the release-age delay for packages requested by exact version.";
|
|
788
|
+
readonly 'scripts-not-enforceable': "The pinned (with apply --user, the installed) npm or pnpm runs every install script and has no allow-list, so \"deny\" cannot be enforced.";
|
|
789
|
+
readonly 'before-overrides-cooldown': "before= in .npmrc takes the place of the release-age delay apply writes, or makes npm stop with an error next to it (apply --user then does not write the delay).";
|
|
790
|
+
readonly 'exact-version-gap': "The pinned (with apply --user, the installed) pnpm skips the release-age delay for packages requested by exact version.";
|
|
647
791
|
readonly 'source-not-enforceable': "The tool has no setting for a dependency source the policy denies; doctor checks the lockfile instead.";
|
|
648
792
|
readonly 'source-switch-indirect-only': "The pnpm setting for git and tarball sources stops them only for indirect dependencies.";
|
|
649
793
|
readonly 'source-switch-combined': "One pnpm setting covers git and tarball sources, so denying one denies both.";
|
|
@@ -669,6 +813,7 @@ declare const APPLY_ERRORS: {
|
|
|
669
813
|
readonly 'policy-exists': "depcurfew init found a depcurfew.json and writes it only with --force.";
|
|
670
814
|
readonly 'directory-not-found': "The directory given on the command line does not exist or cannot be opened.";
|
|
671
815
|
readonly 'not-a-directory': "The path given on the command line is a file, not a directory.";
|
|
816
|
+
readonly 'home-missing': "apply --user and init --user: the home directory (HOME, USERPROFILE on Windows) does not exist or is not an absolute path, so nothing is written.";
|
|
672
817
|
};
|
|
673
818
|
type ApplyWarningCode = keyof typeof APPLY_WARNINGS;
|
|
674
819
|
type ApplyErrorCode = keyof typeof APPLY_ERRORS;
|
|
@@ -708,7 +853,7 @@ declare class WriteFailed extends Error {
|
|
|
708
853
|
readonly unrestored: string[];
|
|
709
854
|
/** For files in `unrestored`: the temporary file, next to it, that holds its earlier text. */
|
|
710
855
|
readonly backups: Readonly<Record<string, string>>;
|
|
711
|
-
/** Temporary files that could not be removed, relative to the root. */
|
|
856
|
+
/** Temporary files that could not be removed, named like `file` (relative to the root, or as WriteOptions.name says). */
|
|
712
857
|
readonly leftovers: string[];
|
|
713
858
|
/** Another program holds the file, or (on Windows) it is read-only. */
|
|
714
859
|
readonly busy: boolean;
|
|
@@ -769,7 +914,14 @@ declare class ApplyWriteError extends Error {
|
|
|
769
914
|
/** Files already replaced that could not be put back (normally none). */
|
|
770
915
|
readonly unrestored: string[];
|
|
771
916
|
readonly report: ApplyReport;
|
|
772
|
-
|
|
917
|
+
/**
|
|
918
|
+
* `command` is what the fix tells the user to run again (depcurfew apply --user for user files), and
|
|
919
|
+
* `versionControl` whether the files may be in version control, to restore them from.
|
|
920
|
+
*/
|
|
921
|
+
constructor(failure: WriteFailed, report: ApplyReport, options?: {
|
|
922
|
+
command?: string;
|
|
923
|
+
versionControl?: boolean;
|
|
924
|
+
});
|
|
773
925
|
}
|
|
774
926
|
/**
|
|
775
927
|
* Reads the policy, detects the project, plans the changes and (unless told otherwise) writes them. If any file
|
|
@@ -779,8 +931,17 @@ declare class ApplyWriteError extends Error {
|
|
|
779
931
|
declare function applyProject(root: string, options?: {
|
|
780
932
|
write?: boolean;
|
|
781
933
|
}): ApplyReport;
|
|
782
|
-
|
|
783
|
-
|
|
934
|
+
interface DiffOptions {
|
|
935
|
+
/** Shows the values of secrets as <redacted> in every line (redactSecrets), for a diff that people or logs see. */
|
|
936
|
+
redact?: boolean;
|
|
937
|
+
}
|
|
938
|
+
/**
|
|
939
|
+
* A unified diff with three lines of context; empty when the texts are equal. `before` is null for a new file.
|
|
940
|
+
* Control characters in the file name are shown as text (printable), so that a name cannot start a line of its own
|
|
941
|
+
* and forge a header or a hunk. A file with an absolute path (a user file outside the home directory) is named as it
|
|
942
|
+
* is, without the a/ and b/ of repository paths.
|
|
943
|
+
*/
|
|
944
|
+
declare function unifiedDiff(file: string, before: string | null, after: string, context?: number, options?: DiffOptions): string;
|
|
784
945
|
interface SimilarName {
|
|
785
946
|
/** The popular package the name resembles. */
|
|
786
947
|
match: string;
|
|
@@ -888,9 +1049,13 @@ declare class Repository {
|
|
|
888
1049
|
#private;
|
|
889
1050
|
readonly root: string;
|
|
890
1051
|
readonly warnings: DetectionWarning[];
|
|
1052
|
+
/** Repository-relative paths of the files that were read, for the log of what doctor checked. */
|
|
1053
|
+
readonly read: Set<string>;
|
|
891
1054
|
constructor(root: string);
|
|
892
1055
|
warn(code: string, message: string, files: readonly string[]): void;
|
|
893
1056
|
isFile(path: string): boolean;
|
|
1057
|
+
/** Whether the path exists in the repository as something other than a regular file or a directory (a named pipe, a socket, a device). */
|
|
1058
|
+
isSpecialFile(path: string): boolean;
|
|
894
1059
|
/** The text of a file, without a byte order mark; undefined (with a warning when useful) if it cannot be read. */
|
|
895
1060
|
readText(path: string, limit?: number): string | undefined;
|
|
896
1061
|
/** The first bytes of a file, e.g. to recognize a lockfile format without reading a large file. */
|
|
@@ -912,6 +1077,8 @@ interface Location {
|
|
|
912
1077
|
file: string;
|
|
913
1078
|
/** 1-based; absent when the finding concerns the whole file. */
|
|
914
1079
|
line?: number;
|
|
1080
|
+
/** doctor --user: the environment variable, as it is set, of a finding whose file is "environment". */
|
|
1081
|
+
variable?: string;
|
|
915
1082
|
}
|
|
916
1083
|
interface Finding {
|
|
917
1084
|
rule: string;
|
|
@@ -943,6 +1110,8 @@ interface Rule {
|
|
|
943
1110
|
id: string;
|
|
944
1111
|
/** One sentence: what the rule finds. */
|
|
945
1112
|
summary: string;
|
|
1113
|
+
/** What the rule checks, said as what holds when it passes, for the list of what doctor checked. */
|
|
1114
|
+
checks?: string;
|
|
946
1115
|
/** Why it matters. */
|
|
947
1116
|
description: string;
|
|
948
1117
|
/** How to fix it in general. */
|
|
@@ -953,12 +1122,43 @@ interface Rule {
|
|
|
953
1122
|
requiresPolicy: boolean;
|
|
954
1123
|
check(context: RuleContext): void;
|
|
955
1124
|
}
|
|
1125
|
+
/** A package manager or bot doctor checked, with the version it checked against when one is known. */
|
|
1126
|
+
interface CheckedTool {
|
|
1127
|
+
id: string;
|
|
1128
|
+
name: string;
|
|
1129
|
+
version?: string;
|
|
1130
|
+
/** Where the version comes from: a repository file, or PATH for doctor --user. */
|
|
1131
|
+
versionFrom?: string;
|
|
1132
|
+
}
|
|
1133
|
+
/** One check of the list of what doctor checked: a rule and what came of it. */
|
|
1134
|
+
interface RuleResult {
|
|
1135
|
+
rule: string;
|
|
1136
|
+
/** What the rule checks, in plain words (Rule.check). */
|
|
1137
|
+
check: string;
|
|
1138
|
+
/** passed: it ran and found nothing; problems: it reported findings; skipped: it needs a policy that is missing or invalid. */
|
|
1139
|
+
result: 'passed' | 'problems' | 'skipped';
|
|
1140
|
+
errors: number;
|
|
1141
|
+
warnings: number;
|
|
1142
|
+
notes: number;
|
|
1143
|
+
}
|
|
1144
|
+
/** What doctor looked at, shown below the result, so that a clean report says what it covers. */
|
|
1145
|
+
interface Checked {
|
|
1146
|
+
tools: CheckedTool[];
|
|
1147
|
+
/** Files that were read, repository-relative (doctor) or as shown (~/.npmrc, doctor --user). */
|
|
1148
|
+
files: string[];
|
|
1149
|
+
/** Every rule, in the order it ran, with its result. */
|
|
1150
|
+
rules: RuleResult[];
|
|
1151
|
+
/** The policy that skipped rules need, as messages show it. */
|
|
1152
|
+
policyFile: string;
|
|
1153
|
+
}
|
|
956
1154
|
interface DoctorReport {
|
|
957
1155
|
schemaVersion: 1;
|
|
958
1156
|
/** invalid: depcurfew.json does not follow the schema or cannot be read (only with invalidPolicy: 'report'). */
|
|
959
1157
|
policy: 'valid' | 'missing' | 'invalid';
|
|
960
1158
|
findings: Finding[];
|
|
961
1159
|
notices: Notice[];
|
|
1160
|
+
/** What was checked. */
|
|
1161
|
+
checked?: Checked;
|
|
962
1162
|
}
|
|
963
1163
|
/** Every doctor rule, in the order they are documented. unreadable-config runs last, after every other rule has read its files. */
|
|
964
1164
|
declare const RULES: readonly Rule[];
|
|
@@ -1033,6 +1233,7 @@ declare const DEFAULT_POLICY: {
|
|
|
1033
1233
|
readonly installScripts: {
|
|
1034
1234
|
readonly default: "deny";
|
|
1035
1235
|
readonly allow: readonly [];
|
|
1236
|
+
readonly deny: readonly [];
|
|
1036
1237
|
};
|
|
1037
1238
|
readonly sources: {
|
|
1038
1239
|
readonly git: "deny";
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { b as APPLY_ERRORS, x as APPLY_WARNINGS, m as ApplyWriteError, M as DEFAULT_POLICY, d as EXIT_FAILURE, f as EXIT_OK, p as EXIT_USAGE, N as POLICY_FILE, h as PolicyError, s as PopularNames,
|
|
1
|
+
export { b as APPLY_ERRORS, x as APPLY_WARNINGS, m as ApplyWriteError, M as DEFAULT_POLICY, d as EXIT_FAILURE, f as EXIT_OK, p as EXIT_USAGE, N as POLICY_FILE, h as PolicyError, s as PopularNames, i as RULES, P as SCHEMA_URL, g as applyProject, _ as botDuration, l as checkSpec, u as checkSpecs, D as convertCooldown, O as convertMinutes, a as countLevels, I as detectProject, A as formatDuration, w as formatIssue, L as getVersion, v as loadPolicy, j as parseDuration, T as parsePolicy, y as planApply, F as renderPolicy, o as renderText, t as run, n as runDoctor, c as scanCommandLine, k as toDurationString, r as toSarif, C as unifiedDiff, E as validatePolicy, S as warningText } from "./run-BBZUJJq-.js";
|