UNPKG

hkopendata

Version:

Access different Opendata API and data in Hong Kong

166 lines (155 loc) 5.08 kB
// https://www.legco.gov.hk/datagovhk/data-dictionary-reference-data-tc.pdf const cmn = require("../../common"); const moment = require("../../moment"); const BASE_URL = "https://app.legco.gov.hk/ScheduleDB/odata/Tmembership"; const VALID = {}; const VALID_OPT = { $format: /^(json|xml)$/, $top: /^[0-9]+$/, $skip: /^[0-9]+$/, $orderby: /^.+$/, $filter: /^.+$/, $inlinecount: /^(allpages)$/, sortorder: /^(asc|desc)$/, }; const PARAMS = { $format: "json", $top: 20, } const FIELDS = { regex: { "home_url": "website", }, text: { "membership_id": "id", "term_id": "term", } } const SEARCH_CONFIG = { rename: { limit: "$top", offset: "$skip", sortby: "$orderby" } } const KEY_TO_NAME = { id: "membership_id", member: "member_id", committee: "committee_id", term: "term_id" } function validateParameters(params) { params = cmn.ParseSearchFields(params, SEARCH_CONFIG); let result = cmn.ValidateParameters(params, VALID, VALID_OPT); if (params.$orderby && !/(asc|desc)/.test(params.$orderby)) { let sortorder = params.sortorder || "asc"; let name = KEY_TO_NAME[params.$orderby] || params.$orderby; params.$orderby = `${name} ${sortorder}`; } if (!params.$filter && params.filter) { let filter = []; for (let key in params.filter) { if (/^(id|member|committee)$/.test(key)) { filter.push(`${KEY_TO_NAME[key]} eq ${params.filter[key]}`); } else if (key == "term") { filter.push(`${KEY_TO_NAME[key]} eq ${params.filter[key] - 1}`); } } if (filter.length > 0) params.$filter = filter.join(" and "); } if (!params.$expand && params.expand) { let expand = []; if (params.expand.term) { expand.push("Tterm"); } if (params.expand.committee) { expand.push("Tcommittee"); } if (params.expand.member) { expand.push("Tmember"); } if (expand.length > 0) params.$expand = expand.join(); } ["filter", "sortorder", "expand"].map(v => delete params[v]); 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 { params = processed.data; cmn.APIRequest(cmn.ReplaceURL(BASE_URL, processed.data), params) .then((res) => { resolve(processData(res, processed)); }) .catch((err) => reject(err)) } }) } function processData(data) { let result = []; data.value.map(item => { item = cmn.RenameFields(item, FIELDS); let temp = {}, term; for (let key in item) { let val = item[key], ckey = key.toCamelCase(), m; if (typeof val === "string") val = val.trimChar("\r\n"); if (!val) continue; if (m = key.match(/(.+)_(chi|eng)/)) { ckey = m[1].toCamelCase(); if (!(ckey in temp)) temp[ckey] = {}; temp[ckey][m[2] == "chi" ? "tc" : "en"] = val; } else if (m = key.match(/T(committee|member)/)) { let key2 = m[1]; if (!(key2 in temp)) temp[key2] = {}; for (let k in item[key]) { if (!item[key][k]) continue; ckey = k.toCamelCase(); if (m = k.match(/(.+)_(chi|eng)/)) { ckey = (m[1] == "home_url" ? "website" : m[1]).toCamelCase(); if (!(ckey in temp[key2])) temp[key2][ckey] = {}; temp[key2][ckey][m[2] == "chi" ? "tc" : "en"] = item[key][k]; } else if (!/member_id|committee_id|seq_num|term_id/.test(k)) { temp[key2][ckey] = item[key][k]; } } } else if (key == "Tterm") { for (let k in item[key]) { if (!item[key][k]) continue; if (/date/.test(k)) { if (!term) term = {}; term[`term_${k}`.toCamelCase()] = moment(item[key][k]).format("YYYY-MM-DD"); } } } else if (/date/.test(key)) { temp[ckey] = moment(val).format("YYYY-MM-DD"); } else if (key == "term") { temp[ckey] = parseInt(val) + 1; } else { temp[ckey] = val; } } if (term) { temp = { ...temp, ...term, } } result.push(temp); }) return result; } module.exports = search;