@cabin-interactive/qrz-api-client
Version:
A TypeScript wrapper for the QRZ.com API
63 lines (62 loc) • 2.53 kB
JavaScript
// qso.ts
import { BaseQrzService } from "./base";
import { QrzAdifFormatError, QrzQsoValidationError, QrzError, } from "../errors";
export class QsoService extends BaseQrzService {
constructor(config, http) {
super(config);
this.http = http;
}
async uploadQso(adif, options = {}) {
this.validateAdif(adif);
const params = {
action: 'INSERT',
adif,
...(options.replace ? { option: 'REPLACE' } : {})
};
// Catch errors thrown by HttpService.post before evaluating response
let response;
try {
response = await this.http.post(params);
}
catch (err) {
throw err;
}
if (this.isFailResponse(response)) {
const errorMessage = response.reason;
throw new QrzError(errorMessage || 'Failed to upload QSO');
}
if (response.result !== QsoService.RESULT_OK && response.result !== QsoService.RESULT_REPLACE) {
throw new QrzError(response.result || 'Failed to upload QSO');
}
// Success case (COUNT=1&LOGID=1193649&RESULT=OK)
return {
logId: response.logId || '',
status: response.result,
count: response.count ? parseInt(response.count, 10) : 1
};
}
isFailResponse(response) {
return response.result === QsoService.RESULT_FAIL;
}
validateAdif(adif) {
if (!/<eor>$/i.test(adif)) {
throw new QrzAdifFormatError('Invalid ADIF format: missing <eor> tag');
}
const requiredFields = ['BAND', 'MODE', 'CALL', 'QSO_DATE', 'TIME_ON'];
for (const field of requiredFields) {
const fieldRegex = new RegExp(`<${field}:`, 'i');
if (!fieldRegex.test(adif)) {
// Convert back to lowercase for the error message to match documentation
const originalField = field.toLowerCase();
throw new QrzQsoValidationError(`Missing required ADIF field: ${originalField}`, originalField);
}
}
const stationIdentifiers = ['STATION_CALLSIGN', 'OPERATOR'];
if (!stationIdentifiers.some(field => new RegExp(`<${field}:`, 'i').test(adif))) {
throw new QrzQsoValidationError('Missing station identification: either station_callsign or operator is required', 'station_identification');
}
}
}
QsoService.RESULT_OK = 'OK';
QsoService.RESULT_FAIL = 'FAIL';
QsoService.RESULT_REPLACE = 'REPLACE';