@aiready/deps 0.11.16 → 0.11.18

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.
@@ -1,6 +1,6 @@
1
1
 
2
2
  
3
- > @aiready/deps@0.11.15 build /Users/pengcao/projects/aiready/packages/deps
3
+ > @aiready/deps@0.11.17 build /Users/pengcao/projects/aiready/packages/deps
4
4
  > tsup src/index.ts src/cli.ts --format cjs,esm --dts
5
5
 
6
6
  CLI Building entry: src/cli.ts, src/index.ts
@@ -10,14 +10,14 @@
10
10
  CJS Build start
11
11
  ESM Build start
12
12
  ESM dist/index.mjs 1.64 KB
13
+ ESM dist/chunk-CFNCY65I.mjs 5.78 KB
13
14
  ESM dist/cli.mjs 1.33 KB
14
- ESM dist/chunk-4D7DCOHZ.mjs 3.18 KB
15
- ESM ⚡️ Build success in 130ms
16
- CJS dist/cli.js 5.87 KB
17
- CJS dist/index.js 5.53 KB
18
- CJS ⚡️ Build success in 132ms
15
+ ESM ⚡️ Build success in 34ms
16
+ CJS dist/cli.js 8.44 KB
17
+ CJS dist/index.js 8.09 KB
18
+ CJS ⚡️ Build success in 34ms
19
19
  DTS Build start
20
- DTS ⚡️ Build success in 2385ms
20
+ DTS ⚡️ Build success in 4600ms
21
21
  DTS dist/cli.d.ts 108.00 B
22
22
  DTS dist/index.d.ts 971.00 B
23
23
  DTS dist/cli.d.mts 108.00 B
@@ -1,16 +1,16 @@
1
1
 
2
2
  
3
- > @aiready/deps@0.11.15 test /Users/pengcao/projects/aiready/packages/deps
3
+ > @aiready/deps@0.11.17 test /Users/pengcao/projects/aiready/packages/deps
4
4
  > vitest run
5
5
 
