@oddessentials/odd-repo-mapper 3.0.5 → 3.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.
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Path Safety Utilities
3
+ *
4
+ * Local implementation mirroring @oddessentials/odd-hive-mind/primitives/safety API.
5
+ * When odd-hive-mind is published to npm, replace with:
6
+ * import { resolveAndCheckPath, checkForbidden } from '@oddessentials/odd-hive-mind/primitives/safety';
7
+ *
8
+ * @see https://github.com/oddessentials/odd-hive-mind/blob/main/src/primitives/safety.ts
9
+ */
10
+ /**
11
+ * Resolve a path and check it doesn't escape the project root.
12
+ * Throws if path escapes containment.
13
+ *
14
+ * @param projectRoot - The root directory to contain writes to
15
+ * @param relPath - Relative path within the project
16
+ * @returns Resolved absolute path
17
+ * @throws Error if path escapes project root
18
+ */
19
+ export declare function resolveAndCheckPath(projectRoot: string, relPath: string): string;
20
+ /**
21
+ * Check if a path matches forbidden patterns.
22
+ *
23
+ * @param relPath - Relative path to check
24
+ * @param extraPatterns - Additional patterns to check against
25
+ * @returns Object indicating if forbidden and which rule matched
26
+ */
27
+ export declare function checkForbidden(relPath: string, extraPatterns?: string[]): {
28
+ forbidden: boolean;
29
+ rule?: string;
30
+ };
31
+ /**
32
+ * Validate output path is safe for writing.
33
+ * Combines containment check and forbidden pattern check.
34
+ *
35
+ * @param projectRoot - Project root for containment
36
+ * @param outputPath - Path to validate
37
+ * @returns Validated absolute path
38
+ * @throws Error if path is forbidden or escapes root
39
+ */
40
+ export declare function validateOutputPath(projectRoot: string, outputPath: string): string;
41
+ //# sourceMappingURL=safety.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safety.d.ts","sourceRoot":"","sources":["../../src/core/safety.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAgBH;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAmBhF;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC1B,OAAO,EAAE,MAAM,EACf,aAAa,GAAE,MAAM,EAAO,GAC7B;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAgBvC;AAwBD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAUlF"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Path Safety Utilities
3
+ *
4
+ * Local implementation mirroring @oddessentials/odd-hive-mind/primitives/safety API.
5
+ * When odd-hive-mind is published to npm, replace with:
6
+ * import { resolveAndCheckPath, checkForbidden } from '@oddessentials/odd-hive-mind/primitives/safety';
7
+ *
8
+ * @see https://github.com/oddessentials/odd-hive-mind/blob/main/src/primitives/safety.ts
9
+ */
10
+ import { resolve, relative, sep } from 'node:path';
11
+ import { realpathSync, existsSync } from 'node:fs';
12
+ /**
13
+ * Patterns forbidden for write operations
14
+ */
15
+ const FORBIDDEN_PATTERNS = [
16
+ '.git/**',
17
+ 'node_modules/**',
18
+ '.env*',
19
+ 'package-lock.json',
20
+ '*.log',
21
+ ];
22
+ /**
23
+ * Resolve a path and check it doesn't escape the project root.
24
+ * Throws if path escapes containment.
25
+ *
26
+ * @param projectRoot - The root directory to contain writes to
27
+ * @param relPath - Relative path within the project
28
+ * @returns Resolved absolute path
29
+ * @throws Error if path escapes project root
30
+ */
31
+ export function resolveAndCheckPath(projectRoot, relPath) {
32
+ const rootReal = realpathSync(projectRoot);
33
+ const candidate = resolve(projectRoot, relPath);
34
+ let resolved;
35
+ if (existsSync(candidate)) {
36
+ resolved = realpathSync(candidate);
37
+ }
38
+ else {
39
+ // For new files, use path.resolve; still enforce boundary
40
+ resolved = resolve(projectRoot, relPath);
41
+ }
42
+ const rootWithSep = rootReal.endsWith(sep) ? rootReal : rootReal + sep;
43
+ if (!resolved.startsWith(rootWithSep) && resolved !== rootReal) {
44
+ throw new Error(`Path escapes project root: ${relPath}`);
45
+ }
46
+ return resolved;
47
+ }
48
+ /**
49
+ * Check if a path matches forbidden patterns.
50
+ *
51
+ * @param relPath - Relative path to check
52
+ * @param extraPatterns - Additional patterns to check against
53
+ * @returns Object indicating if forbidden and which rule matched
54
+ */
55
+ export function checkForbidden(relPath, extraPatterns = []) {
56
+ const p = relPath.replace(/\\/g, '/');
57
+ if (!p) {
58
+ return { forbidden: true, rule: '<empty path>' };
59
+ }
60
+ const patterns = [...FORBIDDEN_PATTERNS, ...extraPatterns];
61
+ for (const rule of patterns) {
62
+ if (matchesPattern(p, rule)) {
63
+ return { forbidden: true, rule };
64
+ }
65
+ }
66
+ return { forbidden: false };
67
+ }
68
+ /**
69
+ * Simple glob pattern matching
70
+ */
71
+ function matchesPattern(path, pattern) {
72
+ const p = path.replace(/\\/g, '/');
73
+ const pat = pattern.replace(/\\/g, '/');
74
+ // Handle ** (any depth)
75
+ if (pat.includes('**')) {
76
+ const prefix = pat.split('**')[0];
77
+ return p.startsWith(prefix);
78
+ }
79
+ // Handle * (single segment)
80
+ if (pat.includes('*')) {
81
+ const regex = new RegExp('^' + pat.replace(/\*/g, '[^/]*') + '$');
82
+ return regex.test(p);
83
+ }
84
+ return p === pat;
85
+ }
86
+ /**
87
+ * Validate output path is safe for writing.
88
+ * Combines containment check and forbidden pattern check.
89
+ *
90
+ * @param projectRoot - Project root for containment
91
+ * @param outputPath - Path to validate
92
+ * @returns Validated absolute path
93
+ * @throws Error if path is forbidden or escapes root
94
+ */
95
+ export function validateOutputPath(projectRoot, outputPath) {
96
+ const absPath = resolveAndCheckPath(projectRoot, outputPath);
97
+ const relPath = relative(projectRoot, absPath);
98
+ const forbidden = checkForbidden(relPath);
99
+ if (forbidden.forbidden) {
100
+ throw new Error(`Forbidden path: ${relPath} (matched: ${forbidden.rule})`);
101
+ }
102
+ return absPath;
103
+ }
104
+ //# sourceMappingURL=safety.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safety.js","sourceRoot":"","sources":["../../src/core/safety.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oddessentials/odd-repo-mapper",
3
- "version": "3.0.5",
3
+ "version": "3.2.0",
4
4
  "description": "Deterministic code intelligence tool producing evidence-backed architecture diagrams and feature-test traceability matrices",
5
5
  "type": "module",
6
6
  "engines": {
@@ -39,7 +39,7 @@
39
39
  "@commitlint/cli": "^20.2.0",
40
40
  "@commitlint/config-conventional": "^20.2.0",
41
41
  "@eslint/js": "^9.39.2",
42
- "@oddessentials/repo-standards": "^4.0.0",
42
+ "@oddessentials/repo-standards": "^4.3.0",
43
43
  "@semantic-release/changelog": "^6.0.3",
44
44
  "@semantic-release/exec": "^7.1.0",
45
45
  "@semantic-release/git": "^10.0.1",