gitx.do 0.0.1 → 0.0.3
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/dist/cli/commands/blame.d.ts +259 -0
- package/dist/cli/commands/blame.d.ts.map +1 -0
- package/dist/cli/commands/blame.js +609 -0
- package/dist/cli/commands/blame.js.map +1 -0
- package/dist/cli/commands/branch.d.ts +249 -0
- package/dist/cli/commands/branch.d.ts.map +1 -0
- package/dist/cli/commands/branch.js +693 -0
- package/dist/cli/commands/branch.js.map +1 -0
- package/dist/cli/commands/commit.d.ts +182 -0
- package/dist/cli/commands/commit.d.ts.map +1 -0
- package/dist/cli/commands/commit.js +437 -0
- package/dist/cli/commands/commit.js.map +1 -0
- package/dist/cli/commands/diff.d.ts +464 -0
- package/dist/cli/commands/diff.d.ts.map +1 -0
- package/dist/cli/commands/diff.js +958 -0
- package/dist/cli/commands/diff.js.map +1 -0
- package/dist/cli/commands/log.d.ts +239 -0
- package/dist/cli/commands/log.d.ts.map +1 -0
- package/dist/cli/commands/log.js +535 -0
- package/dist/cli/commands/log.js.map +1 -0
- package/dist/cli/commands/review.d.ts +457 -0
- package/dist/cli/commands/review.d.ts.map +1 -0
- package/dist/cli/commands/review.js +533 -0
- package/dist/cli/commands/review.js.map +1 -0
- package/dist/cli/commands/status.d.ts +269 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +493 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/web.d.ts +199 -0
- package/dist/cli/commands/web.d.ts.map +1 -0
- package/dist/cli/commands/web.js +696 -0
- package/dist/cli/commands/web.js.map +1 -0
- package/dist/cli/fs-adapter.d.ts +656 -0
- package/dist/cli/fs-adapter.d.ts.map +1 -0
- package/dist/cli/fs-adapter.js +1179 -0
- package/dist/cli/fs-adapter.js.map +1 -0
- package/dist/cli/index.d.ts +387 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +523 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/ui/components/DiffView.d.ts +7 -0
- package/dist/cli/ui/components/DiffView.d.ts.map +1 -0
- package/dist/cli/ui/components/DiffView.js +11 -0
- package/dist/cli/ui/components/DiffView.js.map +1 -0
- package/dist/cli/ui/components/ErrorDisplay.d.ts +6 -0
- package/dist/cli/ui/components/ErrorDisplay.d.ts.map +1 -0
- package/dist/cli/ui/components/ErrorDisplay.js +11 -0
- package/dist/cli/ui/components/ErrorDisplay.js.map +1 -0
- package/dist/cli/ui/components/FuzzySearch.d.ts +9 -0
- package/dist/cli/ui/components/FuzzySearch.d.ts.map +1 -0
- package/dist/cli/ui/components/FuzzySearch.js +12 -0
- package/dist/cli/ui/components/FuzzySearch.js.map +1 -0
- package/dist/cli/ui/components/LoadingSpinner.d.ts +6 -0
- package/dist/cli/ui/components/LoadingSpinner.d.ts.map +1 -0
- package/dist/cli/ui/components/LoadingSpinner.js +10 -0
- package/dist/cli/ui/components/LoadingSpinner.js.map +1 -0
- package/dist/cli/ui/components/NavigationList.d.ts +9 -0
- package/dist/cli/ui/components/NavigationList.d.ts.map +1 -0
- package/dist/cli/ui/components/NavigationList.js +11 -0
- package/dist/cli/ui/components/NavigationList.js.map +1 -0
- package/dist/cli/ui/components/ScrollableContent.d.ts +8 -0
- package/dist/cli/ui/components/ScrollableContent.d.ts.map +1 -0
- package/dist/cli/ui/components/ScrollableContent.js +11 -0
- package/dist/cli/ui/components/ScrollableContent.js.map +1 -0
- package/dist/cli/ui/components/index.d.ts +7 -0
- package/dist/cli/ui/components/index.d.ts.map +1 -0
- package/dist/cli/ui/components/index.js +9 -0
- package/dist/cli/ui/components/index.js.map +1 -0
- package/dist/cli/ui/terminal-ui.d.ts +52 -0
- package/dist/cli/ui/terminal-ui.d.ts.map +1 -0
- package/dist/cli/ui/terminal-ui.js +121 -0
- package/dist/cli/ui/terminal-ui.js.map +1 -0
- package/dist/durable-object/object-store.d.ts +401 -23
- package/dist/durable-object/object-store.d.ts.map +1 -1
- package/dist/durable-object/object-store.js +414 -25
- package/dist/durable-object/object-store.js.map +1 -1
- package/dist/durable-object/schema.d.ts +188 -0
- package/dist/durable-object/schema.d.ts.map +1 -1
- package/dist/durable-object/schema.js +160 -0
- package/dist/durable-object/schema.js.map +1 -1
- package/dist/durable-object/wal.d.ts +336 -31
- package/dist/durable-object/wal.d.ts.map +1 -1
- package/dist/durable-object/wal.js +272 -27
- package/dist/durable-object/wal.js.map +1 -1
- package/dist/index.d.ts +379 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +379 -7
- package/dist/index.js.map +1 -1
- package/dist/mcp/adapter.d.ts +579 -38
- package/dist/mcp/adapter.d.ts.map +1 -1
- package/dist/mcp/adapter.js +426 -33
- package/dist/mcp/adapter.js.map +1 -1
- package/dist/mcp/sandbox.d.ts +532 -29
- package/dist/mcp/sandbox.d.ts.map +1 -1
- package/dist/mcp/sandbox.js +389 -22
- package/dist/mcp/sandbox.js.map +1 -1
- package/dist/mcp/sdk-adapter.d.ts +478 -56
- package/dist/mcp/sdk-adapter.d.ts.map +1 -1
- package/dist/mcp/sdk-adapter.js +346 -44
- package/dist/mcp/sdk-adapter.js.map +1 -1
- package/dist/mcp/tools.d.ts +445 -30
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +363 -33
- package/dist/mcp/tools.js.map +1 -1
- package/dist/ops/blame.d.ts +424 -21
- package/dist/ops/blame.d.ts.map +1 -1
- package/dist/ops/blame.js +303 -20
- package/dist/ops/blame.js.map +1 -1
- package/dist/ops/branch.d.ts +583 -32
- package/dist/ops/branch.d.ts.map +1 -1
- package/dist/ops/branch.js +365 -23
- package/dist/ops/branch.js.map +1 -1
- package/dist/ops/commit-traversal.d.ts +164 -24
- package/dist/ops/commit-traversal.d.ts.map +1 -1
- package/dist/ops/commit-traversal.js +68 -2
- package/dist/ops/commit-traversal.js.map +1 -1
- package/dist/ops/commit.d.ts +387 -53
- package/dist/ops/commit.d.ts.map +1 -1
- package/dist/ops/commit.js +249 -29
- package/dist/ops/commit.js.map +1 -1
- package/dist/ops/merge-base.d.ts +195 -21
- package/dist/ops/merge-base.d.ts.map +1 -1
- package/dist/ops/merge-base.js +122 -12
- package/dist/ops/merge-base.js.map +1 -1
- package/dist/ops/merge.d.ts +600 -130
- package/dist/ops/merge.d.ts.map +1 -1
- package/dist/ops/merge.js +408 -60
- package/dist/ops/merge.js.map +1 -1
- package/dist/ops/tag.d.ts +67 -2
- package/dist/ops/tag.d.ts.map +1 -1
- package/dist/ops/tag.js +42 -1
- package/dist/ops/tag.js.map +1 -1
- package/dist/ops/tree-builder.d.ts +102 -6
- package/dist/ops/tree-builder.d.ts.map +1 -1
- package/dist/ops/tree-builder.js +30 -5
- package/dist/ops/tree-builder.js.map +1 -1
- package/dist/ops/tree-diff.d.ts +50 -2
- package/dist/ops/tree-diff.d.ts.map +1 -1
- package/dist/ops/tree-diff.js +50 -2
- package/dist/ops/tree-diff.js.map +1 -1
- package/dist/pack/delta.d.ts +211 -39
- package/dist/pack/delta.d.ts.map +1 -1
- package/dist/pack/delta.js +232 -46
- package/dist/pack/delta.js.map +1 -1
- package/dist/pack/format.d.ts +390 -28
- package/dist/pack/format.d.ts.map +1 -1
- package/dist/pack/format.js +344 -33
- package/dist/pack/format.js.map +1 -1
- package/dist/pack/full-generation.d.ts +313 -28
- package/dist/pack/full-generation.d.ts.map +1 -1
- package/dist/pack/full-generation.js +238 -19
- package/dist/pack/full-generation.js.map +1 -1
- package/dist/pack/generation.d.ts +346 -23
- package/dist/pack/generation.d.ts.map +1 -1
- package/dist/pack/generation.js +269 -21
- package/dist/pack/generation.js.map +1 -1
- package/dist/pack/index.d.ts +407 -86
- package/dist/pack/index.d.ts.map +1 -1
- package/dist/pack/index.js +351 -70
- package/dist/pack/index.js.map +1 -1
- package/dist/refs/branch.d.ts +517 -71
- package/dist/refs/branch.d.ts.map +1 -1
- package/dist/refs/branch.js +410 -26
- package/dist/refs/branch.js.map +1 -1
- package/dist/refs/storage.d.ts +610 -57
- package/dist/refs/storage.d.ts.map +1 -1
- package/dist/refs/storage.js +481 -29
- package/dist/refs/storage.js.map +1 -1
- package/dist/refs/tag.d.ts +677 -67
- package/dist/refs/tag.d.ts.map +1 -1
- package/dist/refs/tag.js +497 -30
- package/dist/refs/tag.js.map +1 -1
- package/dist/storage/lru-cache.d.ts +556 -53
- package/dist/storage/lru-cache.d.ts.map +1 -1
- package/dist/storage/lru-cache.js +439 -36
- package/dist/storage/lru-cache.js.map +1 -1
- package/dist/storage/object-index.d.ts +483 -38
- package/dist/storage/object-index.d.ts.map +1 -1
- package/dist/storage/object-index.js +388 -22
- package/dist/storage/object-index.js.map +1 -1
- package/dist/storage/r2-pack.d.ts +957 -94
- package/dist/storage/r2-pack.d.ts.map +1 -1
- package/dist/storage/r2-pack.js +756 -48
- package/dist/storage/r2-pack.js.map +1 -1
- package/dist/tiered/cdc-pipeline.d.ts +1610 -38
- package/dist/tiered/cdc-pipeline.d.ts.map +1 -1
- package/dist/tiered/cdc-pipeline.js +1131 -22
- package/dist/tiered/cdc-pipeline.js.map +1 -1
- package/dist/tiered/migration.d.ts +903 -41
- package/dist/tiered/migration.d.ts.map +1 -1
- package/dist/tiered/migration.js +646 -24
- package/dist/tiered/migration.js.map +1 -1
- package/dist/tiered/parquet-writer.d.ts +944 -47
- package/dist/tiered/parquet-writer.d.ts.map +1 -1
- package/dist/tiered/parquet-writer.js +667 -39
- package/dist/tiered/parquet-writer.js.map +1 -1
- package/dist/tiered/read-path.d.ts +728 -34
- package/dist/tiered/read-path.d.ts.map +1 -1
- package/dist/tiered/read-path.js +310 -27
- package/dist/tiered/read-path.js.map +1 -1
- package/dist/types/objects.d.ts +457 -0
- package/dist/types/objects.d.ts.map +1 -1
- package/dist/types/objects.js +305 -4
- package/dist/types/objects.js.map +1 -1
- package/dist/types/storage.d.ts +407 -35
- package/dist/types/storage.d.ts.map +1 -1
- package/dist/types/storage.js +27 -3
- package/dist/types/storage.js.map +1 -1
- package/dist/utils/hash.d.ts +133 -12
- package/dist/utils/hash.d.ts.map +1 -1
- package/dist/utils/hash.js +133 -12
- package/dist/utils/hash.js.map +1 -1
- package/dist/utils/sha1.d.ts +102 -9
- package/dist/utils/sha1.d.ts.map +1 -1
- package/dist/utils/sha1.js +114 -11
- package/dist/utils/sha1.js.map +1 -1
- package/dist/wire/capabilities.d.ts +896 -88
- package/dist/wire/capabilities.d.ts.map +1 -1
- package/dist/wire/capabilities.js +566 -62
- package/dist/wire/capabilities.js.map +1 -1
- package/dist/wire/pkt-line.d.ts +293 -15
- package/dist/wire/pkt-line.d.ts.map +1 -1
- package/dist/wire/pkt-line.js +251 -15
- package/dist/wire/pkt-line.js.map +1 -1
- package/dist/wire/receive-pack.d.ts +814 -64
- package/dist/wire/receive-pack.d.ts.map +1 -1
- package/dist/wire/receive-pack.js +542 -41
- package/dist/wire/receive-pack.js.map +1 -1
- package/dist/wire/smart-http.d.ts +575 -97
- package/dist/wire/smart-http.d.ts.map +1 -1
- package/dist/wire/smart-http.js +337 -46
- package/dist/wire/smart-http.js.map +1 -1
- package/dist/wire/upload-pack.d.ts +492 -98
- package/dist/wire/upload-pack.d.ts.map +1 -1
- package/dist/wire/upload-pack.js +347 -59
- package/dist/wire/upload-pack.js.map +1 -1
- package/package.json +10 -2
package/dist/utils/hash.d.ts
CHANGED
|
@@ -1,31 +1,152 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* SHA
|
|
2
|
+
* @fileoverview SHA Hashing Utilities for Git Objects
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* This module provides cryptographic hashing functions used for Git object
|
|
5
|
+
* identification and verification. Git uses SHA-1 as its primary hash algorithm,
|
|
6
|
+
* with SHA-256 available as an optional newer algorithm (Git v2.29+).
|
|
7
|
+
*
|
|
8
|
+
* The hash functions work with the Web Crypto API for broad compatibility
|
|
9
|
+
* with browsers and edge runtimes like Cloudflare Workers.
|
|
10
|
+
*
|
|
11
|
+
* @module utils/hash
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* import { sha1, hashObject, hexToBytes, bytesToHex } from './utils/hash'
|
|
16
|
+
*
|
|
17
|
+
* // Hash raw data
|
|
18
|
+
* const hash = await sha1('Hello, World!')
|
|
19
|
+
*
|
|
20
|
+
* // Hash as a Git object (includes type header)
|
|
21
|
+
* const content = new TextEncoder().encode('file content')
|
|
22
|
+
* const blobSha = await hashObject('blob', content)
|
|
23
|
+
* console.log(`blob ${blobSha}`)
|
|
24
|
+
* ```
|
|
6
25
|
*/
|
|
7
26
|
/**
|
|
8
|
-
* Compute SHA-1 hash of data
|
|
9
|
-
*
|
|
27
|
+
* Compute the SHA-1 hash of data.
|
|
28
|
+
*
|
|
29
|
+
* @description
|
|
30
|
+
* Computes a SHA-1 digest of the input data using the Web Crypto API.
|
|
31
|
+
* This is the standard hash algorithm used by Git for object identification.
|
|
32
|
+
*
|
|
33
|
+
* **Note**: SHA-1 is considered cryptographically weak. Git uses it for
|
|
34
|
+
* content addressing, not security. For new security-sensitive applications,
|
|
35
|
+
* use SHA-256.
|
|
36
|
+
*
|
|
37
|
+
* @param data - Input data as Uint8Array or string (UTF-8 encoded)
|
|
38
|
+
* @returns 40-character lowercase hexadecimal hash string
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```typescript
|
|
42
|
+
* // Hash a string
|
|
43
|
+
* const hash1 = await sha1('Hello, World!')
|
|
44
|
+
* console.log(hash1) // '0a0a9f2a6772942557ab5355d76af442f8f65e01'
|
|
45
|
+
*
|
|
46
|
+
* // Hash binary data
|
|
47
|
+
* const data = new Uint8Array([0x48, 0x65, 0x6c, 0x6c, 0x6f])
|
|
48
|
+
* const hash2 = await sha1(data)
|
|
49
|
+
* ```
|
|
10
50
|
*/
|
|
11
51
|
export declare function sha1(data: Uint8Array | string): Promise<string>;
|
|
12
52
|
/**
|
|
13
|
-
* Compute SHA-256 hash of data
|
|
14
|
-
*
|
|
53
|
+
* Compute the SHA-256 hash of data.
|
|
54
|
+
*
|
|
55
|
+
* @description
|
|
56
|
+
* Computes a SHA-256 digest of the input data using the Web Crypto API.
|
|
57
|
+
* SHA-256 is the newer, more secure hash algorithm supported by Git v2.29+
|
|
58
|
+
* as an alternative to SHA-1.
|
|
59
|
+
*
|
|
60
|
+
* @param data - Input data as Uint8Array or string (UTF-8 encoded)
|
|
61
|
+
* @returns 64-character lowercase hexadecimal hash string
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```typescript
|
|
65
|
+
* // Hash a string
|
|
66
|
+
* const hash = await sha256('Hello, World!')
|
|
67
|
+
* console.log(hash) // 'dffd6021bb2bd5b0af676290809ec3a53191dd81c7f70a4b28688a362182986f'
|
|
68
|
+
*
|
|
69
|
+
* // Hash binary data
|
|
70
|
+
* const data = new Uint8Array([0x48, 0x65, 0x6c, 0x6c, 0x6f])
|
|
71
|
+
* const hash2 = await sha256(data)
|
|
72
|
+
* ```
|
|
15
73
|
*/
|
|
16
74
|
export declare function sha256(data: Uint8Array | string): Promise<string>;
|
|
17
75
|
/**
|
|
18
|
-
* Hash a
|
|
19
|
-
*
|
|
20
|
-
*
|
|
76
|
+
* Hash a Git object with its type header.
|
|
77
|
+
*
|
|
78
|
+
* @description
|
|
79
|
+
* Computes the SHA-1 hash of a Git object including its header.
|
|
80
|
+
* The header format is: "{type} {size}\0" followed by the content.
|
|
81
|
+
*
|
|
82
|
+
* This matches the output of `git hash-object` command and is the
|
|
83
|
+
* standard way Git computes object identifiers.
|
|
84
|
+
*
|
|
85
|
+
* @param type - Object type ('blob', 'tree', 'commit', 'tag')
|
|
86
|
+
* @param data - Object content as binary data (without header)
|
|
87
|
+
* @returns 40-character lowercase hexadecimal SHA-1 hash
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```typescript
|
|
91
|
+
* // Hash a blob (equivalent to `echo -n "hello" | git hash-object --stdin`)
|
|
92
|
+
* const content = new TextEncoder().encode('hello')
|
|
93
|
+
* const sha = await hashObject('blob', content)
|
|
94
|
+
* console.log(sha) // 'b6fc4c620b67d95f953a5c1c1230aaab5db5a1b0'
|
|
95
|
+
*
|
|
96
|
+
* // Verify with git:
|
|
97
|
+
* // $ echo -n "hello" | git hash-object --stdin
|
|
98
|
+
* // b6fc4c620b67d95f953a5c1c1230aaab5db5a1b0
|
|
99
|
+
* ```
|
|
21
100
|
*/
|
|
22
101
|
export declare function hashObject(type: string, data: Uint8Array): Promise<string>;
|
|
23
102
|
/**
|
|
24
|
-
* Convert
|
|
103
|
+
* Convert a hexadecimal string to a Uint8Array.
|
|
104
|
+
*
|
|
105
|
+
* @description
|
|
106
|
+
* Parses a hexadecimal string and returns the corresponding bytes.
|
|
107
|
+
* Each pair of hex characters becomes one byte.
|
|
108
|
+
*
|
|
109
|
+
* **Edge Cases**:
|
|
110
|
+
* - Empty string returns empty Uint8Array
|
|
111
|
+
* - Hex string should have even length (odd length may produce unexpected results)
|
|
112
|
+
*
|
|
113
|
+
* @param hex - Hexadecimal string (case-insensitive)
|
|
114
|
+
* @returns Binary data as Uint8Array
|
|
115
|
+
*
|
|
116
|
+
* @example
|
|
117
|
+
* ```typescript
|
|
118
|
+
* const bytes = hexToBytes('48656c6c6f')
|
|
119
|
+
* console.log(new TextDecoder().decode(bytes)) // 'Hello'
|
|
120
|
+
*
|
|
121
|
+
* // Convert SHA back to bytes (useful for tree entries)
|
|
122
|
+
* const sha = 'abc123def456...'
|
|
123
|
+
* const sha20 = hexToBytes(sha) // 20 bytes for SHA-1
|
|
124
|
+
* ```
|
|
25
125
|
*/
|
|
26
126
|
export declare function hexToBytes(hex: string): Uint8Array;
|
|
27
127
|
/**
|
|
28
|
-
* Convert Uint8Array to
|
|
128
|
+
* Convert a Uint8Array to a hexadecimal string.
|
|
129
|
+
*
|
|
130
|
+
* @description
|
|
131
|
+
* Converts binary data to a lowercase hexadecimal string representation.
|
|
132
|
+
* Each byte becomes two hex characters (zero-padded).
|
|
133
|
+
*
|
|
134
|
+
* **Edge Cases**:
|
|
135
|
+
* - Empty Uint8Array returns empty string
|
|
136
|
+
*
|
|
137
|
+
* @param bytes - Binary data to convert
|
|
138
|
+
* @returns Lowercase hexadecimal string
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* ```typescript
|
|
142
|
+
* const hello = new TextEncoder().encode('Hello')
|
|
143
|
+
* const hex = bytesToHex(hello)
|
|
144
|
+
* console.log(hex) // '48656c6c6f'
|
|
145
|
+
*
|
|
146
|
+
* // Convert SHA-1 bytes to string
|
|
147
|
+
* const hashBytes = new Uint8Array(20) // ... from crypto
|
|
148
|
+
* const sha = bytesToHex(hashBytes) // 40-char hex string
|
|
149
|
+
* ```
|
|
29
150
|
*/
|
|
30
151
|
export declare function bytesToHex(bytes: Uint8Array): string;
|
|
31
152
|
//# sourceMappingURL=hash.d.ts.map
|
package/dist/utils/hash.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../src/utils/hash.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../src/utils/hash.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAsB,IAAI,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAIrE;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAIvE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAOhF;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAOlD;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAKpD"}
|
package/dist/utils/hash.js
CHANGED
|
@@ -1,12 +1,52 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* SHA
|
|
2
|
+
* @fileoverview SHA Hashing Utilities for Git Objects
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* This module provides cryptographic hashing functions used for Git object
|
|
5
|
+
* identification and verification. Git uses SHA-1 as its primary hash algorithm,
|
|
6
|
+
* with SHA-256 available as an optional newer algorithm (Git v2.29+).
|
|
7
|
+
*
|
|
8
|
+
* The hash functions work with the Web Crypto API for broad compatibility
|
|
9
|
+
* with browsers and edge runtimes like Cloudflare Workers.
|
|
10
|
+
*
|
|
11
|
+
* @module utils/hash
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* import { sha1, hashObject, hexToBytes, bytesToHex } from './utils/hash'
|
|
16
|
+
*
|
|
17
|
+
* // Hash raw data
|
|
18
|
+
* const hash = await sha1('Hello, World!')
|
|
19
|
+
*
|
|
20
|
+
* // Hash as a Git object (includes type header)
|
|
21
|
+
* const content = new TextEncoder().encode('file content')
|
|
22
|
+
* const blobSha = await hashObject('blob', content)
|
|
23
|
+
* console.log(`blob ${blobSha}`)
|
|
24
|
+
* ```
|
|
6
25
|
*/
|
|
7
26
|
/**
|
|
8
|
-
* Compute SHA-1 hash of data
|
|
9
|
-
*
|
|
27
|
+
* Compute the SHA-1 hash of data.
|
|
28
|
+
*
|
|
29
|
+
* @description
|
|
30
|
+
* Computes a SHA-1 digest of the input data using the Web Crypto API.
|
|
31
|
+
* This is the standard hash algorithm used by Git for object identification.
|
|
32
|
+
*
|
|
33
|
+
* **Note**: SHA-1 is considered cryptographically weak. Git uses it for
|
|
34
|
+
* content addressing, not security. For new security-sensitive applications,
|
|
35
|
+
* use SHA-256.
|
|
36
|
+
*
|
|
37
|
+
* @param data - Input data as Uint8Array or string (UTF-8 encoded)
|
|
38
|
+
* @returns 40-character lowercase hexadecimal hash string
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```typescript
|
|
42
|
+
* // Hash a string
|
|
43
|
+
* const hash1 = await sha1('Hello, World!')
|
|
44
|
+
* console.log(hash1) // '0a0a9f2a6772942557ab5355d76af442f8f65e01'
|
|
45
|
+
*
|
|
46
|
+
* // Hash binary data
|
|
47
|
+
* const data = new Uint8Array([0x48, 0x65, 0x6c, 0x6c, 0x6f])
|
|
48
|
+
* const hash2 = await sha1(data)
|
|
49
|
+
* ```
|
|
10
50
|
*/
|
|
11
51
|
export async function sha1(data) {
|
|
12
52
|
const bytes = typeof data === 'string' ? new TextEncoder().encode(data) : data;
|
|
@@ -14,8 +54,26 @@ export async function sha1(data) {
|
|
|
14
54
|
return bytesToHex(new Uint8Array(hashBuffer));
|
|
15
55
|
}
|
|
16
56
|
/**
|
|
17
|
-
* Compute SHA-256 hash of data
|
|
18
|
-
*
|
|
57
|
+
* Compute the SHA-256 hash of data.
|
|
58
|
+
*
|
|
59
|
+
* @description
|
|
60
|
+
* Computes a SHA-256 digest of the input data using the Web Crypto API.
|
|
61
|
+
* SHA-256 is the newer, more secure hash algorithm supported by Git v2.29+
|
|
62
|
+
* as an alternative to SHA-1.
|
|
63
|
+
*
|
|
64
|
+
* @param data - Input data as Uint8Array or string (UTF-8 encoded)
|
|
65
|
+
* @returns 64-character lowercase hexadecimal hash string
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```typescript
|
|
69
|
+
* // Hash a string
|
|
70
|
+
* const hash = await sha256('Hello, World!')
|
|
71
|
+
* console.log(hash) // 'dffd6021bb2bd5b0af676290809ec3a53191dd81c7f70a4b28688a362182986f'
|
|
72
|
+
*
|
|
73
|
+
* // Hash binary data
|
|
74
|
+
* const data = new Uint8Array([0x48, 0x65, 0x6c, 0x6c, 0x6f])
|
|
75
|
+
* const hash2 = await sha256(data)
|
|
76
|
+
* ```
|
|
19
77
|
*/
|
|
20
78
|
export async function sha256(data) {
|
|
21
79
|
const bytes = typeof data === 'string' ? new TextEncoder().encode(data) : data;
|
|
@@ -23,9 +81,30 @@ export async function sha256(data) {
|
|
|
23
81
|
return bytesToHex(new Uint8Array(hashBuffer));
|
|
24
82
|
}
|
|
25
83
|
/**
|
|
26
|
-
* Hash a
|
|
27
|
-
*
|
|
28
|
-
*
|
|
84
|
+
* Hash a Git object with its type header.
|
|
85
|
+
*
|
|
86
|
+
* @description
|
|
87
|
+
* Computes the SHA-1 hash of a Git object including its header.
|
|
88
|
+
* The header format is: "{type} {size}\0" followed by the content.
|
|
89
|
+
*
|
|
90
|
+
* This matches the output of `git hash-object` command and is the
|
|
91
|
+
* standard way Git computes object identifiers.
|
|
92
|
+
*
|
|
93
|
+
* @param type - Object type ('blob', 'tree', 'commit', 'tag')
|
|
94
|
+
* @param data - Object content as binary data (without header)
|
|
95
|
+
* @returns 40-character lowercase hexadecimal SHA-1 hash
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* ```typescript
|
|
99
|
+
* // Hash a blob (equivalent to `echo -n "hello" | git hash-object --stdin`)
|
|
100
|
+
* const content = new TextEncoder().encode('hello')
|
|
101
|
+
* const sha = await hashObject('blob', content)
|
|
102
|
+
* console.log(sha) // 'b6fc4c620b67d95f953a5c1c1230aaab5db5a1b0'
|
|
103
|
+
*
|
|
104
|
+
* // Verify with git:
|
|
105
|
+
* // $ echo -n "hello" | git hash-object --stdin
|
|
106
|
+
* // b6fc4c620b67d95f953a5c1c1230aaab5db5a1b0
|
|
107
|
+
* ```
|
|
29
108
|
*/
|
|
30
109
|
export async function hashObject(type, data) {
|
|
31
110
|
const header = `${type} ${data.length}\0`;
|
|
@@ -36,7 +115,28 @@ export async function hashObject(type, data) {
|
|
|
36
115
|
return sha1(combined);
|
|
37
116
|
}
|
|
38
117
|
/**
|
|
39
|
-
* Convert
|
|
118
|
+
* Convert a hexadecimal string to a Uint8Array.
|
|
119
|
+
*
|
|
120
|
+
* @description
|
|
121
|
+
* Parses a hexadecimal string and returns the corresponding bytes.
|
|
122
|
+
* Each pair of hex characters becomes one byte.
|
|
123
|
+
*
|
|
124
|
+
* **Edge Cases**:
|
|
125
|
+
* - Empty string returns empty Uint8Array
|
|
126
|
+
* - Hex string should have even length (odd length may produce unexpected results)
|
|
127
|
+
*
|
|
128
|
+
* @param hex - Hexadecimal string (case-insensitive)
|
|
129
|
+
* @returns Binary data as Uint8Array
|
|
130
|
+
*
|
|
131
|
+
* @example
|
|
132
|
+
* ```typescript
|
|
133
|
+
* const bytes = hexToBytes('48656c6c6f')
|
|
134
|
+
* console.log(new TextDecoder().decode(bytes)) // 'Hello'
|
|
135
|
+
*
|
|
136
|
+
* // Convert SHA back to bytes (useful for tree entries)
|
|
137
|
+
* const sha = 'abc123def456...'
|
|
138
|
+
* const sha20 = hexToBytes(sha) // 20 bytes for SHA-1
|
|
139
|
+
* ```
|
|
40
140
|
*/
|
|
41
141
|
export function hexToBytes(hex) {
|
|
42
142
|
if (hex.length === 0)
|
|
@@ -48,7 +148,28 @@ export function hexToBytes(hex) {
|
|
|
48
148
|
return bytes;
|
|
49
149
|
}
|
|
50
150
|
/**
|
|
51
|
-
* Convert Uint8Array to
|
|
151
|
+
* Convert a Uint8Array to a hexadecimal string.
|
|
152
|
+
*
|
|
153
|
+
* @description
|
|
154
|
+
* Converts binary data to a lowercase hexadecimal string representation.
|
|
155
|
+
* Each byte becomes two hex characters (zero-padded).
|
|
156
|
+
*
|
|
157
|
+
* **Edge Cases**:
|
|
158
|
+
* - Empty Uint8Array returns empty string
|
|
159
|
+
*
|
|
160
|
+
* @param bytes - Binary data to convert
|
|
161
|
+
* @returns Lowercase hexadecimal string
|
|
162
|
+
*
|
|
163
|
+
* @example
|
|
164
|
+
* ```typescript
|
|
165
|
+
* const hello = new TextEncoder().encode('Hello')
|
|
166
|
+
* const hex = bytesToHex(hello)
|
|
167
|
+
* console.log(hex) // '48656c6c6f'
|
|
168
|
+
*
|
|
169
|
+
* // Convert SHA-1 bytes to string
|
|
170
|
+
* const hashBytes = new Uint8Array(20) // ... from crypto
|
|
171
|
+
* const sha = bytesToHex(hashBytes) // 40-char hex string
|
|
172
|
+
* ```
|
|
52
173
|
*/
|
|
53
174
|
export function bytesToHex(bytes) {
|
|
54
175
|
if (bytes.length === 0)
|
package/dist/utils/hash.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hash.js","sourceRoot":"","sources":["../../src/utils/hash.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"hash.js","sourceRoot":"","sources":["../../src/utils/hash.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,IAAyB;IAClD,MAAM,KAAK,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IAC9E,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;IAC7D,OAAO,UAAU,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC,CAAA;AAC/C,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,IAAyB;IACpD,MAAM,KAAK,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IAC9E,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAAA;IAC/D,OAAO,UAAU,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC,CAAA;AAC/C,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAY,EAAE,IAAgB;IAC7D,MAAM,MAAM,GAAG,GAAG,IAAI,IAAI,IAAI,CAAC,MAAM,IAAI,CAAA;IACzC,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IACpD,MAAM,QAAQ,GAAG,IAAI,UAAU,CAAC,WAAW,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAA;IACjE,QAAQ,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAA;IAC5B,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IACtC,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAA;AACvB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,UAAU,CAAC,CAAC,CAAC,CAAA;IAC9C,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;IAClD,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,UAAU,CAAC,KAAiB;IAC1C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAA;IACjC,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;SACrB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;SACzC,IAAI,CAAC,EAAE,CAAC,CAAA;AACb,CAAC"}
|
package/dist/utils/sha1.d.ts
CHANGED
|
@@ -1,26 +1,119 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Synchronous SHA-1
|
|
2
|
+
* @fileoverview Synchronous SHA-1 Utilities for Git Pack Operations
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* generation
|
|
4
|
+
* This module provides synchronous (non-async) SHA-1 hashing needed for pack file
|
|
5
|
+
* generation, verification, and streaming operations where async is impractical.
|
|
6
|
+
*
|
|
7
|
+
* The implementation follows the SHA-1 specification (FIPS 180-4) and processes
|
|
8
|
+
* data in 512-bit (64-byte) chunks using the standard compression function.
|
|
9
|
+
*
|
|
10
|
+
* **When to use this vs hash.ts**:
|
|
11
|
+
* - Use `utils/hash.ts` for general async hashing (uses Web Crypto API)
|
|
12
|
+
* - Use this module for pack operations that need synchronous hashing
|
|
13
|
+
*
|
|
14
|
+
* @module utils/sha1
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* import { sha1, sha1Hex, sha1Verify } from './utils/sha1'
|
|
19
|
+
*
|
|
20
|
+
* // Compute SHA-1 as bytes
|
|
21
|
+
* const data = new TextEncoder().encode('Hello, World!')
|
|
22
|
+
* const hashBytes = sha1(data) // 20-byte Uint8Array
|
|
23
|
+
*
|
|
24
|
+
* // Compute SHA-1 as hex string
|
|
25
|
+
* const hashHex = sha1Hex(data) // 40-char string
|
|
26
|
+
*
|
|
27
|
+
* // Verify data against expected hash
|
|
28
|
+
* const isValid = sha1Verify(data, expectedHash)
|
|
29
|
+
* ```
|
|
6
30
|
*/
|
|
7
31
|
/**
|
|
8
|
-
* Compute SHA-1 hash of data synchronously
|
|
32
|
+
* Compute SHA-1 hash of data synchronously.
|
|
33
|
+
*
|
|
34
|
+
* @description
|
|
35
|
+
* Implements the SHA-1 algorithm per FIPS 180-4. This pure JavaScript
|
|
36
|
+
* implementation is used when synchronous hashing is needed, such as
|
|
37
|
+
* in pack file generation or streaming operations.
|
|
38
|
+
*
|
|
39
|
+
* **Algorithm Details**:
|
|
40
|
+
* 1. Pad message to 512-bit boundary (with 1-bit, zeros, and 64-bit length)
|
|
41
|
+
* 2. Process in 64-byte chunks using 80-round compression function
|
|
42
|
+
* 3. Return final 160-bit (20-byte) hash
|
|
43
|
+
*
|
|
44
|
+
* **Performance Note**: This is slower than Web Crypto API. Use `hash.ts`
|
|
45
|
+
* for async operations where performance is critical.
|
|
46
|
+
*
|
|
9
47
|
* @param data - Input data to hash
|
|
10
48
|
* @returns 20-byte hash as Uint8Array
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* const data = new TextEncoder().encode('test')
|
|
53
|
+
* const hash = sha1(data)
|
|
54
|
+
* console.log(hash.length) // 20
|
|
55
|
+
*
|
|
56
|
+
* // Use with pack file verification
|
|
57
|
+
* const packData = readPackFile()
|
|
58
|
+
* const computedHash = sha1(packData.slice(0, -20))
|
|
59
|
+
* ```
|
|
11
60
|
*/
|
|
12
61
|
export declare function sha1(data: Uint8Array): Uint8Array;
|
|
13
62
|
/**
|
|
14
|
-
* Compute SHA-1 hash and return as
|
|
63
|
+
* Compute SHA-1 hash and return as hexadecimal string.
|
|
64
|
+
*
|
|
65
|
+
* @description
|
|
66
|
+
* Convenience wrapper that computes SHA-1 and converts the result
|
|
67
|
+
* to a lowercase hexadecimal string. Equivalent to calling `sha1()`
|
|
68
|
+
* followed by hex conversion.
|
|
69
|
+
*
|
|
15
70
|
* @param data - Input data to hash
|
|
16
|
-
* @returns 40-character lowercase
|
|
71
|
+
* @returns 40-character lowercase hexadecimal hash string
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```typescript
|
|
75
|
+
* const data = new TextEncoder().encode('hello')
|
|
76
|
+
* const hex = sha1Hex(data)
|
|
77
|
+
* console.log(hex) // 'aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d'
|
|
78
|
+
*
|
|
79
|
+
* // Compare with git:
|
|
80
|
+
* // $ echo -n "hello" | sha1sum
|
|
81
|
+
* // aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
|
|
82
|
+
* ```
|
|
17
83
|
*/
|
|
18
84
|
export declare function sha1Hex(data: Uint8Array): string;
|
|
19
85
|
/**
|
|
20
|
-
* Verify data against expected SHA-1 hash
|
|
86
|
+
* Verify data against an expected SHA-1 hash.
|
|
87
|
+
*
|
|
88
|
+
* @description
|
|
89
|
+
* Computes the SHA-1 hash of the data and compares it byte-by-byte
|
|
90
|
+
* with the expected hash. Returns true only if all 20 bytes match.
|
|
91
|
+
*
|
|
92
|
+
* This uses constant-time comparison to avoid timing attacks,
|
|
93
|
+
* though SHA-1 is not used for security purposes in Git.
|
|
94
|
+
*
|
|
21
95
|
* @param data - Data to verify
|
|
22
|
-
* @param expected - Expected 20-byte hash
|
|
23
|
-
* @returns
|
|
96
|
+
* @param expected - Expected 20-byte SHA-1 hash
|
|
97
|
+
* @returns True if the computed hash matches the expected hash
|
|
98
|
+
* @throws Never throws - returns false for invalid inputs
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```typescript
|
|
102
|
+
* // Verify pack file integrity
|
|
103
|
+
* const packContent = readPackFile()
|
|
104
|
+
* const contentWithoutChecksum = packContent.slice(0, -20)
|
|
105
|
+
* const expectedChecksum = packContent.slice(-20)
|
|
106
|
+
*
|
|
107
|
+
* if (sha1Verify(contentWithoutChecksum, expectedChecksum)) {
|
|
108
|
+
* console.log('Pack file integrity verified')
|
|
109
|
+
* } else {
|
|
110
|
+
* console.log('Pack file corrupted!')
|
|
111
|
+
* }
|
|
112
|
+
*
|
|
113
|
+
* // Invalid expected hash length
|
|
114
|
+
* const badHash = new Uint8Array(10)
|
|
115
|
+
* sha1Verify(data, badHash) // false (wrong length)
|
|
116
|
+
* ```
|
|
24
117
|
*/
|
|
25
118
|
export declare function sha1Verify(data: Uint8Array, expected: Uint8Array): boolean;
|
|
26
119
|
//# sourceMappingURL=sha1.d.ts.map
|
package/dist/utils/sha1.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sha1.d.ts","sourceRoot":"","sources":["../../src/utils/sha1.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"sha1.d.ts","sourceRoot":"","sources":["../../src/utils/sha1.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,IAAI,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAwGjD;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAOhD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,GAAG,OAAO,CAgB1E"}
|
package/dist/utils/sha1.js
CHANGED
|
@@ -1,19 +1,72 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Synchronous SHA-1
|
|
2
|
+
* @fileoverview Synchronous SHA-1 Utilities for Git Pack Operations
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* generation
|
|
4
|
+
* This module provides synchronous (non-async) SHA-1 hashing needed for pack file
|
|
5
|
+
* generation, verification, and streaming operations where async is impractical.
|
|
6
|
+
*
|
|
7
|
+
* The implementation follows the SHA-1 specification (FIPS 180-4) and processes
|
|
8
|
+
* data in 512-bit (64-byte) chunks using the standard compression function.
|
|
9
|
+
*
|
|
10
|
+
* **When to use this vs hash.ts**:
|
|
11
|
+
* - Use `utils/hash.ts` for general async hashing (uses Web Crypto API)
|
|
12
|
+
* - Use this module for pack operations that need synchronous hashing
|
|
13
|
+
*
|
|
14
|
+
* @module utils/sha1
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* import { sha1, sha1Hex, sha1Verify } from './utils/sha1'
|
|
19
|
+
*
|
|
20
|
+
* // Compute SHA-1 as bytes
|
|
21
|
+
* const data = new TextEncoder().encode('Hello, World!')
|
|
22
|
+
* const hashBytes = sha1(data) // 20-byte Uint8Array
|
|
23
|
+
*
|
|
24
|
+
* // Compute SHA-1 as hex string
|
|
25
|
+
* const hashHex = sha1Hex(data) // 40-char string
|
|
26
|
+
*
|
|
27
|
+
* // Verify data against expected hash
|
|
28
|
+
* const isValid = sha1Verify(data, expectedHash)
|
|
29
|
+
* ```
|
|
6
30
|
*/
|
|
7
31
|
/**
|
|
8
|
-
* Compute SHA-1 hash of data synchronously
|
|
32
|
+
* Compute SHA-1 hash of data synchronously.
|
|
33
|
+
*
|
|
34
|
+
* @description
|
|
35
|
+
* Implements the SHA-1 algorithm per FIPS 180-4. This pure JavaScript
|
|
36
|
+
* implementation is used when synchronous hashing is needed, such as
|
|
37
|
+
* in pack file generation or streaming operations.
|
|
38
|
+
*
|
|
39
|
+
* **Algorithm Details**:
|
|
40
|
+
* 1. Pad message to 512-bit boundary (with 1-bit, zeros, and 64-bit length)
|
|
41
|
+
* 2. Process in 64-byte chunks using 80-round compression function
|
|
42
|
+
* 3. Return final 160-bit (20-byte) hash
|
|
43
|
+
*
|
|
44
|
+
* **Performance Note**: This is slower than Web Crypto API. Use `hash.ts`
|
|
45
|
+
* for async operations where performance is critical.
|
|
46
|
+
*
|
|
9
47
|
* @param data - Input data to hash
|
|
10
48
|
* @returns 20-byte hash as Uint8Array
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* const data = new TextEncoder().encode('test')
|
|
53
|
+
* const hash = sha1(data)
|
|
54
|
+
* console.log(hash.length) // 20
|
|
55
|
+
*
|
|
56
|
+
* // Use with pack file verification
|
|
57
|
+
* const packData = readPackFile()
|
|
58
|
+
* const computedHash = sha1(packData.slice(0, -20))
|
|
59
|
+
* ```
|
|
11
60
|
*/
|
|
12
61
|
export function sha1(data) {
|
|
62
|
+
/**
|
|
63
|
+
* Rotate left (circular left shift) operation.
|
|
64
|
+
* @internal
|
|
65
|
+
*/
|
|
13
66
|
function rotl(n, s) {
|
|
14
67
|
return ((n << s) | (n >>> (32 - s))) >>> 0;
|
|
15
68
|
}
|
|
16
|
-
// Initialize hash values
|
|
69
|
+
// Initialize hash values (first 32 bits of fractional parts of square roots of first 5 primes)
|
|
17
70
|
let h0 = 0x67452301;
|
|
18
71
|
let h1 = 0xefcdab89;
|
|
19
72
|
let h2 = 0x98badcfe;
|
|
@@ -50,22 +103,26 @@ export function sha1(data) {
|
|
|
50
103
|
let c = h2;
|
|
51
104
|
let d = h3;
|
|
52
105
|
let e = h4;
|
|
53
|
-
// Main loop
|
|
106
|
+
// Main loop - 80 rounds
|
|
54
107
|
for (let i = 0; i < 80; i++) {
|
|
55
108
|
let f, k;
|
|
56
109
|
if (i < 20) {
|
|
110
|
+
// Round 0-19: Ch(b,c,d) = (b AND c) XOR (NOT b AND d)
|
|
57
111
|
f = (b & c) | (~b & d);
|
|
58
112
|
k = 0x5a827999;
|
|
59
113
|
}
|
|
60
114
|
else if (i < 40) {
|
|
115
|
+
// Round 20-39: Parity(b,c,d) = b XOR c XOR d
|
|
61
116
|
f = b ^ c ^ d;
|
|
62
117
|
k = 0x6ed9eba1;
|
|
63
118
|
}
|
|
64
119
|
else if (i < 60) {
|
|
120
|
+
// Round 40-59: Maj(b,c,d) = (b AND c) XOR (b AND d) XOR (c AND d)
|
|
65
121
|
f = (b & c) | (b & d) | (c & d);
|
|
66
122
|
k = 0x8f1bbcdc;
|
|
67
123
|
}
|
|
68
124
|
else {
|
|
125
|
+
// Round 60-79: Parity(b,c,d) = b XOR c XOR d
|
|
69
126
|
f = b ^ c ^ d;
|
|
70
127
|
k = 0xca62c1d6;
|
|
71
128
|
}
|
|
@@ -94,9 +151,26 @@ export function sha1(data) {
|
|
|
94
151
|
return result;
|
|
95
152
|
}
|
|
96
153
|
/**
|
|
97
|
-
* Compute SHA-1 hash and return as
|
|
154
|
+
* Compute SHA-1 hash and return as hexadecimal string.
|
|
155
|
+
*
|
|
156
|
+
* @description
|
|
157
|
+
* Convenience wrapper that computes SHA-1 and converts the result
|
|
158
|
+
* to a lowercase hexadecimal string. Equivalent to calling `sha1()`
|
|
159
|
+
* followed by hex conversion.
|
|
160
|
+
*
|
|
98
161
|
* @param data - Input data to hash
|
|
99
|
-
* @returns 40-character lowercase
|
|
162
|
+
* @returns 40-character lowercase hexadecimal hash string
|
|
163
|
+
*
|
|
164
|
+
* @example
|
|
165
|
+
* ```typescript
|
|
166
|
+
* const data = new TextEncoder().encode('hello')
|
|
167
|
+
* const hex = sha1Hex(data)
|
|
168
|
+
* console.log(hex) // 'aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d'
|
|
169
|
+
*
|
|
170
|
+
* // Compare with git:
|
|
171
|
+
* // $ echo -n "hello" | sha1sum
|
|
172
|
+
* // aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
|
|
173
|
+
* ```
|
|
100
174
|
*/
|
|
101
175
|
export function sha1Hex(data) {
|
|
102
176
|
const hash = sha1(data);
|
|
@@ -107,16 +181,45 @@ export function sha1Hex(data) {
|
|
|
107
181
|
return hex;
|
|
108
182
|
}
|
|
109
183
|
/**
|
|
110
|
-
* Verify data against expected SHA-1 hash
|
|
184
|
+
* Verify data against an expected SHA-1 hash.
|
|
185
|
+
*
|
|
186
|
+
* @description
|
|
187
|
+
* Computes the SHA-1 hash of the data and compares it byte-by-byte
|
|
188
|
+
* with the expected hash. Returns true only if all 20 bytes match.
|
|
189
|
+
*
|
|
190
|
+
* This uses constant-time comparison to avoid timing attacks,
|
|
191
|
+
* though SHA-1 is not used for security purposes in Git.
|
|
192
|
+
*
|
|
111
193
|
* @param data - Data to verify
|
|
112
|
-
* @param expected - Expected 20-byte hash
|
|
113
|
-
* @returns
|
|
194
|
+
* @param expected - Expected 20-byte SHA-1 hash
|
|
195
|
+
* @returns True if the computed hash matches the expected hash
|
|
196
|
+
* @throws Never throws - returns false for invalid inputs
|
|
197
|
+
*
|
|
198
|
+
* @example
|
|
199
|
+
* ```typescript
|
|
200
|
+
* // Verify pack file integrity
|
|
201
|
+
* const packContent = readPackFile()
|
|
202
|
+
* const contentWithoutChecksum = packContent.slice(0, -20)
|
|
203
|
+
* const expectedChecksum = packContent.slice(-20)
|
|
204
|
+
*
|
|
205
|
+
* if (sha1Verify(contentWithoutChecksum, expectedChecksum)) {
|
|
206
|
+
* console.log('Pack file integrity verified')
|
|
207
|
+
* } else {
|
|
208
|
+
* console.log('Pack file corrupted!')
|
|
209
|
+
* }
|
|
210
|
+
*
|
|
211
|
+
* // Invalid expected hash length
|
|
212
|
+
* const badHash = new Uint8Array(10)
|
|
213
|
+
* sha1Verify(data, badHash) // false (wrong length)
|
|
214
|
+
* ```
|
|
114
215
|
*/
|
|
115
216
|
export function sha1Verify(data, expected) {
|
|
217
|
+
// Expected hash must be exactly 20 bytes
|
|
116
218
|
if (expected.length !== 20) {
|
|
117
219
|
return false;
|
|
118
220
|
}
|
|
119
221
|
const computed = sha1(data);
|
|
222
|
+
// Compare all 20 bytes
|
|
120
223
|
for (let i = 0; i < 20; i++) {
|
|
121
224
|
if (computed[i] !== expected[i]) {
|
|
122
225
|
return false;
|