hk-bus-eta 3.3.2 → 3.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/fortuneferry.d.ts +5 -3
- package/dist/fortuneferry.js +50 -28
- package/dist/fortuneferry.js.map +1 -1
- package/dist/hkkf.d.ts +5 -4
- package/dist/hkkf.js +44 -23
- package/dist/hkkf.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/sunferry.d.ts +5 -2
- package/dist/sunferry.js +20 -1
- package/dist/sunferry.js.map +1 -1
- package/dist/type.d.ts +8 -8
- package/dist/utils.d.ts +7 -0
- package/dist/utils.js +47 -1
- package/dist/utils.js.map +1 -1
- package/esm/fortuneferry.d.ts +5 -3
- package/esm/fortuneferry.js +50 -28
- package/esm/fortuneferry.js.map +1 -1
- package/esm/hkkf.d.ts +5 -4
- package/esm/hkkf.js +44 -23
- package/esm/hkkf.js.map +1 -1
- package/esm/index.d.ts +3 -1
- package/esm/index.js +4 -4
- package/esm/index.js.map +1 -1
- package/esm/sunferry.d.ts +5 -2
- package/esm/sunferry.js +21 -2
- package/esm/sunferry.js.map +1 -1
- package/esm/type.d.ts +8 -8
- package/esm/utils.d.ts +7 -0
- package/esm/utils.js +45 -0
- package/esm/utils.js.map +1 -1
- package/package.json +2 -3
- package/src/fortuneferry.ts +30 -6
- package/src/hkkf.ts +27 -6
- package/src/index.ts +8 -3
- package/src/sunferry.ts +27 -4
- package/src/type.ts +2 -2
- package/src/utils.ts +65 -0
package/esm/hkkf.js
CHANGED
|
@@ -1,29 +1,50 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export default function fetchEtas({
|
|
3
|
-
if (seq
|
|
1
|
+
import { getUpcomingFerry } from "./utils";
|
|
2
|
+
export default function fetchEtas({ freq, seq, holidays, serviceDayMap, }) {
|
|
3
|
+
if (seq >= 1)
|
|
4
4
|
return Promise.resolve([]);
|
|
5
|
-
|
|
5
|
+
const now = new Date();
|
|
6
|
+
return Promise.resolve(getUpcomingFerry({ holidays, serviceDayMap, freq, date: new Date() })
|
|
7
|
+
.filter(v => (new Date(v)).getTime() - now.getTime() < 180 * 60 * 1000)
|
|
8
|
+
.map(eta => ({
|
|
9
|
+
eta: eta,
|
|
10
|
+
remark: {
|
|
11
|
+
zh: "預定班次",
|
|
12
|
+
en: "Scheduled",
|
|
13
|
+
},
|
|
14
|
+
dest: {
|
|
15
|
+
zh: "",
|
|
16
|
+
en: "",
|
|
17
|
+
},
|
|
18
|
+
co: "fortuneferry",
|
|
19
|
+
})));
|
|
20
|
+
/*
|
|
21
|
+
* the official API is broken most of the time, keep it for reference
|
|
22
|
+
return fetch(
|
|
23
|
+
`https://www.hkkfeta.com/opendata/eta/${route.slice(2)}/${bound === "I" ? "inbound" : "outbound"}`,
|
|
24
|
+
{
|
|
6
25
|
cache: isSafari ? "default" : "no-store",
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
26
|
+
},
|
|
27
|
+
)
|
|
28
|
+
.then((response) => response.json())
|
|
29
|
+
.then(({ data }) => {
|
|
30
|
+
if (!data) return [];
|
|
31
|
+
|
|
12
32
|
return data
|
|
13
|
-
|
|
33
|
+
.map(({ETA}: any) => {
|
|
14
34
|
return {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
|
|
35
|
+
eta: ETA,
|
|
36
|
+
remark: {
|
|
37
|
+
zh: "",
|
|
38
|
+
en: "",
|
|
39
|
+
},
|
|
40
|
+
dest: {
|
|
41
|
+
zh: "",
|
|
42
|
+
en: "",
|
|
43
|
+
},
|
|
44
|
+
co: "hkkf",
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
*/
|
|
28
49
|
}
|
|
29
50
|
//# sourceMappingURL=hkkf.js.map
|
package/esm/hkkf.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hkkf.js","sourceRoot":"","sources":["../src/hkkf.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"hkkf.js","sourceRoot":"","sources":["../src/hkkf.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAY,MAAM,SAAS,CAAC;AASrD,MAAM,CAAC,OAAO,UAAU,SAAS,CAAC,EAChC,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,aAAa,GACnB;IACf,IAAK,GAAG,IAAI,CAAC;QAAG,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;IAC1C,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAA;IACtB,OAAO,OAAO,CAAC,OAAO,CACpB,gBAAgB,CAAC,EAAC,QAAQ,EAAE,aAAa,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,EAAC,CAAC;SAChE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC,OAAO,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,IAAI,CAAE;SACvE,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACX,GAAG,EAAE,GAAG;QACN,MAAM,EAAE;YACN,EAAE,EAAE,MAAM;YACV,EAAE,EAAE,WAAW;SAChB;QACD,IAAI,EAAE;YACJ,EAAE,EAAE,EAAE;YACN,EAAE,EAAE,EAAE;SACP;QACD,EAAE,EAAE,cAAc;KACrB,CAAC,CAAC,CACN,CAAA;IACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA4BI;AACN,CAAC"}
|
package/esm/index.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { RouteListEntry, EtaDb, Eta, StopList } from "./type";
|
|
2
2
|
interface fetchEtasProps extends RouteListEntry {
|
|
3
3
|
stopList: StopList;
|
|
4
|
+
holidays: EtaDb["holidays"];
|
|
5
|
+
serviceDayMap: EtaDb["serviceDayMap"];
|
|
4
6
|
language: "zh" | "en";
|
|
5
7
|
seq: number;
|
|
6
8
|
}
|
|
7
|
-
export declare function fetchEtas({ route, stops, bound, dest, seq, serviceType, co, nlbId, gtfsId, stopList, language, }: fetchEtasProps): Promise<Eta[]>;
|
|
9
|
+
export declare function fetchEtas({ route, stops, bound, dest, freq, seq, serviceType, co, nlbId, gtfsId, stopList, language, holidays, serviceDayMap, }: fetchEtasProps): Promise<Eta[]>;
|
|
8
10
|
export declare function fetchEtaDb(): Promise<EtaDb>;
|
|
9
11
|
export declare function fetchEtaDbMd5(): Promise<string>;
|
|
10
12
|
export type * from "./type";
|
package/esm/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import mtr from "./mtr";
|
|
|
8
8
|
import sunferry from "./sunferry";
|
|
9
9
|
import fortuneferry from "./fortuneferry";
|
|
10
10
|
import hkkf from "./hkkf";
|
|
11
|
-
export async function fetchEtas({ route, stops, bound, dest, seq, serviceType, co, nlbId, gtfsId, stopList, language, }) {
|
|
11
|
+
export async function fetchEtas({ route, stops, bound, dest, freq, seq, serviceType, co, nlbId, gtfsId, stopList, language, holidays, serviceDayMap, }) {
|
|
12
12
|
try {
|
|
13
13
|
let _etas = [];
|
|
14
14
|
for (const company_id of co) {
|
|
@@ -48,14 +48,14 @@ export async function fetchEtas({ route, stops, bound, dest, seq, serviceType, c
|
|
|
48
48
|
}
|
|
49
49
|
else if (company_id === "fortuneferry" && stops.fortuneferry) {
|
|
50
50
|
_etas = _etas.concat(await fortuneferry({
|
|
51
|
-
|
|
51
|
+
stops, seq, stopList, freq, serviceDayMap, holidays,
|
|
52
52
|
}));
|
|
53
53
|
}
|
|
54
54
|
else if (company_id === "sunferry" && stops.sunferry) {
|
|
55
|
-
_etas = _etas.concat(await sunferry({ route, seq }));
|
|
55
|
+
_etas = _etas.concat(await sunferry({ route, seq, holidays, serviceDayMap, freq }));
|
|
56
56
|
}
|
|
57
57
|
else if (company_id === "hkkf" && stops.hkkf) {
|
|
58
|
-
_etas = _etas.concat(await hkkf({
|
|
58
|
+
_etas = _etas.concat(await hkkf({ freq, seq, holidays, serviceDayMap }));
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
return _etas.sort((a, b) => {
|
package/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,OAAO,CAAC;AACxB,OAAO,GAAG,MAAM,OAAO,CAAC;AACxB,OAAO,GAAG,MAAM,OAAO,CAAC;AACxB,OAAO,SAAS,MAAM,aAAa,CAAC;AACpC,OAAO,GAAG,MAAM,OAAO,CAAC;AACxB,OAAO,SAAS,MAAM,aAAa,CAAC;AACpC,OAAO,GAAG,MAAM,OAAO,CAAC;AACxB,OAAO,QAAQ,MAAM,YAAY,CAAA;AACjC,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAC1C,OAAO,IAAI,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/esm/sunferry.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import type { Eta } from "./type";
|
|
1
|
+
import type { Eta, EtaDb, RouteListEntry } from "./type";
|
|
2
2
|
interface fetchEtasProps {
|
|
3
|
+
freq: RouteListEntry["freq"];
|
|
3
4
|
route: string;
|
|
4
5
|
seq: number;
|
|
6
|
+
holidays: EtaDb["holidays"];
|
|
7
|
+
serviceDayMap: EtaDb["serviceDayMap"];
|
|
5
8
|
}
|
|
6
|
-
export default function fetchEtas({ route, seq }: fetchEtasProps): Promise<Eta[]>;
|
|
9
|
+
export default function fetchEtas({ route, seq, freq, holidays, serviceDayMap, }: fetchEtasProps): Promise<Eta[]>;
|
|
7
10
|
export {};
|
package/esm/sunferry.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { isSafari } from "./utils";
|
|
2
|
-
export default function fetchEtas({ route, seq }) {
|
|
1
|
+
import { getUpcomingFerry, isSafari } from "./utils";
|
|
2
|
+
export default function fetchEtas({ route, seq, freq, holidays, serviceDayMap, }) {
|
|
3
3
|
if (seq === 1)
|
|
4
4
|
return Promise.resolve([]);
|
|
5
5
|
return fetch(`https://www.sunferry.com.hk/eta/?route=${route}`, {
|
|
@@ -7,6 +7,7 @@ export default function fetchEtas({ route, seq }) {
|
|
|
7
7
|
})
|
|
8
8
|
.then((response) => response.json())
|
|
9
9
|
.then(({ data }) => {
|
|
10
|
+
throw new Error("");
|
|
10
11
|
if (!data)
|
|
11
12
|
return [];
|
|
12
13
|
return data
|
|
@@ -30,6 +31,24 @@ export default function fetchEtas({ route, seq }) {
|
|
|
30
31
|
co: "sunferry",
|
|
31
32
|
};
|
|
32
33
|
});
|
|
34
|
+
})
|
|
35
|
+
.catch(() => {
|
|
36
|
+
// the API gives CORS error, the below handling is for browser
|
|
37
|
+
const now = new Date();
|
|
38
|
+
return getUpcomingFerry({ holidays, serviceDayMap, freq, date: new Date() })
|
|
39
|
+
.filter(v => (new Date(v)).getTime() - now.getTime() < 180 * 60 * 1000)
|
|
40
|
+
.map(eta => ({
|
|
41
|
+
eta: eta,
|
|
42
|
+
remark: {
|
|
43
|
+
zh: "預定班次",
|
|
44
|
+
en: "Scheduled",
|
|
45
|
+
},
|
|
46
|
+
dest: {
|
|
47
|
+
zh: "",
|
|
48
|
+
en: "",
|
|
49
|
+
},
|
|
50
|
+
co: "sunferry",
|
|
51
|
+
}));
|
|
33
52
|
});
|
|
34
53
|
}
|
|
35
54
|
//# sourceMappingURL=sunferry.js.map
|
package/esm/sunferry.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sunferry.js","sourceRoot":"","sources":["../src/sunferry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"sunferry.js","sourceRoot":"","sources":["../src/sunferry.ts"],"names":[],"mappings":"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"}
|
package/esm/type.d.ts
CHANGED
|
@@ -49,13 +49,13 @@ export type EtaDb = {
|
|
|
49
49
|
stopList: StopList;
|
|
50
50
|
stopMap: StopMap;
|
|
51
51
|
serviceDayMap: Record<string, [
|
|
52
|
-
0 | 1,
|
|
53
|
-
0 | 1,
|
|
54
|
-
0 | 1,
|
|
55
|
-
0 | 1,
|
|
56
|
-
0 | 1,
|
|
57
|
-
0 | 1,
|
|
58
|
-
0 | 1
|
|
52
|
+
"0" | "1",
|
|
53
|
+
"0" | "1",
|
|
54
|
+
"0" | "1",
|
|
55
|
+
"0" | "1",
|
|
56
|
+
"0" | "1",
|
|
57
|
+
"0" | "1",
|
|
58
|
+
"0" | "1"
|
|
59
59
|
]>;
|
|
60
60
|
};
|
|
61
61
|
export type Eta = {
|
|
@@ -70,5 +70,5 @@ export type Eta = {
|
|
|
70
70
|
};
|
|
71
71
|
co: Company;
|
|
72
72
|
lat?: number;
|
|
73
|
-
lng
|
|
73
|
+
lng?: number;
|
|
74
74
|
};
|
package/esm/utils.d.ts
CHANGED
|
@@ -1 +1,8 @@
|
|
|
1
|
+
import { EtaDb, RouteListEntry } from "./type";
|
|
1
2
|
export declare const isSafari: boolean;
|
|
3
|
+
export declare const getUpcomingFerry: ({ holidays, serviceDayMap, date, freq, }: {
|
|
4
|
+
holidays: string[];
|
|
5
|
+
serviceDayMap: EtaDb["serviceDayMap"];
|
|
6
|
+
freq: RouteListEntry["freq"];
|
|
7
|
+
date: Date;
|
|
8
|
+
}) => string[];
|
package/esm/utils.js
CHANGED
|
@@ -10,4 +10,49 @@ export const isSafari = (() => {
|
|
|
10
10
|
return false;
|
|
11
11
|
}
|
|
12
12
|
})();
|
|
13
|
+
// fancy handling for timezone, not recommend to use it unless you know what's going on
|
|
14
|
+
// i.e, calling isHoliday(holidays, new Date()) is checking if it was being a holiday at the moment of 8 hours ago
|
|
15
|
+
const isHoliday = (holidays, utcDate) => {
|
|
16
|
+
if (utcDate.getDay() === 0)
|
|
17
|
+
return true;
|
|
18
|
+
return holidays.includes(String(utcDate.getUTCFullYear()) +
|
|
19
|
+
String(utcDate.getUTCMonth() + 1).padStart(2, "0") +
|
|
20
|
+
String(utcDate.getUTCDate()).padStart(2, "0"));
|
|
21
|
+
};
|
|
22
|
+
export const getUpcomingFerry = ({ holidays, serviceDayMap, date, freq, }) => {
|
|
23
|
+
if (freq === null) {
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
const getEta = (serviceFreq, date) => (Object.keys(serviceFreq).sort((a, b) => a < b ? -1 : 1).reduce((acc, tp) => {
|
|
27
|
+
const ferryTime = new Date(date.getTime());
|
|
28
|
+
ferryTime.setUTCHours(parseInt(tp.slice(0, 2), 10));
|
|
29
|
+
ferryTime.setUTCMinutes(parseInt(tp.slice(2), 10));
|
|
30
|
+
if (ferryTime >= date) {
|
|
31
|
+
acc.push(String(ferryTime.getUTCFullYear()) + "-" +
|
|
32
|
+
String(ferryTime.getUTCMonth() + 1).padStart(2, "0") + "-" +
|
|
33
|
+
String(ferryTime.getUTCDate()).padStart(2, "0") + "T" +
|
|
34
|
+
String(ferryTime.getUTCHours()).padStart(2, "0") + ":" +
|
|
35
|
+
String(ferryTime.getUTCMinutes()).padStart(2, "0") + ":00" +
|
|
36
|
+
".000+08:00");
|
|
37
|
+
}
|
|
38
|
+
return acc;
|
|
39
|
+
}, []));
|
|
40
|
+
// obtain all ETAs sampling for next 24 hours, fancy handling for timezone
|
|
41
|
+
const ret = Array(24).fill(0).reduce((acc, _, idx) => {
|
|
42
|
+
const refDate = new Date(date.getTime());
|
|
43
|
+
refDate.setUTCHours(refDate.getUTCHours() + 8 + idx);
|
|
44
|
+
for (let serviceKey in freq) {
|
|
45
|
+
if (isHoliday(holidays, refDate)) {
|
|
46
|
+
if (serviceDayMap[serviceKey][0] === '1') {
|
|
47
|
+
return acc.concat(getEta(freq[serviceKey], refDate));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
else if (serviceDayMap[serviceKey][refDate.getDay()]) {
|
|
51
|
+
return acc.concat(getEta(freq[serviceKey], refDate)).sort();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return acc;
|
|
55
|
+
}, []);
|
|
56
|
+
return [...new Set(ret)].sort((a, b) => a < b ? -1 : 1);
|
|
57
|
+
};
|
|
13
58
|
//# sourceMappingURL=utils.js.map
|
package/esm/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hk-bus-eta",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.3",
|
|
4
4
|
"description": "Query the ETA (Estimated Time of Arrival) of HK Bus/Minibus/MTR/Lightrail",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "esm/index.js",
|
|
@@ -16,8 +16,7 @@
|
|
|
16
16
|
"build:esm": "tsc --target es2018 --outDir esm",
|
|
17
17
|
"build:cjs": "tsc --target es2015 --module commonjs --outDir dist",
|
|
18
18
|
"build": "yarn build:cjs && yarn build:esm",
|
|
19
|
-
"prepublish": "yarn build"
|
|
20
|
-
"publish": "npm publish"
|
|
19
|
+
"prepublish": "yarn build"
|
|
21
20
|
},
|
|
22
21
|
"repository": {
|
|
23
22
|
"type": "git",
|
package/src/fortuneferry.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import type { Eta, RouteListEntry, StopList } from "./type";
|
|
2
|
-
import { isSafari } from "./utils";
|
|
1
|
+
import type { Eta, EtaDb, RouteListEntry, StopList } from "./type";
|
|
2
|
+
import { getUpcomingFerry, isSafari } from "./utils";
|
|
3
3
|
|
|
4
4
|
interface fetchEtasProps {
|
|
5
|
-
route: string;
|
|
6
5
|
stops: {
|
|
7
6
|
fortuneferry: string[];
|
|
8
7
|
}
|
|
9
8
|
seq: number;
|
|
10
9
|
stopList: StopList;
|
|
10
|
+
freq: RouteListEntry["freq"],
|
|
11
|
+
holidays: EtaDb["holidays"];
|
|
12
|
+
serviceDayMap: EtaDb["serviceDayMap"];
|
|
11
13
|
}
|
|
12
14
|
|
|
13
15
|
const getCode = (zhName: string) => {
|
|
@@ -34,12 +36,33 @@ const getCode = (zhName: string) => {
|
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
export default function fetchEtas({
|
|
37
|
-
|
|
39
|
+
stops: { fortuneferry: stops }, seq,
|
|
40
|
+
holidays, freq, serviceDayMap
|
|
38
41
|
}: fetchEtasProps): Promise<Eta[]> {
|
|
39
42
|
if ( stops.length === seq - 1 ) return Promise.resolve([]);
|
|
40
|
-
const
|
|
41
|
-
|
|
43
|
+
const now = new Date()
|
|
44
|
+
return Promise.resolve(
|
|
45
|
+
getUpcomingFerry({holidays, serviceDayMap, freq, date: new Date()})
|
|
46
|
+
.filter(v => (new Date(v)).getTime() - now.getTime() < 180 * 60 * 1000 )
|
|
47
|
+
.map(eta => ({
|
|
48
|
+
eta: eta,
|
|
49
|
+
remark: {
|
|
50
|
+
zh: "預定班次",
|
|
51
|
+
en: "Scheduled",
|
|
52
|
+
},
|
|
53
|
+
dest: {
|
|
54
|
+
zh: "",
|
|
55
|
+
en: "",
|
|
56
|
+
},
|
|
57
|
+
co: "fortuneferry",
|
|
58
|
+
}))
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
/*
|
|
62
|
+
* the official API is broken most of the time, keep it for reference
|
|
42
63
|
|
|
64
|
+
const v = getCode(stopList[stops[seq+1]].name.zh)
|
|
65
|
+
const u = getCode(stopList[stops[seq]].name.zh)
|
|
43
66
|
return fetch(
|
|
44
67
|
`https://www.hongkongwatertaxi.com.hk/eta/?route=${u}${v}`,
|
|
45
68
|
{
|
|
@@ -72,4 +95,5 @@ export default function fetchEtas({
|
|
|
72
95
|
}
|
|
73
96
|
});
|
|
74
97
|
});
|
|
98
|
+
*/
|
|
75
99
|
}
|
package/src/hkkf.ts
CHANGED
|
@@ -1,16 +1,36 @@
|
|
|
1
|
-
import type { Eta, RouteListEntry } from "./type";
|
|
2
|
-
import { isSafari } from "./utils";
|
|
1
|
+
import type { Eta, EtaDb, RouteListEntry } from "./type";
|
|
2
|
+
import { getUpcomingFerry, isSafari } from "./utils";
|
|
3
3
|
|
|
4
4
|
interface fetchEtasProps {
|
|
5
|
-
|
|
6
|
-
bound: RouteListEntry["bound"]["hkkf"];
|
|
5
|
+
freq: RouteListEntry["freq"];
|
|
7
6
|
seq: number;
|
|
7
|
+
holidays: EtaDb["holidays"];
|
|
8
|
+
serviceDayMap: EtaDb["serviceDayMap"];
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
export default function fetchEtas({
|
|
11
|
-
|
|
12
|
+
freq, seq, holidays, serviceDayMap,
|
|
12
13
|
}: fetchEtasProps): Promise<Eta[]> {
|
|
13
|
-
if ( seq
|
|
14
|
+
if ( seq >= 1 ) return Promise.resolve([])
|
|
15
|
+
const now = new Date()
|
|
16
|
+
return Promise.resolve(
|
|
17
|
+
getUpcomingFerry({holidays, serviceDayMap, freq, date: new Date()})
|
|
18
|
+
.filter(v => (new Date(v)).getTime() - now.getTime() < 180 * 60 * 1000 )
|
|
19
|
+
.map(eta => ({
|
|
20
|
+
eta: eta,
|
|
21
|
+
remark: {
|
|
22
|
+
zh: "預定班次",
|
|
23
|
+
en: "Scheduled",
|
|
24
|
+
},
|
|
25
|
+
dest: {
|
|
26
|
+
zh: "",
|
|
27
|
+
en: "",
|
|
28
|
+
},
|
|
29
|
+
co: "fortuneferry",
|
|
30
|
+
}))
|
|
31
|
+
)
|
|
32
|
+
/*
|
|
33
|
+
* the official API is broken most of the time, keep it for reference
|
|
14
34
|
return fetch(
|
|
15
35
|
`https://www.hkkfeta.com/opendata/eta/${route.slice(2)}/${bound === "I" ? "inbound" : "outbound"}`,
|
|
16
36
|
{
|
|
@@ -37,4 +57,5 @@ export default function fetchEtas({
|
|
|
37
57
|
}
|
|
38
58
|
});
|
|
39
59
|
});
|
|
60
|
+
*/
|
|
40
61
|
}
|
package/src/index.ts
CHANGED
|
@@ -12,6 +12,8 @@ import { RouteListEntry, EtaDb, Eta, StopList } from "./type";
|
|
|
12
12
|
|
|
13
13
|
interface fetchEtasProps extends RouteListEntry {
|
|
14
14
|
stopList: StopList;
|
|
15
|
+
holidays: EtaDb["holidays"],
|
|
16
|
+
serviceDayMap: EtaDb["serviceDayMap"],
|
|
15
17
|
language: "zh" | "en";
|
|
16
18
|
seq: number;
|
|
17
19
|
}
|
|
@@ -21,6 +23,7 @@ export async function fetchEtas({
|
|
|
21
23
|
stops,
|
|
22
24
|
bound,
|
|
23
25
|
dest,
|
|
26
|
+
freq,
|
|
24
27
|
seq,
|
|
25
28
|
serviceType,
|
|
26
29
|
co,
|
|
@@ -28,6 +31,8 @@ export async function fetchEtas({
|
|
|
28
31
|
gtfsId,
|
|
29
32
|
stopList,
|
|
30
33
|
language,
|
|
34
|
+
holidays,
|
|
35
|
+
serviceDayMap,
|
|
31
36
|
}: fetchEtasProps): Promise<Eta[]> {
|
|
32
37
|
try {
|
|
33
38
|
let _etas: Eta[] = [];
|
|
@@ -74,13 +79,13 @@ export async function fetchEtas({
|
|
|
74
79
|
} else if (company_id === "fortuneferry" && stops.fortuneferry) {
|
|
75
80
|
_etas = _etas.concat(
|
|
76
81
|
await fortuneferry({
|
|
77
|
-
|
|
82
|
+
stops, seq, stopList, freq, serviceDayMap, holidays,
|
|
78
83
|
})
|
|
79
84
|
)
|
|
80
85
|
} else if (company_id === "sunferry" && stops.sunferry) {
|
|
81
|
-
_etas = _etas.concat(await sunferry({route, seq}))
|
|
86
|
+
_etas = _etas.concat(await sunferry({route, seq, holidays, serviceDayMap, freq}))
|
|
82
87
|
} else if (company_id === "hkkf" && stops.hkkf) {
|
|
83
|
-
_etas = _etas.concat(await hkkf({
|
|
88
|
+
_etas = _etas.concat(await hkkf({freq, seq, holidays, serviceDayMap}))
|
|
84
89
|
}
|
|
85
90
|
}
|
|
86
91
|
|
package/src/sunferry.ts
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
|
-
import type { Eta } from "./type";
|
|
2
|
-
import { isSafari } from "./utils";
|
|
1
|
+
import type { Eta, EtaDb, Freq, RouteListEntry } from "./type";
|
|
2
|
+
import { getUpcomingFerry, isSafari } from "./utils";
|
|
3
3
|
|
|
4
4
|
interface fetchEtasProps {
|
|
5
|
+
freq: RouteListEntry["freq"],
|
|
5
6
|
route: string;
|
|
6
7
|
seq: number;
|
|
8
|
+
holidays: EtaDb["holidays"],
|
|
9
|
+
serviceDayMap: EtaDb["serviceDayMap"],
|
|
7
10
|
}
|
|
8
11
|
|
|
9
12
|
export default function fetchEtas({
|
|
10
|
-
route, seq
|
|
13
|
+
route, seq,
|
|
14
|
+
freq, holidays, serviceDayMap,
|
|
11
15
|
}: fetchEtasProps): Promise<Eta[]> {
|
|
12
16
|
if ( seq === 1 ) return Promise.resolve([])
|
|
17
|
+
|
|
13
18
|
return fetch(
|
|
14
19
|
`https://www.sunferry.com.hk/eta/?route=${route}`,
|
|
15
20
|
{
|
|
@@ -18,8 +23,8 @@ export default function fetchEtas({
|
|
|
18
23
|
)
|
|
19
24
|
.then((response) => response.json())
|
|
20
25
|
.then(({ data }) => {
|
|
26
|
+
throw new Error("")
|
|
21
27
|
if (!data) return [];
|
|
22
|
-
|
|
23
28
|
return data
|
|
24
29
|
.map(({depart_time, rmk_en, rmk_tc, route_tc, route_en}: any) => {
|
|
25
30
|
const date = new Date();
|
|
@@ -41,5 +46,23 @@ export default function fetchEtas({
|
|
|
41
46
|
co: "sunferry",
|
|
42
47
|
}
|
|
43
48
|
});
|
|
49
|
+
})
|
|
50
|
+
.catch(() => {
|
|
51
|
+
// the API gives CORS error, the below handling is for browser
|
|
52
|
+
const now = new Date()
|
|
53
|
+
return getUpcomingFerry({holidays, serviceDayMap, freq, date: new Date()})
|
|
54
|
+
.filter(v => (new Date(v)).getTime() - now.getTime() < 180 * 60 * 1000 )
|
|
55
|
+
.map(eta => ({
|
|
56
|
+
eta: eta,
|
|
57
|
+
remark: {
|
|
58
|
+
zh: "預定班次",
|
|
59
|
+
en: "Scheduled",
|
|
60
|
+
},
|
|
61
|
+
dest: {
|
|
62
|
+
zh: "",
|
|
63
|
+
en: "",
|
|
64
|
+
},
|
|
65
|
+
co: "sunferry",
|
|
66
|
+
}))
|
|
44
67
|
});
|
|
45
68
|
}
|
package/src/type.ts
CHANGED
|
@@ -70,7 +70,7 @@ export type EtaDb = {
|
|
|
70
70
|
stopMap: StopMap;
|
|
71
71
|
serviceDayMap: Record<
|
|
72
72
|
string,
|
|
73
|
-
[0 | 1, 0 | 1, 0 | 1, 0 | 1, 0 | 1, 0 | 1, 0 | 1]
|
|
73
|
+
["0" | "1", "0" | "1", "0" | "1", "0" | "1", "0" | "1", "0" | "1", "0" | "1"]
|
|
74
74
|
>;
|
|
75
75
|
};
|
|
76
76
|
|
|
@@ -86,5 +86,5 @@ export type Eta = {
|
|
|
86
86
|
};
|
|
87
87
|
co: Company;
|
|
88
88
|
lat?: number;
|
|
89
|
-
lng
|
|
89
|
+
lng?: number;
|
|
90
90
|
};
|
package/src/utils.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { EtaDb, Freq, RouteListEntry } from "./type";
|
|
2
|
+
|
|
1
3
|
export const isSafari = (() => {
|
|
2
4
|
try {
|
|
3
5
|
return Boolean(
|
|
@@ -13,3 +15,66 @@ export const isSafari = (() => {
|
|
|
13
15
|
return false;
|
|
14
16
|
}
|
|
15
17
|
})();
|
|
18
|
+
|
|
19
|
+
// fancy handling for timezone, not recommend to use it unless you know what's going on
|
|
20
|
+
// i.e, calling isHoliday(holidays, new Date()) is checking if it was being a holiday at the moment of 8 hours ago
|
|
21
|
+
const isHoliday = (holidays: string[], utcDate: Date): boolean => {
|
|
22
|
+
if ( utcDate.getDay() === 0 ) return true
|
|
23
|
+
return holidays.includes(
|
|
24
|
+
String(utcDate.getUTCFullYear()) +
|
|
25
|
+
String(utcDate.getUTCMonth()+1).padStart(2, "0") +
|
|
26
|
+
String(utcDate.getUTCDate()).padStart(2, "0")
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const getUpcomingFerry = ({
|
|
31
|
+
holidays,
|
|
32
|
+
serviceDayMap,
|
|
33
|
+
date,
|
|
34
|
+
freq,
|
|
35
|
+
}: {
|
|
36
|
+
holidays: string[],
|
|
37
|
+
serviceDayMap: EtaDb["serviceDayMap"],
|
|
38
|
+
freq: RouteListEntry["freq"],
|
|
39
|
+
date: Date
|
|
40
|
+
}): string[] => {
|
|
41
|
+
if ( freq === null ) {
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const getEta = (serviceFreq: Record<string, any>, date: Date): string[] => (
|
|
46
|
+
Object.keys(serviceFreq).sort((a, b) => a < b ? -1 : 1).reduce((acc, tp) => {
|
|
47
|
+
const ferryTime = new Date(date.getTime())
|
|
48
|
+
ferryTime.setUTCHours(parseInt(tp.slice(0, 2), 10))
|
|
49
|
+
ferryTime.setUTCMinutes(parseInt(tp.slice(2), 10))
|
|
50
|
+
if ( ferryTime >= date ) {
|
|
51
|
+
acc.push(
|
|
52
|
+
String(ferryTime.getUTCFullYear()) + "-" +
|
|
53
|
+
String(ferryTime.getUTCMonth()+1).padStart(2, "0") + "-" +
|
|
54
|
+
String(ferryTime.getUTCDate()).padStart(2, "0") + "T" +
|
|
55
|
+
String(ferryTime.getUTCHours()).padStart(2, "0") + ":" +
|
|
56
|
+
String(ferryTime.getUTCMinutes()).padStart(2, "0") + ":00" +
|
|
57
|
+
".000+08:00"
|
|
58
|
+
)
|
|
59
|
+
}
|
|
60
|
+
return acc
|
|
61
|
+
}, [] as string[])
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
// obtain all ETAs sampling for next 24 hours, fancy handling for timezone
|
|
65
|
+
const ret = Array(24).fill(0).reduce((acc, _, idx) => {
|
|
66
|
+
const refDate = new Date(date.getTime())
|
|
67
|
+
refDate.setUTCHours(refDate.getUTCHours() + 8 + idx)
|
|
68
|
+
for ( let serviceKey in freq ) {
|
|
69
|
+
if ( isHoliday(holidays, refDate) ) {
|
|
70
|
+
if ( serviceDayMap[serviceKey][0] === '1' ) {
|
|
71
|
+
return acc.concat(getEta(freq[serviceKey], refDate))
|
|
72
|
+
}
|
|
73
|
+
} else if ( serviceDayMap[serviceKey][refDate.getDay()] ) {
|
|
74
|
+
return acc.concat(getEta(freq[serviceKey], refDate)).sort()
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return acc
|
|
78
|
+
}, [] as string[]);
|
|
79
|
+
return ([...new Set(ret)] as string[]).sort((a,b) => a < b ? -1 : 1)
|
|
80
|
+
}
|