@tracehound/core 1.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.
- package/README.md +125 -0
- package/dist/core/agent.d.ts +89 -0
- package/dist/core/agent.d.ts.map +1 -0
- package/dist/core/agent.js +141 -0
- package/dist/core/agent.js.map +1 -0
- package/dist/core/audit-chain.d.ts +39 -0
- package/dist/core/audit-chain.d.ts.map +1 -0
- package/dist/core/audit-chain.js +87 -0
- package/dist/core/audit-chain.js.map +1 -0
- package/dist/core/cold-storage.d.ts +87 -0
- package/dist/core/cold-storage.d.ts.map +1 -0
- package/dist/core/cold-storage.js +53 -0
- package/dist/core/cold-storage.js.map +1 -0
- package/dist/core/evidence-factory.d.ts +85 -0
- package/dist/core/evidence-factory.d.ts.map +1 -0
- package/dist/core/evidence-factory.js +96 -0
- package/dist/core/evidence-factory.js.map +1 -0
- package/dist/core/evidence.d.ts +48 -0
- package/dist/core/evidence.d.ts.map +1 -0
- package/dist/core/evidence.js +135 -0
- package/dist/core/evidence.js.map +1 -0
- package/dist/core/fail-safe.d.ts +149 -0
- package/dist/core/fail-safe.d.ts.map +1 -0
- package/dist/core/fail-safe.js +217 -0
- package/dist/core/fail-safe.js.map +1 -0
- package/dist/core/hound-ipc.d.ts +91 -0
- package/dist/core/hound-ipc.d.ts.map +1 -0
- package/dist/core/hound-ipc.js +196 -0
- package/dist/core/hound-ipc.js.map +1 -0
- package/dist/core/hound-pool.d.ts +157 -0
- package/dist/core/hound-pool.d.ts.map +1 -0
- package/dist/core/hound-pool.js +337 -0
- package/dist/core/hound-pool.js.map +1 -0
- package/dist/core/hound-process.d.ts +14 -0
- package/dist/core/hound-process.d.ts.map +1 -0
- package/dist/core/hound-process.js +112 -0
- package/dist/core/hound-process.js.map +1 -0
- package/dist/core/hound-worker.d.ts +14 -0
- package/dist/core/hound-worker.d.ts.map +1 -0
- package/dist/core/hound-worker.js +112 -0
- package/dist/core/hound-worker.js.map +1 -0
- package/dist/core/lane-queue.d.ts +121 -0
- package/dist/core/lane-queue.d.ts.map +1 -0
- package/dist/core/lane-queue.js +181 -0
- package/dist/core/lane-queue.js.map +1 -0
- package/dist/core/license-manager.d.ts +128 -0
- package/dist/core/license-manager.d.ts.map +1 -0
- package/dist/core/license-manager.js +219 -0
- package/dist/core/license-manager.js.map +1 -0
- package/dist/core/notification-emitter.d.ts +140 -0
- package/dist/core/notification-emitter.d.ts.map +1 -0
- package/dist/core/notification-emitter.js +197 -0
- package/dist/core/notification-emitter.js.map +1 -0
- package/dist/core/process-adapter.d.ts +146 -0
- package/dist/core/process-adapter.d.ts.map +1 -0
- package/dist/core/process-adapter.js +174 -0
- package/dist/core/process-adapter.js.map +1 -0
- package/dist/core/quarantine.d.ts +95 -0
- package/dist/core/quarantine.d.ts.map +1 -0
- package/dist/core/quarantine.js +221 -0
- package/dist/core/quarantine.js.map +1 -0
- package/dist/core/rate-limiter.d.ts +94 -0
- package/dist/core/rate-limiter.d.ts.map +1 -0
- package/dist/core/rate-limiter.js +156 -0
- package/dist/core/rate-limiter.js.map +1 -0
- package/dist/core/s3-cold-storage.d.ts +116 -0
- package/dist/core/s3-cold-storage.d.ts.map +1 -0
- package/dist/core/s3-cold-storage.js +198 -0
- package/dist/core/s3-cold-storage.js.map +1 -0
- package/dist/core/scheduler.d.ts +126 -0
- package/dist/core/scheduler.d.ts.map +1 -0
- package/dist/core/scheduler.js +138 -0
- package/dist/core/scheduler.js.map +1 -0
- package/dist/core/security-state.d.ts +170 -0
- package/dist/core/security-state.d.ts.map +1 -0
- package/dist/core/security-state.js +156 -0
- package/dist/core/security-state.js.map +1 -0
- package/dist/core/tier-capacity.d.ts +58 -0
- package/dist/core/tier-capacity.d.ts.map +1 -0
- package/dist/core/tier-capacity.js +89 -0
- package/dist/core/tier-capacity.js.map +1 -0
- package/dist/core/tracehound.d.ts +85 -0
- package/dist/core/tracehound.d.ts.map +1 -0
- package/dist/core/tracehound.js +90 -0
- package/dist/core/tracehound.js.map +1 -0
- package/dist/core/trust-boundary.d.ts +85 -0
- package/dist/core/trust-boundary.d.ts.map +1 -0
- package/dist/core/trust-boundary.js +71 -0
- package/dist/core/trust-boundary.js.map +1 -0
- package/dist/core/watcher.d.ts +153 -0
- package/dist/core/watcher.d.ts.map +1 -0
- package/dist/core/watcher.js +141 -0
- package/dist/core/watcher.js.map +1 -0
- package/dist/index.d.ts +53 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +112 -0
- package/dist/index.js.map +1 -0
- package/dist/types/audit.d.ts +45 -0
- package/dist/types/audit.d.ts.map +1 -0
- package/dist/types/audit.js +5 -0
- package/dist/types/audit.js.map +1 -0
- package/dist/types/common.d.ts +12 -0
- package/dist/types/common.d.ts.map +1 -0
- package/dist/types/common.js +5 -0
- package/dist/types/common.js.map +1 -0
- package/dist/types/config.d.ts +98 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +58 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/errors.d.ts +118 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +266 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/evidence.d.ts +102 -0
- package/dist/types/evidence.d.ts.map +1 -0
- package/dist/types/evidence.js +5 -0
- package/dist/types/evidence.js.map +1 -0
- package/dist/types/index.d.ts +18 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +9 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/result.d.ts +62 -0
- package/dist/types/result.d.ts.map +1 -0
- package/dist/types/result.js +34 -0
- package/dist/types/result.js.map +1 -0
- package/dist/types/scent.d.ts +55 -0
- package/dist/types/scent.d.ts.map +1 -0
- package/dist/types/scent.js +5 -0
- package/dist/types/scent.js.map +1 -0
- package/dist/types/signature.d.ts +47 -0
- package/dist/types/signature.d.ts.map +1 -0
- package/dist/types/signature.js +68 -0
- package/dist/types/signature.js.map +1 -0
- package/dist/types/threat.d.ts +38 -0
- package/dist/types/threat.d.ts.map +1 -0
- package/dist/types/threat.js +18 -0
- package/dist/types/threat.js.map +1 -0
- package/dist/utils/binary-codec.d.ts +225 -0
- package/dist/utils/binary-codec.d.ts.map +1 -0
- package/dist/utils/binary-codec.js +266 -0
- package/dist/utils/binary-codec.js.map +1 -0
- package/dist/utils/compare.d.ts +26 -0
- package/dist/utils/compare.d.ts.map +1 -0
- package/dist/utils/compare.js +44 -0
- package/dist/utils/compare.js.map +1 -0
- package/dist/utils/encode.d.ts +39 -0
- package/dist/utils/encode.d.ts.map +1 -0
- package/dist/utils/encode.js +124 -0
- package/dist/utils/encode.js.map +1 -0
- package/dist/utils/hash.d.ts +19 -0
- package/dist/utils/hash.d.ts.map +1 -0
- package/dist/utils/hash.js +25 -0
- package/dist/utils/hash.js.map +1 -0
- package/dist/utils/id.d.ts +20 -0
- package/dist/utils/id.d.ts.map +1 -0
- package/dist/utils/id.js +47 -0
- package/dist/utils/id.js.map +1 -0
- package/dist/utils/runtime.d.ts +24 -0
- package/dist/utils/runtime.d.ts.map +1 -0
- package/dist/utils/runtime.js +68 -0
- package/dist/utils/runtime.js.map +1 -0
- package/dist/utils/serialize.d.ts +14 -0
- package/dist/utils/serialize.d.ts.map +1 -0
- package/dist/utils/serialize.js +27 -0
- package/dist/utils/serialize.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"binary-codec.js","sourceRoot":"","sources":["../../src/utils/binary-codec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constant-time comparison utilities.
|
|
3
|
+
* Prevents timing attacks on cryptographic comparisons (CWE-208).
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Perform constant-time string comparison.
|
|
7
|
+
* Uses Node.js crypto.timingSafeEqual internally.
|
|
8
|
+
*
|
|
9
|
+
* IMPORTANT: This MUST be used for all signature/hash comparisons
|
|
10
|
+
* to prevent timing attacks where attackers can statistically
|
|
11
|
+
* analyze response times to guess valid signatures.
|
|
12
|
+
*
|
|
13
|
+
* @param a - First string
|
|
14
|
+
* @param b - Second string
|
|
15
|
+
* @returns True if strings are equal
|
|
16
|
+
*/
|
|
17
|
+
export declare function constantTimeEqual(a: string, b: string): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Perform constant-time buffer comparison.
|
|
20
|
+
*
|
|
21
|
+
* @param a - First buffer
|
|
22
|
+
* @param b - Second buffer
|
|
23
|
+
* @returns True if buffers are equal
|
|
24
|
+
*/
|
|
25
|
+
export declare function constantTimeBufferEqual(a: ArrayBuffer | Uint8Array, b: ArrayBuffer | Uint8Array): boolean;
|
|
26
|
+
//# sourceMappingURL=compare.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compare.d.ts","sourceRoot":"","sources":["../../src/utils/compare.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAY/D;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,CAAC,EAAE,WAAW,GAAG,UAAU,EAC3B,CAAC,EAAE,WAAW,GAAG,UAAU,GAC1B,OAAO,CAST"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constant-time comparison utilities.
|
|
3
|
+
* Prevents timing attacks on cryptographic comparisons (CWE-208).
|
|
4
|
+
*/
|
|
5
|
+
import { timingSafeEqual } from 'node:crypto';
|
|
6
|
+
/**
|
|
7
|
+
* Perform constant-time string comparison.
|
|
8
|
+
* Uses Node.js crypto.timingSafeEqual internally.
|
|
9
|
+
*
|
|
10
|
+
* IMPORTANT: This MUST be used for all signature/hash comparisons
|
|
11
|
+
* to prevent timing attacks where attackers can statistically
|
|
12
|
+
* analyze response times to guess valid signatures.
|
|
13
|
+
*
|
|
14
|
+
* @param a - First string
|
|
15
|
+
* @param b - Second string
|
|
16
|
+
* @returns True if strings are equal
|
|
17
|
+
*/
|
|
18
|
+
export function constantTimeEqual(a, b) {
|
|
19
|
+
// Fast path: different lengths are not equal
|
|
20
|
+
// Length comparison is safe - attacker already knows lengths
|
|
21
|
+
if (a.length !== b.length) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
// Convert to buffers for timing-safe comparison
|
|
25
|
+
const aBuf = Buffer.from(a, 'utf8');
|
|
26
|
+
const bBuf = Buffer.from(b, 'utf8');
|
|
27
|
+
return timingSafeEqual(aBuf, bBuf);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Perform constant-time buffer comparison.
|
|
31
|
+
*
|
|
32
|
+
* @param a - First buffer
|
|
33
|
+
* @param b - Second buffer
|
|
34
|
+
* @returns True if buffers are equal
|
|
35
|
+
*/
|
|
36
|
+
export function constantTimeBufferEqual(a, b) {
|
|
37
|
+
const aBuf = a instanceof Uint8Array ? a : new Uint8Array(a);
|
|
38
|
+
const bBuf = b instanceof Uint8Array ? b : new Uint8Array(b);
|
|
39
|
+
if (aBuf.length !== bBuf.length) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
return timingSafeEqual(aBuf, bBuf);
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=compare.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compare.js","sourceRoot":"","sources":["../../src/utils/compare.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAE7C;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,iBAAiB,CAAC,CAAS,EAAE,CAAS;IACpD,6CAA6C;IAC7C,6DAA6D;IAC7D,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAA;IACd,CAAC;IAED,gDAAgD;IAChD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAA;IACnC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAA;IAEnC,OAAO,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;AACpC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,uBAAuB,CACrC,CAA2B,EAC3B,CAA2B;IAE3B,MAAM,IAAI,GAAG,CAAC,YAAY,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,CAAA;IAC5D,MAAM,IAAI,GAAG,CAAC,YAAY,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,CAAA;IAE5D,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;QAChC,OAAO,KAAK,CAAA;IACd,CAAC;IAED,OAAO,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;AACpC,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Payload encoding with size-first validation.
|
|
3
|
+
*
|
|
4
|
+
* SECURITY INVARIANT: Size check MUST happen BEFORE serialization
|
|
5
|
+
* to prevent memory exhaustion attacks via large payloads.
|
|
6
|
+
*/
|
|
7
|
+
import type { JsonSerializable } from '../types/common.js';
|
|
8
|
+
/** Result of payload encoding */
|
|
9
|
+
export interface EncodeResult {
|
|
10
|
+
/** UTF-8 encoded bytes */
|
|
11
|
+
bytes: Uint8Array;
|
|
12
|
+
/** Size in bytes */
|
|
13
|
+
size: number;
|
|
14
|
+
/** Canonical JSON string (for debugging only) */
|
|
15
|
+
canonical: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Encode payload to UTF-8 bytes with size-first validation.
|
|
19
|
+
*
|
|
20
|
+
* SECURITY: This function enforces the following invariants:
|
|
21
|
+
* 1. Payload structure is validated for edge cases
|
|
22
|
+
* 2. Size is checked AFTER encoding (actual byte size)
|
|
23
|
+
* 3. Returns bytes for direct use in signature hashing
|
|
24
|
+
*
|
|
25
|
+
* @param payload - JSON-serializable payload
|
|
26
|
+
* @param maxSize - Maximum allowed size in bytes
|
|
27
|
+
* @returns Encoded bytes and metadata
|
|
28
|
+
* @throws TracehoundError if validation fails
|
|
29
|
+
*/
|
|
30
|
+
export declare function encodePayload(payload: JsonSerializable, maxSize: number): EncodeResult;
|
|
31
|
+
/**
|
|
32
|
+
* Quick size estimate without full encoding.
|
|
33
|
+
* Use for early rejection before detailed validation.
|
|
34
|
+
*
|
|
35
|
+
* NOTE: This is a conservative estimate. Actual UTF-8 size
|
|
36
|
+
* may be larger for non-ASCII characters.
|
|
37
|
+
*/
|
|
38
|
+
export declare function estimatePayloadSize(payload: JsonSerializable): number;
|
|
39
|
+
//# sourceMappingURL=encode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encode.d.ts","sourceRoot":"","sources":["../../src/utils/encode.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAM1D,iCAAiC;AACjC,MAAM,WAAW,YAAY;IAC3B,0BAA0B;IAC1B,KAAK,EAAE,UAAU,CAAA;IACjB,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,iDAAiD;IACjD,SAAS,EAAE,MAAM,CAAA;CAClB;AAmFD;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,GAAG,YAAY,CAqBtF;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,CAMrE"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Payload encoding with size-first validation.
|
|
3
|
+
*
|
|
4
|
+
* SECURITY INVARIANT: Size check MUST happen BEFORE serialization
|
|
5
|
+
* to prevent memory exhaustion attacks via large payloads.
|
|
6
|
+
*/
|
|
7
|
+
import { Errors } from '../types/errors.js';
|
|
8
|
+
const MAX_NESTING_DEPTH = 32;
|
|
9
|
+
const MAX_OBJECT_KEYS = 1000;
|
|
10
|
+
/**
|
|
11
|
+
* Validate payload structure for edge cases that could cause
|
|
12
|
+
* signature collisions or unexpected behavior.
|
|
13
|
+
*
|
|
14
|
+
* @throws TracehoundError if payload contains problematic values
|
|
15
|
+
*/
|
|
16
|
+
function validatePayloadStructure(value, path = 'root', depth = 0) {
|
|
17
|
+
if (depth > MAX_NESTING_DEPTH) {
|
|
18
|
+
throw Errors.serializationFailed(`max nesting depth exceeded at ${path} (${depth} > ${MAX_NESTING_DEPTH})`);
|
|
19
|
+
}
|
|
20
|
+
if (value === undefined) {
|
|
21
|
+
throw Errors.serializationFailed(`undefined value at ${path} - use null instead`);
|
|
22
|
+
}
|
|
23
|
+
if (typeof value === 'number') {
|
|
24
|
+
if (Number.isNaN(value)) {
|
|
25
|
+
throw Errors.serializationFailed(`NaN value at ${path} - not allowed`);
|
|
26
|
+
}
|
|
27
|
+
if (!Number.isFinite(value)) {
|
|
28
|
+
throw Errors.serializationFailed(`Infinity value at ${path} - not allowed`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if (typeof value === 'function') {
|
|
32
|
+
throw Errors.serializationFailed(`function at ${path} - not serializable`);
|
|
33
|
+
}
|
|
34
|
+
if (typeof value === 'symbol') {
|
|
35
|
+
throw Errors.serializationFailed(`symbol at ${path} - not serializable`);
|
|
36
|
+
}
|
|
37
|
+
if (typeof value === 'bigint') {
|
|
38
|
+
throw Errors.serializationFailed(`bigint at ${path} - use string representation`);
|
|
39
|
+
}
|
|
40
|
+
if (Array.isArray(value)) {
|
|
41
|
+
for (let i = 0; i < value.length; i++) {
|
|
42
|
+
validatePayloadStructure(value[i], `${path}[${i}]`, depth + 1);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
else if (value !== null && typeof value === 'object') {
|
|
46
|
+
// Check for circular references would require WeakSet tracking
|
|
47
|
+
// JSON.stringify will throw on circular refs anyway
|
|
48
|
+
const entries = Object.entries(value);
|
|
49
|
+
if (entries.length > MAX_OBJECT_KEYS) {
|
|
50
|
+
throw Errors.serializationFailed(`max object key count exceeded at ${path} (${entries.length} > ${MAX_OBJECT_KEYS})`);
|
|
51
|
+
}
|
|
52
|
+
for (const [key, val] of entries) {
|
|
53
|
+
if (val === undefined) {
|
|
54
|
+
throw Errors.serializationFailed(`undefined value at ${path}.${key} - use null or omit key`);
|
|
55
|
+
}
|
|
56
|
+
validatePayloadStructure(val, `${path}.${key}`, depth + 1);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Serialize value to canonical JSON with sorted keys.
|
|
62
|
+
* Ensures identical payloads produce identical strings.
|
|
63
|
+
*/
|
|
64
|
+
function canonicalize(value) {
|
|
65
|
+
return JSON.stringify(value, (_, v) => {
|
|
66
|
+
if (v !== null && typeof v === 'object' && !Array.isArray(v)) {
|
|
67
|
+
const sorted = {};
|
|
68
|
+
const obj = v;
|
|
69
|
+
Object.keys(obj)
|
|
70
|
+
.sort()
|
|
71
|
+
.forEach((key) => {
|
|
72
|
+
sorted[key] = obj[key];
|
|
73
|
+
});
|
|
74
|
+
return sorted;
|
|
75
|
+
}
|
|
76
|
+
return v;
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Encode payload to UTF-8 bytes with size-first validation.
|
|
81
|
+
*
|
|
82
|
+
* SECURITY: This function enforces the following invariants:
|
|
83
|
+
* 1. Payload structure is validated for edge cases
|
|
84
|
+
* 2. Size is checked AFTER encoding (actual byte size)
|
|
85
|
+
* 3. Returns bytes for direct use in signature hashing
|
|
86
|
+
*
|
|
87
|
+
* @param payload - JSON-serializable payload
|
|
88
|
+
* @param maxSize - Maximum allowed size in bytes
|
|
89
|
+
* @returns Encoded bytes and metadata
|
|
90
|
+
* @throws TracehoundError if validation fails
|
|
91
|
+
*/
|
|
92
|
+
export function encodePayload(payload, maxSize) {
|
|
93
|
+
// Step 1: Validate structure (catches undefined, NaN, etc.)
|
|
94
|
+
validatePayloadStructure(payload);
|
|
95
|
+
// Step 2: Canonicalize to JSON string
|
|
96
|
+
const canonical = canonicalize(payload);
|
|
97
|
+
// Step 3: Encode to UTF-8 bytes
|
|
98
|
+
const encoder = new TextEncoder();
|
|
99
|
+
const bytes = encoder.encode(canonical);
|
|
100
|
+
// Step 4: Check size AFTER encoding (actual byte size, not string length)
|
|
101
|
+
if (bytes.length > maxSize) {
|
|
102
|
+
throw Errors.payloadTooLarge(bytes.length, maxSize);
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
bytes,
|
|
106
|
+
size: bytes.length,
|
|
107
|
+
canonical,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Quick size estimate without full encoding.
|
|
112
|
+
* Use for early rejection before detailed validation.
|
|
113
|
+
*
|
|
114
|
+
* NOTE: This is a conservative estimate. Actual UTF-8 size
|
|
115
|
+
* may be larger for non-ASCII characters.
|
|
116
|
+
*/
|
|
117
|
+
export function estimatePayloadSize(payload) {
|
|
118
|
+
// Quick stringify without sorting (faster for estimation)
|
|
119
|
+
const json = JSON.stringify(payload);
|
|
120
|
+
// UTF-8: ASCII = 1 byte, others = up to 4 bytes
|
|
121
|
+
// Use 2x as conservative multiplier
|
|
122
|
+
return json.length * 2;
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=encode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encode.js","sourceRoot":"","sources":["../../src/utils/encode.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cryptographic hashing utilities.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Compute SHA-256 hash of a string.
|
|
6
|
+
* Uses synchronous crypto for hot-path performance.
|
|
7
|
+
*
|
|
8
|
+
* @param data - String to hash
|
|
9
|
+
* @returns Lowercase hex string (64 characters)
|
|
10
|
+
*/
|
|
11
|
+
export declare function hash(data: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* Compute SHA-256 hash of a buffer.
|
|
14
|
+
*
|
|
15
|
+
* @param data - Buffer to hash
|
|
16
|
+
* @returns Lowercase hex string (64 characters)
|
|
17
|
+
*/
|
|
18
|
+
export declare function hashBuffer(data: ArrayBuffer | Uint8Array): string;
|
|
19
|
+
//# sourceMappingURL=hash.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../src/utils/hash.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;;;;;GAMG;AACH,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEzC;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,WAAW,GAAG,UAAU,GAAG,MAAM,CAGjE"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cryptographic hashing utilities.
|
|
3
|
+
*/
|
|
4
|
+
import { createHash } from 'node:crypto';
|
|
5
|
+
/**
|
|
6
|
+
* Compute SHA-256 hash of a string.
|
|
7
|
+
* Uses synchronous crypto for hot-path performance.
|
|
8
|
+
*
|
|
9
|
+
* @param data - String to hash
|
|
10
|
+
* @returns Lowercase hex string (64 characters)
|
|
11
|
+
*/
|
|
12
|
+
export function hash(data) {
|
|
13
|
+
return createHash('sha256').update(data).digest('hex');
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Compute SHA-256 hash of a buffer.
|
|
17
|
+
*
|
|
18
|
+
* @param data - Buffer to hash
|
|
19
|
+
* @returns Lowercase hex string (64 characters)
|
|
20
|
+
*/
|
|
21
|
+
export function hashBuffer(data) {
|
|
22
|
+
const uint8 = data instanceof Uint8Array ? data : new Uint8Array(data);
|
|
23
|
+
return createHash('sha256').update(uint8).digest('hex');
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=hash.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hash.js","sourceRoot":"","sources":["../../src/utils/hash.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAExC;;;;;;GAMG;AACH,MAAM,UAAU,IAAI,CAAC,IAAY;IAC/B,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AACxD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,IAA8B;IACvD,MAAM,KAAK,GAAG,IAAI,YAAY,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,CAAA;IACtE,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AACzD,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secure ID generation.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Generate a secure, time-ordered unique ID.
|
|
6
|
+
* Combines UUIDv7 (time-ordered) with random suffix for unpredictability.
|
|
7
|
+
*
|
|
8
|
+
* Format: {uuidv7}-{random8chars}
|
|
9
|
+
*
|
|
10
|
+
* @returns Unique ID string
|
|
11
|
+
*/
|
|
12
|
+
export declare function generateSecureId(): string;
|
|
13
|
+
/**
|
|
14
|
+
* Validate a secure ID format.
|
|
15
|
+
*
|
|
16
|
+
* @param id - ID to validate
|
|
17
|
+
* @returns True if valid format
|
|
18
|
+
*/
|
|
19
|
+
export declare function isValidSecureId(id: string): boolean;
|
|
20
|
+
//# sourceMappingURL=id.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"id.d.ts","sourceRoot":"","sources":["../../src/utils/id.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAIzC;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAwBnD"}
|
package/dist/utils/id.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secure ID generation.
|
|
3
|
+
*/
|
|
4
|
+
import { randomBytes } from 'node:crypto';
|
|
5
|
+
import { v7 as uuidv7 } from 'uuid';
|
|
6
|
+
/**
|
|
7
|
+
* Generate a secure, time-ordered unique ID.
|
|
8
|
+
* Combines UUIDv7 (time-ordered) with random suffix for unpredictability.
|
|
9
|
+
*
|
|
10
|
+
* Format: {uuidv7}-{random8chars}
|
|
11
|
+
*
|
|
12
|
+
* @returns Unique ID string
|
|
13
|
+
*/
|
|
14
|
+
export function generateSecureId() {
|
|
15
|
+
const timeOrdered = uuidv7();
|
|
16
|
+
const randomSuffix = randomBytes(4).toString('hex');
|
|
17
|
+
return `${timeOrdered}-${randomSuffix}`;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Validate a secure ID format.
|
|
21
|
+
*
|
|
22
|
+
* @param id - ID to validate
|
|
23
|
+
* @returns True if valid format
|
|
24
|
+
*/
|
|
25
|
+
export function isValidSecureId(id) {
|
|
26
|
+
// UUIDv7 (36 chars) + hyphen + 8 hex chars = 45 chars
|
|
27
|
+
if (id.length !== 45)
|
|
28
|
+
return false;
|
|
29
|
+
const [uuid, suffix] = id.split('-').reduce((acc, part, i) => {
|
|
30
|
+
if (i < 5) {
|
|
31
|
+
acc[0] = acc[0] ? `${acc[0]}-${part}` : part;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
acc[1] = part;
|
|
35
|
+
}
|
|
36
|
+
return acc;
|
|
37
|
+
}, ['', '']);
|
|
38
|
+
// Validate UUID format (basic check)
|
|
39
|
+
const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
40
|
+
if (!uuidPattern.test(uuid))
|
|
41
|
+
return false;
|
|
42
|
+
// Validate suffix (8 hex chars)
|
|
43
|
+
if (suffix === undefined || !/^[0-9a-f]{8}$/i.test(suffix))
|
|
44
|
+
return false;
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=id.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"id.js","sourceRoot":"","sources":["../../src/utils/id.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAA;AAEnC;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB;IAC9B,MAAM,WAAW,GAAG,MAAM,EAAE,CAAA;IAC5B,MAAM,YAAY,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;IACnD,OAAO,GAAG,WAAW,IAAI,YAAY,EAAE,CAAA;AACzC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,EAAU;IACxC,sDAAsD;IACtD,IAAI,EAAE,CAAC,MAAM,KAAK,EAAE;QAAE,OAAO,KAAK,CAAA;IAElC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CACzC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE;QACf,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACV,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;QAC9C,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAA;QACf,CAAC;QACD,OAAO,GAAG,CAAA;IACZ,CAAC,EACD,CAAC,EAAE,EAAE,EAAE,CAAqB,CAC7B,CAAA;IAED,qCAAqC;IACrC,MAAM,WAAW,GAAG,wEAAwE,CAAA;IAC5F,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAA;IAEzC,gCAAgC;IAChC,IAAI,MAAM,KAAK,SAAS,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAA;IAExE,OAAO,IAAI,CAAA;AACb,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime environment verification.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Verify runtime environment meets security requirements.
|
|
6
|
+
*
|
|
7
|
+
* Checks:
|
|
8
|
+
* - --disable-proto=throw: Prevents prototype pollution via __proto__
|
|
9
|
+
* - --frozen-intrinsics: Freezes built-in prototypes
|
|
10
|
+
*
|
|
11
|
+
* @param strict - If true, throw on missing flags. If false, warn only.
|
|
12
|
+
* @throws {TracehoundError} if strict mode and flags missing
|
|
13
|
+
*/
|
|
14
|
+
export declare function verifyRuntime(strict: boolean): void;
|
|
15
|
+
/**
|
|
16
|
+
* Get runtime environment info.
|
|
17
|
+
*/
|
|
18
|
+
export declare function getRuntimeInfo(): {
|
|
19
|
+
nodeVersion: string;
|
|
20
|
+
protoDisabled: boolean;
|
|
21
|
+
intrinsicsFrozen: boolean;
|
|
22
|
+
platform: string;
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/utils/runtime.ts"],"names":[],"mappings":"AAAA;;GAEG;AA6BH;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAoBnD;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI;IAChC,WAAW,EAAE,MAAM,CAAA;IACnB,aAAa,EAAE,OAAO,CAAA;IACtB,gBAAgB,EAAE,OAAO,CAAA;IACzB,QAAQ,EAAE,MAAM,CAAA;CACjB,CAOA"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime environment verification.
|
|
3
|
+
*/
|
|
4
|
+
import { Errors } from '../types/errors.js';
|
|
5
|
+
/**
|
|
6
|
+
* Check if prototype access is disabled.
|
|
7
|
+
* Returns true if --disable-proto=throw is set.
|
|
8
|
+
*/
|
|
9
|
+
function isProtoDisabled() {
|
|
10
|
+
try {
|
|
11
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
12
|
+
const obj = {};
|
|
13
|
+
// If __proto__ throws, flag is set correctly
|
|
14
|
+
void obj.__proto__;
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Check if intrinsics are frozen.
|
|
23
|
+
* Returns true if --frozen-intrinsics is set.
|
|
24
|
+
*/
|
|
25
|
+
function areIntrinsicsFrozen() {
|
|
26
|
+
// If Object.prototype is frozen, flag is likely set
|
|
27
|
+
return Object.isFrozen(Object.prototype);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Verify runtime environment meets security requirements.
|
|
31
|
+
*
|
|
32
|
+
* Checks:
|
|
33
|
+
* - --disable-proto=throw: Prevents prototype pollution via __proto__
|
|
34
|
+
* - --frozen-intrinsics: Freezes built-in prototypes
|
|
35
|
+
*
|
|
36
|
+
* @param strict - If true, throw on missing flags. If false, warn only.
|
|
37
|
+
* @throws {TracehoundError} if strict mode and flags missing
|
|
38
|
+
*/
|
|
39
|
+
export function verifyRuntime(strict) {
|
|
40
|
+
const issues = [];
|
|
41
|
+
if (!isProtoDisabled()) {
|
|
42
|
+
issues.push('--disable-proto=throw not set. Prototype pollution via __proto__ possible.');
|
|
43
|
+
}
|
|
44
|
+
if (!areIntrinsicsFrozen()) {
|
|
45
|
+
issues.push('--frozen-intrinsics not set. Built-in prototypes can be modified.');
|
|
46
|
+
}
|
|
47
|
+
if (issues.length > 0) {
|
|
48
|
+
const message = `[tracehound] Runtime security issues:\n - ${issues.join('\n - ')}`;
|
|
49
|
+
if (strict) {
|
|
50
|
+
throw Errors.runtimeFlagMissing(issues.join(', '));
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
console.warn(message);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Get runtime environment info.
|
|
59
|
+
*/
|
|
60
|
+
export function getRuntimeInfo() {
|
|
61
|
+
return {
|
|
62
|
+
nodeVersion: process.version,
|
|
63
|
+
protoDisabled: isProtoDisabled(),
|
|
64
|
+
intrinsicsFrozen: areIntrinsicsFrozen(),
|
|
65
|
+
platform: process.platform,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/utils/runtime.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAE3C;;;GAGG;AACH,SAAS,eAAe;IACtB,IAAI,CAAC;QACH,8DAA8D;QAC9D,MAAM,GAAG,GAAG,EAAS,CAAA;QACrB,6CAA6C;QAC7C,KAAK,GAAG,CAAC,SAAS,CAAA;QAClB,OAAO,KAAK,CAAA;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAS,mBAAmB;IAC1B,oDAAoD;IACpD,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;AAC1C,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,aAAa,CAAC,MAAe;IAC3C,MAAM,MAAM,GAAa,EAAE,CAAA;IAE3B,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;QACvB,MAAM,CAAC,IAAI,CAAC,4EAA4E,CAAC,CAAA;IAC3F,CAAC;IAED,IAAI,CAAC,mBAAmB,EAAE,EAAE,CAAC;QAC3B,MAAM,CAAC,IAAI,CAAC,mEAAmE,CAAC,CAAA;IAClF,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,8CAA8C,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAA;QAErF,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;QACpD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACvB,CAAC;IACH,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc;IAM5B,OAAO;QACL,WAAW,EAAE,OAAO,CAAC,OAAO;QAC5B,aAAa,EAAE,eAAe,EAAE;QAChC,gBAAgB,EAAE,mBAAmB,EAAE;QACvC,QAAQ,EAAE,OAAO,CAAC,QAAQ;KAC3B,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic JSON serialization with sorted keys.
|
|
3
|
+
*/
|
|
4
|
+
import type { JsonSerializable } from '../types/common.js';
|
|
5
|
+
/**
|
|
6
|
+
* Serialize a value to a deterministic JSON string.
|
|
7
|
+
* Object keys are sorted to ensure identical payloads produce identical strings
|
|
8
|
+
* regardless of key insertion order.
|
|
9
|
+
*
|
|
10
|
+
* @param value - JSON-serializable value
|
|
11
|
+
* @returns Deterministic JSON string
|
|
12
|
+
*/
|
|
13
|
+
export declare function serialize(value: JsonSerializable): string;
|
|
14
|
+
//# sourceMappingURL=serialize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serialize.d.ts","sourceRoot":"","sources":["../../src/utils/serialize.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAE1D;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAczD"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic JSON serialization with sorted keys.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Serialize a value to a deterministic JSON string.
|
|
6
|
+
* Object keys are sorted to ensure identical payloads produce identical strings
|
|
7
|
+
* regardless of key insertion order.
|
|
8
|
+
*
|
|
9
|
+
* @param value - JSON-serializable value
|
|
10
|
+
* @returns Deterministic JSON string
|
|
11
|
+
*/
|
|
12
|
+
export function serialize(value) {
|
|
13
|
+
return JSON.stringify(value, (_, v) => {
|
|
14
|
+
if (v !== null && typeof v === 'object' && !Array.isArray(v)) {
|
|
15
|
+
const sorted = {};
|
|
16
|
+
const obj = v;
|
|
17
|
+
Object.keys(obj)
|
|
18
|
+
.sort()
|
|
19
|
+
.forEach((key) => {
|
|
20
|
+
sorted[key] = obj[key];
|
|
21
|
+
});
|
|
22
|
+
return sorted;
|
|
23
|
+
}
|
|
24
|
+
return v;
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=serialize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serialize.js","sourceRoot":"","sources":["../../src/utils/serialize.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;;;;;;GAOG;AACH,MAAM,UAAU,SAAS,CAAC,KAAuB;IAC/C,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAU,EAAE,EAAE;QAC7C,IAAI,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7D,MAAM,MAAM,GAA4B,EAAE,CAAA;YAC1C,MAAM,GAAG,GAAG,CAA4B,CAAA;YACxC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;iBACb,IAAI,EAAE;iBACN,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;gBACf,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAA;YACxB,CAAC,CAAC,CAAA;YACJ,OAAO,MAAM,CAAA;QACf,CAAC;QACD,OAAO,CAAC,CAAA;IACV,CAAC,CAAC,CAAA;AACJ,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tracehound/core",
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "Deterministic runtime security buffer for high-velocity APIs",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"author": "Erdem Arslan <me@erdem.work>",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/tracehound/tracehound.git",
|
|
10
|
+
"directory": "packages/core"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/tracehound/tracehound#readme",
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/tracehound/tracehound/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"security",
|
|
18
|
+
"runtime",
|
|
19
|
+
"quarantine",
|
|
20
|
+
"evidence",
|
|
21
|
+
"forensics",
|
|
22
|
+
"waf",
|
|
23
|
+
"audit",
|
|
24
|
+
"deterministic"
|
|
25
|
+
],
|
|
26
|
+
"type": "module",
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"import": "./dist/index.js"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"dist"
|
|
35
|
+
],
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"uuid": "^10.0.0"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/node": "^20.0.0",
|
|
41
|
+
"@types/uuid": "^10.0.0",
|
|
42
|
+
"vitest": "^2.0.0"
|
|
43
|
+
},
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"typescript": "^5.3.0"
|
|
46
|
+
},
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build": "tsc",
|
|
49
|
+
"test": "vitest run",
|
|
50
|
+
"test:watch": "vitest",
|
|
51
|
+
"lint": "tsc --noEmit",
|
|
52
|
+
"clean": "rm -rf dist"
|
|
53
|
+
}
|
|
54
|
+
}
|