@realitydefender/realitydefender
Version:
SDK for the Reality Defender API for deepfake detection
140 lines (139 loc) • 5.66 kB
JavaScript
;
/**
* Reality Defender SDK
* Client library for deepfake detection using the Reality Defender API
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.RealityDefenderError = exports.RealityDefender = void 0;
const async_1 = require("./utils/async");
const client_1 = require("./client");
const constants_1 = require("./core/constants");
const events_1 = require("./core/events");
const upload_1 = require("./detection/upload");
const results_1 = require("./detection/results");
const errors_1 = require("./errors");
/**
* Main SDK class for interacting with the Reality Defender API
*/
class RealityDefender extends events_1.TypedEventEmitter {
/**
* Creates a new Reality Defender SDK instance
* @param config Configuration options
*/
constructor(config) {
super();
if (!config.apiKey) {
throw new errors_1.RealityDefenderError('API key is required', 'unauthorized');
}
this.apiKey = config.apiKey;
this.client = (0, client_1.createHttpClient)({
apiKey: this.apiKey,
baseUrl: config.baseUrl,
});
}
/**
* Upload a file to Reality Defender for analysis
*
* @param options Upload options including file path
* @returns Promise with the request ID
*/
async upload(options) {
try {
// Upload the file and get tracking IDs
return await (0, upload_1.uploadFile)(this.client, options);
}
catch (error) {
if (error instanceof errors_1.RealityDefenderError) {
throw error;
}
throw new errors_1.RealityDefenderError(`Upload failed: ${error.message}`, 'upload_failed');
}
}
/**
* Get the detection result for a specific request ID
*
* @param requestId The request ID to get results for
* @param options Optional parameters for polling
* @returns Promise with the detection result
*/
async getResult(requestId, options = {}) {
return (0, results_1.getDetectionResult)(this.client, requestId, options);
}
/**
* Upload a file and get detection results in a single operation
*
* @param options Upload options including file path
* @param resultOptions Optional parameters for polling results
* @returns Promise with the detection result
*/
async detect(options, resultOptions = {}) {
// First upload the file
const uploadResult = await this.upload(options);
// Then get the results using the request ID from the upload
return this.getResult(uploadResult.requestId, resultOptions);
}
/**
* Start polling for results with event-based callback
*
* @param requestId The request ID to poll for
* @param options Polling configuration options
* @returns Promise that resolves when polling completes (for testing purposes)
*/
pollForResults(requestId, options = {}) {
const { pollingInterval = constants_1.DEFAULT_POLLING_INTERVAL, timeout = constants_1.DEFAULT_TIMEOUT } = options;
return this._pollForResults(requestId, pollingInterval, timeout);
}
/**
* Internal implementation of polling for results
* @returns Promise that resolves when polling completes (for testing purposes)
*/
async _pollForResults(requestId, pollingInterval, timeout) {
let elapsed = 0;
const maxWaitTime = timeout;
// Use a flag to track if we've already emitted a result
let isCompleted = false;
// Check if timeout is already zero/expired before starting
if (timeout <= 0) {
this.emit('error', new errors_1.RealityDefenderError('Polling timeout exceeded', 'timeout'));
return;
}
// Create a polling loop that uses await instead of setTimeout
while (!isCompleted && elapsed < maxWaitTime) {
try {
// Use the built-in polling mechanism with just a single attempt per call
const result = await this.getResult(requestId);
// If the status is still ANALYZING and we haven't exceeded the timeout,
// continue polling after a delay
if (result.status === 'ANALYZING') {
elapsed += pollingInterval;
await (0, async_1.sleep)(pollingInterval);
}
else {
// We have a final result
isCompleted = true;
this.emit('result', result);
}
}
catch (error) {
if (error instanceof errors_1.RealityDefenderError && error.code === 'not_found') {
// Result not ready yet, continue polling if we haven't exceeded the timeout
elapsed += pollingInterval;
await (0, async_1.sleep)(pollingInterval);
}
else {
// Any other error is emitted and polling stops
isCompleted = true;
this.emit('error', error);
}
}
}
// Check if we timed out
if (!isCompleted && elapsed >= maxWaitTime) {
this.emit('error', new errors_1.RealityDefenderError('Polling timeout exceeded', 'timeout'));
}
}
}
exports.RealityDefender = RealityDefender;
// Export error classes and types
var errors_2 = require("./errors");
Object.defineProperty(exports, "RealityDefenderError", { enumerable: true, get: function () { return errors_2.RealityDefenderError; } });