160 lines
4.8 KiB
JavaScript
160 lines
4.8 KiB
JavaScript
import AbortController from 'abort-controller';
|
|
import DebugInfo from '../models/DebugInfo.js';
|
|
import Vehicle from '../models/vehicle.js';
|
|
import Utils from '../utils/utils.js';
|
|
|
|
const baseUrl = 'https://vin01.ru/v2';
|
|
const reportBaseUrl = `${baseUrl}/gibddApp.php`;
|
|
|
|
async function fetchWithTimeout(url, params, timeout) {
|
|
const controller = new AbortController();
|
|
const timeoutId = setTimeout(() => {
|
|
controller.abort();
|
|
}, timeout);
|
|
|
|
let requestParams = params ?? {};
|
|
requestParams.signal = controller.signal;
|
|
|
|
try {
|
|
return await fetch(url, requestParams);
|
|
} finally {
|
|
clearInterval(timeoutId);
|
|
}
|
|
}
|
|
|
|
class Vin01Provider {
|
|
static async getVin(number, token) {
|
|
let url = `${baseUrl}/getVin.php?key=${token}&gosNumber=${encodeURIComponent(number)}`;
|
|
let result = await fetchWithTimeout(url, null, 14000);
|
|
let json = await result.json();
|
|
if(json.success && json.code == 200) {
|
|
return json.data.vin;
|
|
} else {
|
|
throw Error('Vin01 provider failed to get VIN');
|
|
}
|
|
}
|
|
|
|
static async runCheck(type, vin, token) {
|
|
let result = await fetchWithTimeout(reportBaseUrl, {
|
|
method: 'POST',
|
|
body: new URLSearchParams({
|
|
typeCheckValue: type,
|
|
vinValue: vin,
|
|
key: token,
|
|
token: null
|
|
})
|
|
}, 25000);
|
|
console.log('Vin01 response for: ', type);
|
|
return await result.json();
|
|
}
|
|
|
|
static checkErrors(result) {
|
|
if(result.status == 'fulfilled') {
|
|
let json = result.value;
|
|
if(json.status == 200) {
|
|
if('status' in json.data) {
|
|
if(json.data.status == 200) {
|
|
result.value = json.data;
|
|
return result;
|
|
} else {
|
|
return { status: 'rejected', reason: Error(`[${json.data.status}] ${json.data.message}`) };
|
|
}
|
|
} else {
|
|
result.value = json.data;
|
|
return result;
|
|
}
|
|
} else {
|
|
return { status: 'rejected', reason: Error(`[${json.status}] ${json.code}`) };
|
|
}
|
|
} else {
|
|
return result;
|
|
}
|
|
}
|
|
|
|
static async getReport(number, token) {
|
|
try {
|
|
let vin = await Vin01Provider.getVin(number, token);
|
|
console.log('vin01 found VIN: ', vin);
|
|
|
|
let checks = [Vin01Provider.runCheck('base', vin, token), Vin01Provider.runCheck('history', vin, token)];
|
|
let [base, history] = (await Promise.allSettled(checks)).map(Vin01Provider.checkErrors);
|
|
if(base.status == 'rejected' && history.status == 'rejected') {
|
|
console.log('Vin01 base error: ', base.reason.message);
|
|
console.log('Vin01 history error: ', history.reason.message);
|
|
let vehicle = new Vehicle();
|
|
vehicle.vin1 = Utils.cyrillicToLatin(vin);
|
|
vehicle.debugInfo = {
|
|
vin01vin: new DebugInfo(),
|
|
vin01history: DebugInfo.fromError(history.reason.message),
|
|
vin01base: DebugInfo.fromError(base.reason.message)
|
|
};
|
|
return vehicle;
|
|
} else if(base.status == 'rejected') {
|
|
console.log('vin01 found history');
|
|
let vehicle = Vehicle.fromVin01History(history.value);
|
|
vehicle.number = number;
|
|
Object.assign(vehicle.debugInfo, {
|
|
vin01vin: new DebugInfo(),
|
|
vin01base: DebugInfo.fromError(base.reason.message)
|
|
});
|
|
return vehicle;
|
|
} else if(history.status == 'rejected') {
|
|
console.log('vin01 found base info');
|
|
let vehicle = Vehicle.fromVin01Base(base.value);
|
|
vehicle.number = number;
|
|
Object.assign(vehicle.debugInfo, {
|
|
vin01vin: new DebugInfo(),
|
|
vin01history: DebugInfo.fromError(history.reason.message)
|
|
});
|
|
return vehicle;
|
|
} else {
|
|
// Both history and base reports were successfully received, merge them in one report
|
|
let baseVehicle = Vehicle.fromVin01Base(base.value);
|
|
let historyVehicle = Vehicle.fromVin01History(history.value);
|
|
|
|
historyVehicle.brand.name.normalized = baseVehicle.brand.name.normalized;
|
|
historyVehicle.model = baseVehicle.model;
|
|
|
|
for(let period of historyVehicle.ownershipPeriods) {
|
|
let basePeriod = baseVehicle.ownershipPeriods.find(p => p.from == period.from);
|
|
if(basePeriod) {
|
|
period.region = basePeriod.region;
|
|
period.registrationRegion = basePeriod.registrationRegion;
|
|
period.locality = basePeriod.locality;
|
|
|
|
if(basePeriod.street) {
|
|
period.street = basePeriod.street;
|
|
}
|
|
|
|
if(basePeriod.building) {
|
|
period.building = basePeriod.building;
|
|
}
|
|
|
|
if(basePeriod.inn) {
|
|
period.inn = basePeriod.inn;
|
|
}
|
|
|
|
if(basePeriod.code) {
|
|
period.code = basePeriod.code;
|
|
}
|
|
}
|
|
}
|
|
|
|
Object.assign(historyVehicle.debugInfo, { vin01vin: new DebugInfo() });
|
|
Object.assign(historyVehicle.debugInfo, baseVehicle.debugInfo);
|
|
|
|
historyVehicle.number = number;
|
|
return historyVehicle;
|
|
}
|
|
} catch(ex) {
|
|
ex.debugInfo = {
|
|
vin01vin:DebugInfo.fromError(ex.message),
|
|
vin01history: DebugInfo.fromError('Not applicable (VIN was not found)'),
|
|
vin01base: DebugInfo.fromError('Not applicable (VIN was not found)')
|
|
};
|
|
throw ex;
|
|
}
|
|
}
|
|
}
|
|
|
|
export default Vin01Provider; |