mcard-js
Version:
MCard - Content-addressable storage with cryptographic hashing, handle resolution, and vector search for Node.js and browsers
139 lines (136 loc) • 3.78 kB
JavaScript
// src/model/hash/HashValidator.ts
var HashValidator = class {
/**
* Compute hash of content using specified algorithm
*/
static async computeHash(content, algorithm = "sha256") {
const data = typeof content === "string" ? new TextEncoder().encode(content) : content;
let algoName = "SHA-256";
switch (algorithm.toLowerCase()) {
case "sha1":
algoName = "SHA-1";
break;
case "sha-1":
algoName = "SHA-1";
break;
case "sha256":
algoName = "SHA-256";
break;
case "sha-256":
algoName = "SHA-256";
break;
case "sha384":
algoName = "SHA-384";
break;
case "sha-384":
algoName = "SHA-384";
break;
case "sha512":
algoName = "SHA-512";
break;
case "sha-512":
algoName = "SHA-512";
break;
default:
console.warn(`Algorithm ${algorithm} not natively supported or mapped, defaulting to SHA-256`);
algoName = "SHA-256";
}
const buffer = new Uint8Array(data).buffer;
const hashBuffer = await crypto.subtle.digest(algoName, buffer);
return Array.from(new Uint8Array(hashBuffer)).map((b) => b.toString(16).padStart(2, "0")).join("");
}
/**
* Validate that content matches expected hash
*/
static async validate(content, expectedHash) {
const computedHash = await this.computeHash(content);
return computedHash === expectedHash;
}
};
// src/model/GTime.ts
var VALID_HASH_ALGORITHMS = ["md5", "sha1", "sha224", "sha256", "sha384", "sha512"];
var GTime = class {
static DEFAULT_ALGORITHM = "sha256";
/**
* Generate a GTime stamp for the current moment
* Format: HASH_ALGO|TIMESTAMP|REGION_CODE
*/
static stampNow(hashAlgorithm = this.DEFAULT_ALGORITHM) {
const algo = hashAlgorithm.toLowerCase();
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
const region = "UTC";
return `${algo}|${timestamp}|${region}`;
}
/**
* Parse a GTime string
*/
static parse(gtime) {
const parts = gtime.split("|");
if (parts.length !== 3) {
throw new Error(`Invalid GTime format: ${gtime}`);
}
return {
algorithm: parts[0],
timestamp: new Date(parts[1]),
region: parts[2]
};
}
/**
* Get the hash algorithm from a GTime string
*/
static getHashAlgorithm(gtime) {
return this.parse(gtime).algorithm;
}
/**
* Get the timestamp from a GTime string
*/
static getTimestamp(gtime) {
return this.parse(gtime).timestamp;
}
/**
* Get the region code from a GTime string
*/
static getRegionCode(gtime) {
return this.parse(gtime).region;
}
/**
* Check if the provided hash function is valid.
* Matches Python's GTime.is_valid_hash_function()
*/
static isValidHashFunction(hashFunction) {
if (!hashFunction || typeof hashFunction !== "string") {
return false;
}
return VALID_HASH_ALGORITHMS.includes(hashFunction.toLowerCase());
}
/**
* Check if the provided region code is valid.
* Matches Python's GTime.is_valid_region_code()
*/
static isValidRegionCode(regionCode) {
return Boolean(regionCode && regionCode === regionCode.toUpperCase());
}
/**
* Check if the provided timestamp is in ISO format.
* Matches Python's GTime.is_iso_format()
*/
static isIsoFormat(timestamp) {
if (!timestamp || typeof timestamp !== "string") {
return false;
}
try {
const date = new Date(timestamp);
if (isNaN(date.getTime())) {
return false;
}
const isoPattern = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/;
return isoPattern.test(timestamp);
} catch {
return false;
}
}
};
export {
HashValidator,
GTime
};