@hashgraphonline/standards-sdk
Version:
The Hashgraph Online Standards SDK provides a complete implementation of the Hashgraph Consensus Standards (HCS), giving developers all the tools needed to build applications on Hedera.
160 lines (159 loc) • 4.38 kB
JavaScript
import axios from "axios";
import { Logger } from "./standards-sdk.es22.js";
class HRLResolver {
constructor(logLevel = "info") {
this.defaultEndpoint = "https://kiloscribe.com/api/inscription-cdn";
this.logger = Logger.getInstance({
level: logLevel,
module: "HRLResolver"
});
}
/**
* Determines if a MIME type represents binary content
*/
isBinaryContentType(mimeType) {
const binaryTypes = [
"image/",
"audio/",
"video/",
"application/octet-stream",
"application/pdf",
"application/zip",
"application/gzip",
"application/x-binary",
"application/vnd.ms-",
"application/x-msdownload",
"application/x-shockwave-flash",
"font/",
"application/wasm"
];
return binaryTypes.some((prefix) => mimeType.startsWith(prefix));
}
/**
* Parses an HRL string into its components
*/
parseHRL(hrl) {
if (!hrl) {
return null;
}
const hrlPattern = /^hcs:\/\/(\d+)\/([0-9]+\.[0-9]+\.[0-9]+)$/;
const match = hrl.match(hrlPattern);
if (!match) {
return null;
}
return {
standard: match[1],
topicId: match[2]
};
}
/**
* Validates if a string is a valid HRL
*/
isValidHRL(hrl) {
if (!hrl || typeof hrl !== "string") {
return false;
}
const parsed = this.parseHRL(hrl);
if (!parsed) {
return false;
}
const topicIdPattern = /^[0-9]+\.[0-9]+\.[0-9]+$/;
if (!topicIdPattern.test(parsed.topicId)) {
return false;
}
return true;
}
async getContentWithType(hrl, options) {
if (!this.isValidHRL(hrl)) {
return {
content: hrl,
contentType: "text/plain",
isBinary: false
};
}
try {
const result = await this.resolveHRL(hrl, options);
return {
content: result.content,
contentType: result.contentType,
isBinary: result.isBinary
};
} catch (e) {
const error = e;
const logMessage = `Error resolving HRL for content and type: ${error.message}`;
this.logger.error(logMessage);
throw new Error(logMessage);
}
}
/**
* Resolves HRL content with proper content type detection
*/
async resolveHRL(hrl, options) {
const parsed = this.parseHRL(hrl);
if (!parsed) {
throw new Error(`Invalid HRL format: ${hrl}`);
}
const { standard, topicId } = parsed;
this.logger.debug(
`Resolving HRL reference: standard=${standard}, topicId=${topicId}`
);
try {
const cdnEndpoint = options.cdnEndpoint || this.defaultEndpoint;
const cdnUrl = `${cdnEndpoint}/${topicId}?network=${options.network}`;
this.logger.debug(`Fetching content from CDN: ${cdnUrl}`);
const headResponse = await axios.head(cdnUrl);
const contentType = headResponse.headers["content-type"] || "";
const isBinary = this.isBinaryContentType(contentType);
if (isBinary || options.returnRaw) {
const response2 = await axios.get(cdnUrl, {
responseType: "arraybuffer"
});
return {
content: response2.data,
contentType,
topicId,
isBinary: true
};
}
if (contentType === "application/json") {
const response2 = await axios.get(cdnUrl, {
responseType: "json"
});
if (!response2.data) {
throw new Error(`Failed to fetch content from topic: ${topicId}`);
}
return {
content: response2.data,
contentType,
topicId,
isBinary: false
};
}
const response = await axios.get(cdnUrl);
if (!response.data) {
throw new Error(`Failed to fetch content from topic: ${topicId}`);
}
let content;
if (typeof response.data === "object") {
content = response.data.content || response.data.text || JSON.stringify(response.data);
} else {
content = response.data;
}
return {
content,
contentType,
topicId,
isBinary: false
};
} catch (e) {
const error = e;
const logMessage = `Error resolving HRL reference: ${error.message}`;
this.logger.error(logMessage);
throw new Error(logMessage);
}
}
}
export {
HRLResolver
};
//# sourceMappingURL=standards-sdk.es25.js.map