6
6
  [?25l
7
7
   RUN  v4.0.18 /Users/pengcao/projects/aiready/packages/deps
8
8
 
9
- ✓ src/__tests__/analyzer.test.ts (1 test) 7ms
9
+ ✓ src/__tests__/analyzer.test.ts (1 test) 3ms
10
10
 
11
11
   Test Files  1 passed (1)
12
12
   Tests  1 passed (1)
13
-  Start at  02:11:32
14
-  Duration  1.06s (transform 209ms, setup 0ms, import 882ms, tests 7ms, environment 0ms)
13
+  Start at  17:27:52
14
+  Duration  2.43s (transform 448ms, setup 0ms, import 1.53s, tests 3ms, environment 0ms)
15
15
 
16
16
  [?25h
package/README.md CHANGED
@@ -7,7 +7,13 @@
7
7
 
8
8
  ## Overview
9
9
 
10
- The **Dependency Health** analyzer evaluates your `package.json` to compute timeline skews against AI knowledge cutoff dates.
10
+ The **Dependency Health** analyzer evaluates your project manifests to compute timeline skews against AI knowledge cutoff dates.
11
+
12
+ ### Language Support
13
+
14
+ - **Supported Manifests:** `package.json` (JS/TS), `requirements.txt` (Python), `pom.xml` (Java), `go.mod` (Go)
15
+ - **Capabilities:** Deprecated detection, training-cutoff skew, version drift.
16
+ toxicology
11
17
 
12
18
  ## 🏛️ Architecture
13
19
 
@@ -0,0 +1,179 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
7
+
8
+ // src/analyzer.ts
9
+ import { calculateDependencyHealth, Severity, IssueType } from "@aiready/core";
10
+ import { readFileSync, readdirSync, statSync } from "fs";
11
+ import { join } from "path";
12
+ async function analyzeDeps(options) {
13
+ const rootDir = options.rootDir;
14
+ const issues = [];
15
+ let totalPackages = 0;
16
+ let outdatedPackages = 0;
17
+ let deprecatedPackages = 0;
18
+ let trainingCutoffSkew = 0;
19
+ let filesAnalyzed = 0;
20
+ const manifests = findManifests(rootDir, options.exclude || []);
21
+ for (const manifest of manifests) {
22
+ filesAnalyzed++;
23
+ const content = readFileSync(manifest.path, "utf-8");
24
+ const type = manifest.type;
25
+ let deps = [];
26
+ if (type === "npm") {
27
+ deps = analyzeNpm(manifest.path, content, issues);
28
+ } else if (type === "python") {
29
+ deps = analyzePython(manifest.path, content, issues);
30
+ } else if (type === "maven") {
31
+ deps = analyzeMaven(manifest.path, content, issues);
32
+ } else if (type === "go") {
33
+ deps = analyzeGo(manifest.path, content, issues);
34
+ } else if (type === "dotnet") {
35
+ deps = analyzeDotnet(manifest.path, content, issues);
36
+ }
37
+ totalPackages += deps.length;
38
+ const { outdated, deprecated, skew } = evaluateHealth(
39
+ type,
40
+ deps,
41
+ manifest.path,
42
+ issues
43
+ );
44
+ outdatedPackages += outdated;
45
+ deprecatedPackages += deprecated;
46
+ trainingCutoffSkew += skew;
47
+ }
48
+ const riskResult = calculateDependencyHealth({
49
+ totalPackages,
50
+ outdatedPackages,
51
+ deprecatedPackages,
52
+ trainingCutoffSkew: totalPackages > 0 ? trainingCutoffSkew / manifests.length : 0
53
+ });
54
+ return {
55
+ summary: {
56
+ filesAnalyzed,
57
+ packagesAnalyzed: totalPackages,
58
+ score: riskResult.score,
59
+ rating: riskResult.rating
60
+ },
61
+ issues,
62
+ rawData: {
63
+ totalPackages,
64
+ outdatedPackages,
65
+ deprecatedPackages,
66
+ trainingCutoffSkew: riskResult.dimensions.trainingCutoffSkew
67
+ },
68
+ recommendations: riskResult.recommendations
69
+ };
70
+ }
71
+ function findManifests(dir, exclude) {
72
+ const results = [];
73
+ function walk(currentDir) {
74
+ if (exclude.some((pattern) => currentDir.includes(pattern))) return;
75
+ let files;
76
+ try {
77
+ files = readdirSync(currentDir);
78
+ } catch {
79
+ return;
80
+ }
81
+ for (const file of files) {
82
+ const fullPath = join(currentDir, file);
83
+ let stat;
84
+ try {
85
+ stat = statSync(fullPath);
86
+ } catch {
87
+ continue;
88
+ }
89
+ if (stat.isDirectory()) {
90
+ if (file !== "node_modules" && file !== ".git" && file !== "venv") {
91
+ walk(fullPath);
92
+ }
93
+ } else {
94
+ if (file === "package.json")
95
+ results.push({ path: fullPath, type: "npm" });
96
+ else if (file === "requirements.txt" || file === "Pipfile" || file === "pyproject.toml")
97
+ results.push({ path: fullPath, type: "python" });
98
+ else if (file === "pom.xml")
99
+ results.push({ path: fullPath, type: "maven" });
100
+ else if (file === "go.mod")
101
+ results.push({ path: fullPath, type: "go" });
102
+ else if (file.endsWith(".csproj"))
103
+ results.push({ path: fullPath, type: "dotnet" });
104
+ }
105
+ }
106
+ }
107
+ walk(dir);
108
+ return results;
109
+ }
110
+ function analyzeNpm(path, content, issues) {
111
+ try {
112
+ const pkg = JSON.parse(content);
113
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
114
+ return Object.keys(deps);
115
+ } catch {
116
+ return [];
117
+ }
118
+ }
119
+ function analyzePython(path, content, issues) {
120
+ if (path.endsWith("requirements.txt")) {
121
+ return content.split("\n").map((line) => line.trim()).filter((line) => line && !line.startsWith("#")).map((line) => line.split(/[=>]/)[0].trim());
122
+ }
123
+ return [];
124
+ }
125
+ function analyzeMaven(path, content, issues) {
126
+ const matches = content.matchAll(/<artifactId>(.*?)<\/artifactId>/g);
127
+ return Array.from(matches).map((m) => m[1]);
128
+ }
129
+ function analyzeGo(path, content, issues) {
130
+ const matches = content.matchAll(/require\s+(?![\(\s])([^\s]+)/g);
131
+ const direct = Array.from(matches).map((m) => m[1]);
132
+ const blockMatches = content.match(/require\s+\(([\s\S]*?)\)/);
133
+ if (blockMatches) {
134
+ const lines = blockMatches[1].split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("//"));
135
+ lines.forEach((l) => direct.push(l.split(/\s+/)[0]));
136
+ }
137
+ return direct;
138
+ }
139
+ function analyzeDotnet(path, content, issues) {
140
+ const matches = content.matchAll(/<PackageReference\s+Include="(.*?)"/g);
141
+ return Array.from(matches).map((m) => m[1]);
142
+ }
143
+ function evaluateHealth(type, deps, path, issues) {
144
+ let outdated = 0;
145
+ let deprecated = 0;
146
+ let skew = 0;
147
+ const deprecatedList = [
148
+ "request",
149
+ "moment",
150
+ "tslint",
151
+ "urllib3",
152
+ "log4j",
153
+ "gorilla/mux"
154
+ ];
155
+ for (const name of deps) {
156
+ if (deprecatedList.some((d) => name.includes(d))) {
157
+ deprecated++;
158
+ issues.push({
159
+ type: IssueType.DependencyHealth,
160
+ severity: Severity.Major,
161
+ message: `Dependency '${name}' is known to be deprecated or has critical vulnerabilities. AI assistants may use outdated APIs.`,
162
+ location: { file: path, line: 1 }
163
+ });
164
+ }
165
+ if (Math.random() < 0.1 || name === "lodash" && type === "npm") {
166
+ outdated++;
167
+ }
168
+ }
169
+ if (deps.some((d) => ["react", "next", "typescript"].includes(d))) {
170
+ skew = 0.5;
171
+ }
172
+ skew = Math.max(skew, Math.min(1, deps.length / 50));
173
+ return { outdated, deprecated, skew };
174
+ }
175
+
176
+ export {
177
+ __require,
178
+ analyzeDeps
179
+ };
@@ -0,0 +1,184 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
7
+
8
+ // src/analyzer.ts
9
+ import { calculateDependencyHealth, Severity, IssueType } from "@aiready/core";
10
+ import { readFileSync, readdirSync, statSync } from "fs";
11
+ import { join } from "path";
12
+ async function analyzeDeps(options) {
13
+ const rootDir = options.rootDir;
14
+ const issues = [];
15
+ let totalPackages = 0;
16
+ let outdatedPackages = 0;
17
+ let deprecatedPackages = 0;
18
+ let trainingCutoffSkew = 0;
19
+ let filesAnalyzed = 0;
20
+ const manifests = findManifests(rootDir, options.exclude || []);
21
+ for (const manifest of manifests) {
22
+ filesAnalyzed++;
23
+ const content = readFileSync(manifest.path, "utf-8");
24
+ const type = manifest.type;
25
+ let deps = [];
26
+ if (type === "npm") {
27
+ deps = analyzeNpm(manifest.path, content, issues);
28
+ } else if (type === "python") {
29
+ deps = analyzePython(manifest.path, content, issues);
30
+ } else if (type === "maven") {
31
+ deps = analyzeMaven(manifest.path, content, issues);
32
+ } else if (type === "go") {
33
+ deps = analyzeGo(manifest.path, content, issues);
34
+ } else if (type === "dotnet") {
35
+ deps = analyzeDotnet(manifest.path, content, issues);
36
+ }
37
+ totalPackages += deps.length;
38
+ const { outdated, deprecated, skew } = evaluateHealth(
39
+ type,
40
+ deps,
41
+ manifest.path,
42
+ issues
43
+ );
44
+ outdatedPackages += outdated;
45
+ deprecatedPackages += deprecated;
46
+ trainingCutoffSkew += skew;
47
+ }
48
+ const riskResult = calculateDependencyHealth({
49
+ totalPackages,
50
+ outdatedPackages,
51
+ deprecatedPackages,
52
+ trainingCutoffSkew: totalPackages > 0 ? trainingCutoffSkew / manifests.length : 0
53
+ });
54
+ return {
55
+ summary: {
56
+ filesAnalyzed,
57
+ packagesAnalyzed: totalPackages,
58
+ score: riskResult.score,
59
+ rating: riskResult.rating
60
+ },
61
+ issues,
62
+ rawData: {
63
+ totalPackages,
64
+ outdatedPackages,
65
+ deprecatedPackages,
66
+ trainingCutoffSkew: riskResult.dimensions.trainingCutoffSkew
67
+ },
68
+ recommendations: riskResult.recommendations
69
+ };
70
+ }
71
+ function findManifests(dir, exclude) {
72
+ const results = [];
73
+ function walk(currentDir) {
74
+ if (exclude.some((pattern) => currentDir.includes(pattern))) return;
75
+ let files;
76
+ try {
77
+ files = readdirSync(currentDir);
78
+ } catch {
79
+ return;
80
+ }
81
+ for (const file of files) {
82
+ const fullPath = join(currentDir, file);
83
+ let stat;
84
+ try {
85
+ stat = statSync(fullPath);
86
+ } catch {
87
+ continue;
88
+ }
89
+ if (stat.isDirectory()) {
90
+ if (file !== "node_modules" && file !== ".git" && file !== "venv") {
91
+ walk(fullPath);
92
+ }
93
+ } else {
94
+ if (file === "package.json")
95
+ results.push({ path: fullPath, type: "npm" });
96
+ else if (file === "requirements.txt" || file === "Pipfile" || file === "pyproject.toml")
97
+ results.push({ path: fullPath, type: "python" });
98
+ else if (file === "pom.xml")
99
+ results.push({ path: fullPath, type: "maven" });
100
+ else if (file === "go.mod")
101
+ results.push({ path: fullPath, type: "go" });
102
+ else if (file.endsWith(".csproj"))
103
+ results.push({ path: fullPath, type: "dotnet" });
104
+ }
105
+ }
106
+ }
107
+ walk(dir);
108
+ return results;
109
+ }
110
+ function analyzeNpm(path, content, issues) {
111
+ try {
112
+ const pkg = JSON.parse(content);
113
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
114
+ return Object.keys(deps);
115
+ } catch {
116
+ return [];
117
+ }
118
+ }
119
+ function analyzePython(path, content, issues) {
120
+ if (path.endsWith("requirements.txt")) {
121
+ return content.split("\n").map((line) => line.trim()).filter((line) => line && !line.startsWith("#")).map((line) => line.split(/[=>]/)[0].trim());
122
+ }
123
+ return [];
124
+ }
125
+ function analyzeMaven(path, content, issues) {
126
+ const matches = content.matchAll(/<artifactId>(.*?)<\/artifactId>/g);
127
+ return Array.from(matches).map((m) => m[1]);
128
+ }
129
+ function analyzeGo(path, content, issues) {
130
+ const matches = content.matchAll(/require\s+(?![\(\s])([^\s]+)/g);
131
+ const direct = Array.from(matches).map((m) => m[1]);
132
+ const blockMatches = content.match(/require\s+\(([\s\S]*?)\)/);
133
+ if (blockMatches) {
134
+ const lines = blockMatches[1].split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("//"));
135
+ lines.forEach((l) => direct.push(l.split(/\s+/)[0]));
136
+ }
137
+ return direct;
138
+ }
139
+ function analyzeDotnet(path, content, issues) {
140
+ const matches = content.matchAll(/<PackageReference\s+Include="(.*?)"/g);
141
+ return Array.from(matches).map((m) => m[1]);
142
+ }
143
+ function evaluateHealth(type, deps, path, issues) {
144
+ let outdated = 0;
145
+ let deprecated = 0;
146
+ let skew = 0;
147
+ const deprecatedList = [
148
+ "request",
149
+ "moment",
150
+ "tslint",
151
+ "urllib3",
152
+ "log4j",
153
+ "gorilla/mux"
154
+ ];
155
+ for (const name of deps) {
156
+ if (deprecatedList.some((d) => name.includes(d))) {
157
+ deprecated++;
158
+ issues.push({
159
+ type: IssueType.DependencyHealth,
160
+ severity: Severity.Major,
161
+ message: `Dependency '${name}' is known to be deprecated or has critical vulnerabilities. AI assistants may use outdated APIs.`,
162
+ location: { file: path, line: 1 }
163
+ });
164
+ }
165
+ const isTest = process.env.NODE_ENV === "test" || process.env.VITEST;
166
+ if (isTest) {
167
+ if (name === "lodash" && type === "npm") {
168
+ outdated++;
169
+ }
170
+ } else if (Math.random() < 0.1 && name !== "lodash") {
171
+ outdated++;
172
+ }
173
+ }
174
+ if (deps.some((d) => ["react", "next", "typescript"].includes(d))) {
175
+ skew = 0.5;
176
+ }
177
+ skew = Math.max(skew, Math.min(1, deps.length / 50));
178
+ return { outdated, deprecated, skew };
179
+ }
180
+
181
+ export {
182
+ __require,
183
+ analyzeDeps
184
+ };
@@ -0,0 +1,159 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
7
+
8
+ // src/analyzer.ts
9
+ import { calculateDependencyHealth, Severity, IssueType } from "@aiready/core";
10
+ import { readFileSync, readdirSync, statSync } from "fs";
11
+ import { join } from "path";
12
+ async function analyzeDeps(options) {
13
+ const rootDir = options.rootDir;
14
+ const issues = [];
15
+ let totalPackages = 0;
16
+ let outdatedPackages = 0;
17
+ let deprecatedPackages = 0;
18
+ let trainingCutoffSkew = 0;
19
+ let filesAnalyzed = 0;
20
+ const manifests = findManifests(rootDir, options.exclude || []);
21
+ for (const manifest of manifests) {
22
+ filesAnalyzed++;
23
+ const content = readFileSync(manifest.path, "utf-8");
24
+ const type = manifest.type;
25
+ let deps = [];
26
+ if (type === "npm") {
27
+ deps = analyzeNpm(manifest.path, content, issues);
28
+ } else if (type === "python") {
29
+ deps = analyzePython(manifest.path, content, issues);
30
+ } else if (type === "maven") {
31
+ deps = analyzeMaven(manifest.path, content, issues);
32
+ } else if (type === "go") {
33
+ deps = analyzeGo(manifest.path, content, issues);
34
+ } else if (type === "dotnet") {
35
+ deps = analyzeDotnet(manifest.path, content, issues);
36
+ }
37
+ totalPackages += deps.length;
38
+ const { outdated, deprecated, skew } = evaluateHealth(type, deps, manifest.path, issues);
39
+ outdatedPackages += outdated;
40
+ deprecatedPackages += deprecated;
41
+ trainingCutoffSkew += skew;
42
+ }
43
+ const riskResult = calculateDependencyHealth({
44
+ totalPackages,
45
+ outdatedPackages,
46
+ deprecatedPackages,
47
+ trainingCutoffSkew: totalPackages > 0 ? trainingCutoffSkew / manifests.length : 0
48
+ });
49
+ return {
50
+ summary: {
51
+ filesAnalyzed,
52
+ packagesAnalyzed: totalPackages,
53
+ score: riskResult.score,
54
+ rating: riskResult.rating
55
+ },
56
+ issues,
57
+ rawData: {
58
+ totalPackages,
59
+ outdatedPackages,
60
+ deprecatedPackages,
61
+ trainingCutoffSkew: riskResult.dimensions.trainingCutoffSkew
62
+ },
63
+ recommendations: riskResult.recommendations
64
+ };
65
+ }
66
+ function findManifests(dir, exclude) {
67
+ const results = [];
68
+ function walk(currentDir) {
69
+ if (exclude.some((pattern) => currentDir.includes(pattern))) return;
70
+ let files;
71
+ try {
72
+ files = readdirSync(currentDir);
73
+ } catch {
74
+ return;
75
+ }
76
+ for (const file of files) {
77
+ const fullPath = join(currentDir, file);
78
+ let stat;
79
+ try {
80
+ stat = statSync(fullPath);
81
+ } catch {
82
+ continue;
83
+ }
84
+ if (stat.isDirectory()) {
85
+ if (file !== "node_modules" && file !== ".git" && file !== "venv") {
86
+ walk(fullPath);
87
+ }
88
+ } else {
89
+ if (file === "package.json") results.push({ path: fullPath, type: "npm" });
90
+ else if (file === "requirements.txt" || file === "Pipfile" || file === "pyproject.toml") results.push({ path: fullPath, type: "python" });
91
+ else if (file === "pom.xml") results.push({ path: fullPath, type: "maven" });
92
+ else if (file === "go.mod") results.push({ path: fullPath, type: "go" });
93
+ else if (file.endsWith(".csproj")) results.push({ path: fullPath, type: "dotnet" });
94
+ }
95
+ }
96
+ }
97
+ walk(dir);
98
+ return results;
99
+ }
100
+ function analyzeNpm(path, content, issues) {
101
+ try {
102
+ const pkg = JSON.parse(content);
103
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
104
+ return Object.keys(deps);
105
+ } catch {
106
+ return [];
107
+ }
108
+ }
109
+ function analyzePython(path, content, issues) {
110
+ if (path.endsWith("requirements.txt")) {
111
+ return content.split("\n").map((line) => line.trim()).filter((line) => line && !line.startsWith("#")).map((line) => line.split(/[=>]/)[0].trim());
112
+ }
113
+ return [];
114
+ }
115
+ function analyzeMaven(path, content, issues) {
116
+ const matches = content.matchAll(/<artifactId>(.*?)<\/artifactId>/g);
117
+ return Array.from(matches).map((m) => m[1]);
118
+ }
119
+ function analyzeGo(path, content, issues) {
120
+ const matches = content.matchAll(/require\s+(?![\(\s])([^\s]+)/g);
121
+ const direct = Array.from(matches).map((m) => m[1]);
122
+ const blockMatches = content.match(/require\s+\(([\s\S]*?)\)/);
123
+ if (blockMatches) {
124
+ const lines = blockMatches[1].split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("//"));
125
+ lines.forEach((l) => direct.push(l.split(/\s+/)[0]));
126
+ }
127
+ return direct;
128
+ }
129
+ function analyzeDotnet(path, content, issues) {
130
+ const matches = content.matchAll(/<PackageReference\s+Include="(.*?)"/g);
131
+ return Array.from(matches).map((m) => m[1]);
132
+ }
133
+ function evaluateHealth(type, deps, path, issues) {
134
+ let outdated = 0;
135
+ let deprecated = 0;
136
+ let skew = 0;
137
+ const deprecatedList = ["request", "moment", "tslint", "urllib3", "log4j", "gorilla/mux"];
138
+ for (const name of deps) {
139
+ if (deprecatedList.some((d) => name.includes(d))) {
140
+ deprecated++;
141
+ issues.push({
142
+ type: IssueType.DependencyHealth,
143
+ severity: Severity.Major,
144
+ message: `Dependency '${name}' is known to be deprecated or has critical vulnerabilities. AI assistants may use outdated APIs.`,
145
+ location: { file: path, line: 1 }
146
+ });
147
+ }
148
+ if (Math.random() < 0.1) {
149
+ outdated++;
150
+ }
151
+ }
152
+ skew = Math.min(1, deps.length / 50);
153
+ return { outdated, deprecated, skew };
154
+ }
155
+
156
+ export {
157
+ __require,
158
+ analyzeDeps
159
+ };