hkopendata
Version:
Access different Opendata API and data in Hong Kong
133 lines (126 loc) • 4.41 kB
JavaScript
// https://www.hongkongpost.hk/opendata/DataDictionary/tc/DataDictionary_PostageRate.pdf
const cmn = require("../../common");
const UnitValue = require("../../_class").UnitValue;
const BASE_URL = "https://www.hongkongpost.hk/opendata/postageRate-{type}.json";
const VALID = {
type: /^local-(ORD|REG|PAR|LCP|SMP|bulk-(LBM|LPS))|intl-(ORD|REG|SURPAR|AIRPAR|SPT|EXP|bulk-(IML|LWA|BAM|OPS))|businessSolution$/,
};
const PARAMS = {
type: "local-ORD"
}
const FIELDS = {
regex: {
"destinationName": "destination"
},
number: {
"wgtLimit": "weightLimit",
"amount": "charge",
"handleFee": "serviceCharge",
}
}
const SEARCH_CONFIG = {
value: {
type: {
accepted: ["local-ORD", "local-REG", "local-PAR", "local-LCP", "local-SMP", "local-bulk-LBM", "local-bulk-LPS", "intl-ORD", "intl-REG", "intl-SURPAR", "intl-AIRPAR", "intl-SPT", "intl-EXP", "intl-bulk-IML", "intl-bulk-LWA", "intl-bulk-BAM", "intl-bulk-OPS", "businessSolution"]
},
},
};
function validateParameters(params) {
params = cmn.ParseSearchFields(params, SEARCH_CONFIG);
let result = cmn.ValidateParameters(params, VALID);
if (!result.error) {
result.data = {
...params
}
}
return result;
}
function search(data, opts) {
return new Promise((resolve, reject) => {
let processed = validateParameters({
...PARAMS,
...data
});
if (processed.error) {
reject(processed);
} else {
cmn.APIRequest(cmn.ReplaceURL(BASE_URL, processed.data))
.then((res) => {
resolve(processData(res, opts))
})
.catch((err) => reject(err))
}
})
}
function processData(data, opts) {
let result = [];
data.data.map(item => {
let temp = preprocessFields(item);
temp.lastUpdate = data.lastUpdateDate;
result.push(temp);
})
return result;
}
function preprocessFields(data) {
const WEIGHT_UNIT = {
type: "weight",
category: "gram",
scale: "kilo",
};
if (Array.isArray(data)) return data.map(v => preprocessFields(v))
else if (typeof data === "object" && data !== null) {
data = cmn.RenameFields(data, FIELDS);
let temp = {};
for (let key in data) {
let m;
if (typeof data[key] === "object" && data[key] != null) {
temp[key] = preprocessFields(data[key])
} else if (m = key.match(/^([A-z]+)(TC|SC|EN)$/)) {
if (!(m[1] in temp)) temp[m[1]] = {};
temp[m[1]][m[2].toLowerCase()] = data[key];
} else if (m = key.match(/additional(Amount|Weight)/)) {
if (!("overweight" in temp)) temp.overweight = {};
if (m[1] == "Amount") {
temp.overweight.charge = parseFloat(data[key]);
} else {
temp.overweight.weight = new UnitValue({
...WEIGHT_UNIT,
...{
value: data[key]
}
});
}
} else if (/weight(To|From)/.test(key)) {
if (!("weightLimit" in temp)) temp.weightLimit = {};
let limit = key == "weightTo" ? "max" : "min";
temp.weightLimit[limit] = new UnitValue({
...WEIGHT_UNIT,
...{
value: data[key]
}
});
temp.weightLimit[limit].toBestScaleSI();
} else if (key == "weightLimit") {
temp[key] = new UnitValue({
...WEIGHT_UNIT,
...{
value: data[key]
}
});
} else if (/Code$/.test(key) || key == "trackingLevel") {
if (key == "trackingLevel") {
temp.tracking = data[key] != "0";
}
temp[`_${key}`] = data[key];
} else {
temp[key] = data[key];
}
}
if ("subServiceName" in temp) {
temp.mlss = temp.subServiceName.tc.indexOf("非標準") == -1;
}
return temp;
}
return data;
}
module.exports = search