@untangle-code/scanner 0.0.0-stage → 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/LICENSE +661 -0
- package/NOTICE +90 -0
- package/README.md +303 -2
- package/THIRD_PARTY_LICENSES.md +24 -0
- package/dist/binary-classifier.d.ts +45 -0
- package/dist/binary-classifier.d.ts.map +1 -0
- package/dist/binary-classifier.js +296 -0
- package/dist/binary-classifier.js.map +1 -0
- package/dist/concurrency.d.ts +8 -0
- package/dist/concurrency.d.ts.map +1 -0
- package/dist/concurrency.js +64 -0
- package/dist/concurrency.js.map +1 -0
- package/dist/discovery.d.ts +9 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +254 -0
- package/dist/discovery.js.map +1 -0
- package/dist/gitignore-pattern.d.ts +35 -0
- package/dist/gitignore-pattern.d.ts.map +1 -0
- package/dist/gitignore-pattern.js +155 -0
- package/dist/gitignore-pattern.js.map +1 -0
- package/dist/hashing.d.ts +14 -0
- package/dist/hashing.d.ts.map +1 -0
- package/dist/hashing.js +32 -0
- package/dist/hashing.js.map +1 -0
- package/dist/ignore-engine.d.ts +27 -0
- package/dist/ignore-engine.d.ts.map +1 -0
- package/dist/ignore-engine.js +130 -0
- package/dist/ignore-engine.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/language-classifier.d.ts +19 -0
- package/dist/language-classifier.d.ts.map +1 -0
- package/dist/language-classifier.js +114 -0
- package/dist/language-classifier.js.map +1 -0
- package/dist/node-fs/index.d.ts +10 -0
- package/dist/node-fs/index.d.ts.map +1 -0
- package/dist/node-fs/index.js +10 -0
- package/dist/node-fs/index.js.map +1 -0
- package/dist/node-fs/node-file-system.d.ts +19 -0
- package/dist/node-fs/node-file-system.d.ts.map +1 -0
- package/dist/node-fs/node-file-system.js +104 -0
- package/dist/node-fs/node-file-system.js.map +1 -0
- package/dist/node-fs/node-streaming-hasher.d.ts +4 -0
- package/dist/node-fs/node-streaming-hasher.d.ts.map +1 -0
- package/dist/node-fs/node-streaming-hasher.js +33 -0
- package/dist/node-fs/node-streaming-hasher.js.map +1 -0
- package/dist/port-options.d.ts +8 -0
- package/dist/port-options.d.ts.map +1 -0
- package/dist/port-options.js +4 -0
- package/dist/port-options.js.map +1 -0
- package/dist/semaphore.d.ts +18 -0
- package/dist/semaphore.d.ts.map +1 -0
- package/dist/semaphore.js +42 -0
- package/dist/semaphore.js.map +1 -0
- package/dist/types.d.ts +102 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +63 -3
- package/src/binary-classifier.ts +365 -0
- package/src/concurrency.ts +78 -0
- package/src/discovery.ts +362 -0
- package/src/gitignore-pattern.ts +170 -0
- package/src/hashing.ts +37 -0
- package/src/ignore-engine.ts +157 -0
- package/src/index.ts +48 -0
- package/src/language-classifier.ts +137 -0
- package/src/node-fs/index.ts +9 -0
- package/src/node-fs/node-file-system.ts +137 -0
- package/src/node-fs/node-streaming-hasher.ts +35 -0
- package/src/port-options.ts +10 -0
- package/src/semaphore.ts +45 -0
- package/src/types.ts +121 -0
package/src/types.ts
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scanner-local contracts (spec.md §6.1–§6.3, §12.1; architecture.md §6.4).
|
|
3
|
+
*
|
|
4
|
+
* `ScannedFileV1` is a WP-05-local type, not an import from
|
|
5
|
+
* `@untangle-code/domain` — see README, "Entscheidungen" (Entscheidung 1)
|
|
6
|
+
* for the full reasoning. In short: docs/BUILD_PLAN.md §3's Contract-Register
|
|
7
|
+
* (the authoritative, exhaustive list of what MUST live in domain) requires
|
|
8
|
+
* `FileManifestV1` for a file's tracked analysis state but does not register
|
|
9
|
+
* a raw pre-analysis scan output shape at all; the name deliberately avoids
|
|
10
|
+
* "FileSnapshot" (architecture.md §6.1's informal domain-entity name for
|
|
11
|
+
* this concept) so it cannot be mistaken for that domain contract by name
|
|
12
|
+
* alone. Downstream packages (parser-registry, chunker) consume it
|
|
13
|
+
* positionally, not by importing domain types for it.
|
|
14
|
+
*/
|
|
15
|
+
import type { FileSystemPort, PortCallOptions } from "@untangle-code/domain";
|
|
16
|
+
|
|
17
|
+
/** Coarse text-encoding guess from a byte sample (BOM + byte-range heuristics). */
|
|
18
|
+
export type TextEncodingGuess = "utf8" | "utf16le" | "utf16be" | "ascii" | "unknown";
|
|
19
|
+
|
|
20
|
+
/** How a file's language id was determined. */
|
|
21
|
+
export type LanguageDetectionSource = "extension" | "content" | "unknown";
|
|
22
|
+
|
|
23
|
+
/** Why a discovered path was excluded from the yielded candidate stream. */
|
|
24
|
+
export type ExclusionReason =
|
|
25
|
+
| "security"
|
|
26
|
+
| "config-exclude"
|
|
27
|
+
| "untangleignore"
|
|
28
|
+
| "gitignore"
|
|
29
|
+
| "default-exclude"
|
|
30
|
+
| "binary"
|
|
31
|
+
| "size-limit"
|
|
32
|
+
| "symlink-cycle"
|
|
33
|
+
| "symlink-escape"
|
|
34
|
+
| "unreadable";
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* One file discovered and accepted for downstream analysis (spec.md §12.1
|
|
38
|
+
* comparison fields: path, size, mtime as hint, hash as source of truth).
|
|
39
|
+
*/
|
|
40
|
+
export interface ScannedFileV1 {
|
|
41
|
+
/** "/"-normalized path relative to the scanned repository root. */
|
|
42
|
+
relativePath: string;
|
|
43
|
+
/** Absolute path to read content from (post symlink resolution). */
|
|
44
|
+
absolutePath: string;
|
|
45
|
+
sizeBytes: number;
|
|
46
|
+
/** Fast change hint only — never authoritative (spec.md §12.1). */
|
|
47
|
+
mtimeEpochMs: number;
|
|
48
|
+
/** SHA-256 hex of the raw file content; sole "unchanged" authority. */
|
|
49
|
+
contentHash: string;
|
|
50
|
+
languageId: string;
|
|
51
|
+
languageDetectedBy: LanguageDetectionSource;
|
|
52
|
+
isMinified: boolean;
|
|
53
|
+
encoding: TextEncodingGuess;
|
|
54
|
+
hasBom: boolean;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** One path the scanner decided not to yield, with its reason. */
|
|
58
|
+
export interface ScanSkipV1 {
|
|
59
|
+
relativePath: string;
|
|
60
|
+
reason: ExclusionReason;
|
|
61
|
+
detail?: string;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Pluggable content hasher (spec.md §12.1 hash pipeline).
|
|
66
|
+
*
|
|
67
|
+
* `FileSystemPort` (domain) exposes only whole-buffer reads, so the default,
|
|
68
|
+
* port-based implementation cannot avoid materializing a file's bytes. A
|
|
69
|
+
* Node-specific streaming implementation is provided from `./node-fs` for
|
|
70
|
+
* callers that want to hash large files without buffering them fully — see
|
|
71
|
+
* README, "Entscheidungen".
|
|
72
|
+
*/
|
|
73
|
+
export interface ContentHasher {
|
|
74
|
+
hashFile(absolutePath: string, sizeBytes: number, options?: PortCallOptions): Promise<string>;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export interface IgnoreConfig {
|
|
78
|
+
/** RepositoryConfig.include (spec.md §4.3) — overrides default excludes only. */
|
|
79
|
+
configInclude?: readonly string[];
|
|
80
|
+
/** RepositoryConfig.exclude (spec.md §4.3) — layer 2, spec.md §6.2. */
|
|
81
|
+
configExclude?: readonly string[];
|
|
82
|
+
/** File name searched for at every directory level. Default ".untangleignore". */
|
|
83
|
+
untangleIgnoreFileName?: string;
|
|
84
|
+
/** File name searched for at every directory level. Default ".gitignore". */
|
|
85
|
+
gitIgnoreFileName?: string;
|
|
86
|
+
/** Extra patterns appended to the overridable default-exclude layer. */
|
|
87
|
+
additionalDefaultExcludes?: readonly string[];
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export interface IgnoreDecision {
|
|
91
|
+
ignored: boolean;
|
|
92
|
+
reason?: ExclusionReason;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export interface BinaryClassification {
|
|
96
|
+
isBinary: boolean;
|
|
97
|
+
hasNullByte: boolean;
|
|
98
|
+
nonPrintableRatio: number;
|
|
99
|
+
encoding: TextEncodingGuess;
|
|
100
|
+
hasBom: boolean;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export interface ScanOptions {
|
|
104
|
+
fs: FileSystemPort;
|
|
105
|
+
/** Workspace roots for `assertWithinWorkspace` (architecture.md §23.1). */
|
|
106
|
+
roots: readonly string[];
|
|
107
|
+
/** Absolute path to the repository directory to scan. */
|
|
108
|
+
repoRoot: string;
|
|
109
|
+
ignore?: IgnoreConfig;
|
|
110
|
+
/** Reject before a full read via `stat` (spec.md §6.1). Default 5 MiB. */
|
|
111
|
+
maxFileSizeBytes?: number;
|
|
112
|
+
/** Bytes inspected for binary/minified/language-content classification. Default 8 KiB. */
|
|
113
|
+
sampleBytes?: number;
|
|
114
|
+
/** Bounded parallelism for the per-file processing stage. Default 8. */
|
|
115
|
+
concurrency?: number;
|
|
116
|
+
/** Non-printable-byte ratio above which a sample is classified binary. Default 0.3. */
|
|
117
|
+
nonPrintableThreshold?: number;
|
|
118
|
+
hasher?: ContentHasher;
|
|
119
|
+
onSkip?: (skip: ScanSkipV1) => void;
|
|
120
|
+
signal?: AbortSignal;
|
|
121
|
+
}
|