surfscan 0.1.0 → 0.1.1
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/CHANGELOG.md +4 -0
- package/README.md +2 -1
- package/dist/{chunk-5SNUPVTB.js → chunk-MJKZGRUS.js} +24 -5
- package/dist/chunk-MJKZGRUS.js.map +1 -0
- package/dist/cli/bin.js +2 -2
- package/dist/cli/bin.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -1
- package/docs/rules.md +1 -1
- package/package.json +1 -1
- package/dist/chunk-5SNUPVTB.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.1 (2026-11-09)
|
|
4
|
+
|
|
5
|
+
- New `deps.trustedPackages` config key: DEPS-004 skips the listed packages and says which it skipped. surfscan itself is always skipped, so depending on it no longer raises DEPS-004.
|
|
6
|
+
|
|
3
7
|
## 0.1.0 (2026-11-05)
|
|
4
8
|
|
|
5
9
|
First release.
|
package/README.md
CHANGED
|
@@ -165,13 +165,14 @@ In CI, pass `--strict`. If any check could not run, surfscan exits 2 instead of
|
|
|
165
165
|
{
|
|
166
166
|
"ignore": ["RULES-006"],
|
|
167
167
|
"ignorePaths": ["vendor/**"],
|
|
168
|
-
"deps": { "minAgeDays": 30 }
|
|
168
|
+
"deps": { "minAgeDays": 30, "trustedPackages": ["my-new-lib"] }
|
|
169
169
|
}
|
|
170
170
|
```
|
|
171
171
|
|
|
172
172
|
- `ignore`: rule IDs to skip
|
|
173
173
|
- `ignorePaths`: globs to exclude from scanning
|
|
174
174
|
- `deps.minAgeDays`: DEPS-004 threshold in days (default 30)
|
|
175
|
+
- `deps.trustedPackages`: package names the DEPS-004 age check skips (surfscan itself is always skipped). Other DEPS rules still apply. A project's `surfscan.json` is controlled by whoever owns the project, so do not rely on it when scanning code you do not trust.
|
|
175
176
|
|
|
176
177
|
Unknown keys are rejected with an error.
|
|
177
178
|
|
|
@@ -136,7 +136,7 @@ var CONFIG_FILE_NAME = "surfscan.json";
|
|
|
136
136
|
var DEFAULT_CONFIG = {
|
|
137
137
|
ignore: [],
|
|
138
138
|
ignorePaths: [],
|
|
139
|
-
deps: { minAgeDays: 30 }
|
|
139
|
+
deps: { minAgeDays: 30, trustedPackages: [] }
|
|
140
140
|
};
|
|
141
141
|
var ConfigError = class extends Error {
|
|
142
142
|
constructor(message) {
|
|
@@ -145,7 +145,7 @@ var ConfigError = class extends Error {
|
|
|
145
145
|
}
|
|
146
146
|
};
|
|
147
147
|
var TOP_LEVEL_KEYS = ["ignore", "ignorePaths", "deps"];
|
|
148
|
-
var DEPS_KEYS = ["minAgeDays"];
|
|
148
|
+
var DEPS_KEYS = ["minAgeDays", "trustedPackages"];
|
|
149
149
|
var RULE_ID = /^[A-Z]+-\d{3}$/;
|
|
150
150
|
function isPlainObject(value) {
|
|
151
151
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -173,7 +173,7 @@ function validateConfig(raw, source = CONFIG_FILE_NAME) {
|
|
|
173
173
|
const config = {
|
|
174
174
|
ignore: [...DEFAULT_CONFIG.ignore],
|
|
175
175
|
ignorePaths: [...DEFAULT_CONFIG.ignorePaths],
|
|
176
|
-
deps: { ...DEFAULT_CONFIG.deps }
|
|
176
|
+
deps: { ...DEFAULT_CONFIG.deps, trustedPackages: [...DEFAULT_CONFIG.deps.trustedPackages] }
|
|
177
177
|
};
|
|
178
178
|
if (raw.ignore !== void 0) {
|
|
179
179
|
config.ignore = stringArray(raw.ignore, "ignore", source);
|
|
@@ -198,6 +198,13 @@ function validateConfig(raw, source = CONFIG_FILE_NAME) {
|
|
|
198
198
|
}
|
|
199
199
|
config.deps.minAgeDays = minAgeDays;
|
|
200
200
|
}
|
|
201
|
+
if (raw.deps.trustedPackages !== void 0) {
|
|
202
|
+
const names = stringArray(raw.deps.trustedPackages, "deps.trustedPackages", source);
|
|
203
|
+
if (names.some((n) => n.trim() === "")) {
|
|
204
|
+
throw new ConfigError(`${source}: "deps.trustedPackages" must not contain empty names`);
|
|
205
|
+
}
|
|
206
|
+
config.deps.trustedPackages = names;
|
|
207
|
+
}
|
|
201
208
|
}
|
|
202
209
|
return config;
|
|
203
210
|
}
|
|
@@ -2655,6 +2662,7 @@ function dataFor(context) {
|
|
|
2655
2662
|
function finding2(rule, ref, message, fix) {
|
|
2656
2663
|
return { ruleId: rule.id, severity: rule.severity, message, file: ref.file, line: ref.line, fix };
|
|
2657
2664
|
}
|
|
2665
|
+
var BUILT_IN_TRUSTED = ["surfscan"];
|
|
2658
2666
|
async function registryFindings(context, check) {
|
|
2659
2667
|
const { refs, lookups } = await dataFor(context);
|
|
2660
2668
|
const out = [];
|
|
@@ -2742,19 +2750,30 @@ var rules5 = [
|
|
|
2742
2750
|
severity: "medium",
|
|
2743
2751
|
title: "Newly published package",
|
|
2744
2752
|
check(context) {
|
|
2745
|
-
const { minAgeDays } = context.config.deps;
|
|
2753
|
+
const { minAgeDays, trustedPackages } = context.config.deps;
|
|
2754
|
+
const trusted = /* @__PURE__ */ new Set([...BUILT_IN_TRUSTED, ...trustedPackages]);
|
|
2755
|
+
const skipped = /* @__PURE__ */ new Set();
|
|
2746
2756
|
const now = Date.now();
|
|
2747
2757
|
return registryFindings(context, (ref, packument) => {
|
|
2748
2758
|
const created = Date.parse(packument.created ?? "");
|
|
2749
2759
|
if (Number.isNaN(created)) return void 0;
|
|
2750
2760
|
const ageDays = Math.floor((now - created) / DAY_MS);
|
|
2751
2761
|
if (ageDays >= minAgeDays) return void 0;
|
|
2762
|
+
if (trusted.has(ref.name)) {
|
|
2763
|
+
skipped.add(ref.name);
|
|
2764
|
+
return void 0;
|
|
2765
|
+
}
|
|
2752
2766
|
return finding2(
|
|
2753
2767
|
this,
|
|
2754
2768
|
ref,
|
|
2755
2769
|
`"${ref.name}" was first published ${ageDays} day(s) ago (minimum ${minAgeDays})`,
|
|
2756
2770
|
"review the package and its maintainer before using it, or wait until it has a track record"
|
|
2757
2771
|
);
|
|
2772
|
+
}).then((findings) => {
|
|
2773
|
+
if (skipped.size > 0) {
|
|
2774
|
+
context.warn(`deps: skipped the age check (DEPS-004) for ${skipped.size} trusted package(s): ${[...skipped].join(", ")}`);
|
|
2775
|
+
}
|
|
2776
|
+
return findings;
|
|
2758
2777
|
});
|
|
2759
2778
|
}
|
|
2760
2779
|
},
|
|
@@ -2880,4 +2899,4 @@ export {
|
|
|
2880
2899
|
rules5,
|
|
2881
2900
|
depsScanner
|
|
2882
2901
|
};
|
|
2883
|
-
//# sourceMappingURL=chunk-
|
|
2902
|
+
//# sourceMappingURL=chunk-MJKZGRUS.js.map
|