scrapemyferry 1.0.0 → 1.0.2

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.
Files changed (152) hide show
  1. package/README.md +1 -1
  2. package/dist/cli.d.ts +2 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +90 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/index.d.ts +2 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +18 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/lib/index.d.ts +3 -0
  11. package/dist/lib/index.d.ts.map +1 -0
  12. package/dist/lib/index.js +7 -0
  13. package/dist/lib/index.js.map +1 -0
  14. package/dist/lib/setup.d.ts +2 -0
  15. package/dist/lib/setup.d.ts.map +1 -0
  16. package/dist/lib/setup.js +13 -0
  17. package/dist/lib/setup.js.map +1 -0
  18. package/dist/lib/sources/bcf/config.d.ts +7 -0
  19. package/dist/lib/sources/bcf/config.d.ts.map +1 -0
  20. package/dist/lib/sources/bcf/config.js +10 -0
  21. package/dist/lib/sources/bcf/config.js.map +1 -0
  22. package/dist/lib/sources/bcf/currentConditions.d.ts +3 -0
  23. package/dist/lib/sources/bcf/currentConditions.d.ts.map +1 -0
  24. package/dist/lib/sources/bcf/currentConditions.js +113 -0
  25. package/dist/lib/sources/bcf/currentConditions.js.map +1 -0
  26. package/dist/lib/sources/bcf/dailySchedule.d.ts +3 -0
  27. package/dist/lib/sources/bcf/dailySchedule.d.ts.map +1 -0
  28. package/dist/lib/sources/bcf/dailySchedule.js +43 -0
  29. package/dist/lib/sources/bcf/dailySchedule.js.map +1 -0
  30. package/dist/lib/sources/bcf/departures.d.ts +3 -0
  31. package/dist/lib/sources/bcf/departures.d.ts.map +1 -0
  32. package/dist/lib/sources/bcf/departures.js +101 -0
  33. package/dist/lib/sources/bcf/departures.js.map +1 -0
  34. package/dist/lib/sources/bcf/index.d.ts +8 -0
  35. package/dist/lib/sources/bcf/index.d.ts.map +1 -0
  36. package/dist/lib/sources/bcf/index.js +18 -0
  37. package/dist/lib/sources/bcf/index.js.map +1 -0
  38. package/dist/lib/sources/bcf/routes.d.ts +3 -0
  39. package/dist/lib/sources/bcf/routes.d.ts.map +1 -0
  40. package/dist/lib/sources/bcf/routes.js +93 -0
  41. package/dist/lib/sources/bcf/routes.js.map +1 -0
  42. package/dist/lib/sources/bcf/sailing.d.ts +3 -0
  43. package/dist/lib/sources/bcf/sailing.d.ts.map +1 -0
  44. package/dist/lib/sources/bcf/sailing.js +60 -0
  45. package/dist/lib/sources/bcf/sailing.js.map +1 -0
  46. package/dist/lib/sources/bcf/seasonalSchedule.d.ts +3 -0
  47. package/dist/lib/sources/bcf/seasonalSchedule.d.ts.map +1 -0
  48. package/dist/lib/sources/bcf/seasonalSchedule.js +76 -0
  49. package/dist/lib/sources/bcf/seasonalSchedule.js.map +1 -0
  50. package/dist/lib/sources/bcf/tests/config.test.d.ts +2 -0
  51. package/dist/lib/sources/bcf/tests/config.test.d.ts.map +1 -0
  52. package/dist/lib/sources/bcf/tests/config.test.js +24 -0
  53. package/dist/lib/sources/bcf/tests/config.test.js.map +1 -0
  54. package/dist/lib/sources/bcf/tests/currentConditions.live.test.d.ts +2 -0
  55. package/dist/lib/sources/bcf/tests/currentConditions.live.test.d.ts.map +1 -0
  56. package/dist/lib/sources/bcf/tests/currentConditions.live.test.js +26 -0
  57. package/dist/lib/sources/bcf/tests/currentConditions.live.test.js.map +1 -0
  58. package/dist/lib/sources/bcf/tests/currentConditions.test.d.ts +2 -0
  59. package/dist/lib/sources/bcf/tests/currentConditions.test.d.ts.map +1 -0
  60. package/dist/lib/sources/bcf/tests/currentConditions.test.js +169 -0
  61. package/dist/lib/sources/bcf/tests/currentConditions.test.js.map +1 -0
  62. package/dist/lib/sources/bcf/tests/dailySchedule.live.test.d.ts +2 -0
  63. package/dist/lib/sources/bcf/tests/dailySchedule.live.test.d.ts.map +1 -0
  64. package/dist/lib/sources/bcf/tests/dailySchedule.live.test.js +19 -0
  65. package/dist/lib/sources/bcf/tests/dailySchedule.live.test.js.map +1 -0
  66. package/dist/lib/sources/bcf/tests/dailySchedule.test.d.ts +2 -0
  67. package/dist/lib/sources/bcf/tests/dailySchedule.test.d.ts.map +1 -0
  68. package/dist/lib/sources/bcf/tests/dailySchedule.test.js +76 -0
  69. package/dist/lib/sources/bcf/tests/dailySchedule.test.js.map +1 -0
  70. package/dist/lib/sources/bcf/tests/departures.live.test.d.ts +2 -0
  71. package/dist/lib/sources/bcf/tests/departures.live.test.d.ts.map +1 -0
  72. package/dist/lib/sources/bcf/tests/departures.live.test.js +25 -0
  73. package/dist/lib/sources/bcf/tests/departures.live.test.js.map +1 -0
  74. package/dist/lib/sources/bcf/tests/departures.test.d.ts +2 -0
  75. package/dist/lib/sources/bcf/tests/departures.test.d.ts.map +1 -0
  76. package/dist/lib/sources/bcf/tests/departures.test.js +408 -0
  77. package/dist/lib/sources/bcf/tests/departures.test.js.map +1 -0
  78. package/dist/lib/sources/bcf/tests/fixtures/availability.json +1 -0
  79. package/dist/lib/sources/bcf/tests/fixtures/current-conditions/departures.json +1 -0
  80. package/dist/lib/sources/bcf/tests/fixtures/current-conditions.json +1 -0
  81. package/dist/lib/sources/bcf/tests/fixtures/routes-fares/schedules/daily.json +1 -0
  82. package/dist/lib/sources/bcf/tests/fixtures/routes-fares/schedules/seasonal.json +1 -0
  83. package/dist/lib/sources/bcf/tests/fixtures/routes-fares/schedules.json +1 -0
  84. package/dist/lib/sources/bcf/tests/routes.live.test.d.ts +2 -0
  85. package/dist/lib/sources/bcf/tests/routes.live.test.d.ts.map +1 -0
  86. package/dist/lib/sources/bcf/tests/routes.live.test.js +28 -0
  87. package/dist/lib/sources/bcf/tests/routes.live.test.js.map +1 -0
  88. package/dist/lib/sources/bcf/tests/routes.test.d.ts +2 -0
  89. package/dist/lib/sources/bcf/tests/routes.test.d.ts.map +1 -0
  90. package/dist/lib/sources/bcf/tests/routes.test.js +363 -0
  91. package/dist/lib/sources/bcf/tests/routes.test.js.map +1 -0
  92. package/dist/lib/sources/bcf/tests/sailing.live.test.d.ts +2 -0
  93. package/dist/lib/sources/bcf/tests/sailing.live.test.d.ts.map +1 -0
  94. package/dist/lib/sources/bcf/tests/sailing.live.test.js +25 -0
  95. package/dist/lib/sources/bcf/tests/sailing.live.test.js.map +1 -0
  96. package/dist/lib/sources/bcf/tests/sailing.test.d.ts +2 -0
  97. package/dist/lib/sources/bcf/tests/sailing.test.d.ts.map +1 -0
  98. package/dist/lib/sources/bcf/tests/sailing.test.js +53 -0
  99. package/dist/lib/sources/bcf/tests/sailing.test.js.map +1 -0
  100. package/dist/lib/sources/bcf/tests/seasonalSchedule.live.test.d.ts +2 -0
  101. package/dist/lib/sources/bcf/tests/seasonalSchedule.live.test.d.ts.map +1 -0
  102. package/dist/lib/sources/bcf/tests/seasonalSchedule.live.test.js +22 -0
  103. package/dist/lib/sources/bcf/tests/seasonalSchedule.live.test.js.map +1 -0
  104. package/dist/lib/sources/bcf/tests/seasonalSchedule.test.d.ts +2 -0
  105. package/dist/lib/sources/bcf/tests/seasonalSchedule.test.d.ts.map +1 -0
  106. package/dist/lib/sources/bcf/tests/seasonalSchedule.test.js +403 -0
  107. package/dist/lib/sources/bcf/tests/seasonalSchedule.test.js.map +1 -0
  108. package/dist/lib/sources/bcf/tests/urls.test.d.ts +2 -0
  109. package/dist/lib/sources/bcf/tests/urls.test.d.ts.map +1 -0
  110. package/dist/lib/sources/bcf/tests/urls.test.js +69 -0
  111. package/dist/lib/sources/bcf/tests/urls.test.js.map +1 -0
  112. package/dist/lib/sources/bcf/tests/utils.test.d.ts +2 -0
  113. package/dist/lib/sources/bcf/tests/utils.test.d.ts.map +1 -0
  114. package/dist/lib/sources/bcf/tests/utils.test.js +79 -0
  115. package/dist/lib/sources/bcf/tests/utils.test.js.map +1 -0
  116. package/dist/lib/sources/bcf/urls.d.ts +11 -0
  117. package/dist/lib/sources/bcf/urls.d.ts.map +1 -0
  118. package/dist/lib/sources/bcf/urls.js +68 -0
  119. package/dist/lib/sources/bcf/urls.js.map +1 -0
  120. package/dist/lib/sources/bcf/utils.d.ts +6 -0
  121. package/dist/lib/sources/bcf/utils.d.ts.map +1 -0
  122. package/dist/lib/sources/bcf/utils.js +47 -0
  123. package/dist/lib/sources/bcf/utils.js.map +1 -0
  124. package/dist/lib/sources/index.d.ts +2 -0
  125. package/dist/lib/sources/index.d.ts.map +1 -0
  126. package/dist/lib/sources/index.js +6 -0
  127. package/dist/lib/sources/index.js.map +1 -0
  128. package/dist/lib/sources/source.d.ts +3 -0
  129. package/dist/lib/sources/source.d.ts.map +1 -0
  130. package/dist/lib/sources/source.js +34 -0
  131. package/dist/lib/sources/source.js.map +1 -0
  132. package/dist/lib/sources/types.d.ts +111 -0
  133. package/dist/lib/sources/types.d.ts.map +1 -0
  134. package/dist/lib/sources/types.js +3 -0
  135. package/dist/lib/sources/types.js.map +1 -0
  136. package/dist/lib/test/jest-conditional.d.ts +11 -0
  137. package/dist/lib/test/jest-conditional.d.ts.map +1 -0
  138. package/dist/lib/test/jest-conditional.js +22 -0
  139. package/dist/lib/test/jest-conditional.js.map +1 -0
  140. package/dist/lib/test/setup-jest-env.d.ts +2 -0
  141. package/dist/lib/test/setup-jest-env.d.ts.map +1 -0
  142. package/dist/lib/test/setup-jest-env.js +30 -0
  143. package/dist/lib/test/setup-jest-env.js.map +1 -0
  144. package/dist/lib/test/setup-jest-global.d.ts +2 -0
  145. package/dist/lib/test/setup-jest-global.d.ts.map +1 -0
  146. package/dist/lib/test/setup-jest-global.js +7 -0
  147. package/dist/lib/test/setup-jest-global.js.map +1 -0
  148. package/dist/lib/test/setup-jest.d.ts +2 -0
  149. package/dist/lib/test/setup-jest.d.ts.map +1 -0
  150. package/dist/lib/test/setup-jest.js +5 -0
  151. package/dist/lib/test/setup-jest.js.map +1 -0
  152. package/package.json +3 -2
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.routes = routes;
7
+ const scrape_it_1 = __importDefault(require("scrape-it"));
8
+ const urls_1 = require("./urls");
9
+ function routes() {
10
+ const url = (0, urls_1.routesUrl)();
11
+ return (0, scrape_it_1.default)(url, {
12
+ regionNames: {
13
+ listItem: '#schedulesList header > span',
14
+ },
15
+ regions: {
16
+ listItem: '#schedulesList header + div',
17
+ data: {
18
+ from: {
19
+ listItem: '.container.card',
20
+ data: {
21
+ name: {
22
+ selector: 'button',
23
+ },
24
+ to: {
25
+ selector: 'p',
26
+ data: {
27
+ routes: {
28
+ listItem: 'a',
29
+ data: {
30
+ href: {
31
+ attr: 'href',
32
+ },
33
+ name: {},
34
+ },
35
+ },
36
+ },
37
+ },
38
+ },
39
+ },
40
+ },
41
+ },
42
+ }).then(transform);
43
+ function transform({ data: { regionNames, regions }, }) {
44
+ return {
45
+ url,
46
+ regions: regions
47
+ .filter(({ from }) => from.length > 0)
48
+ .map(({ from }, i) => ({
49
+ name: regionNames[i],
50
+ from: from
51
+ .filter(({ to: { routes } }) => routes.length > 0)
52
+ .map(({ name, to: { routes } }) => {
53
+ const [code] = routeCodesFromUrl(routes[0].href);
54
+ return {
55
+ name,
56
+ code,
57
+ to: routes.map(({ name, href }) => {
58
+ const urlPath = href.replace(urls_1.baseUrl, '');
59
+ const codes = routeCodesFromUrl(urlPath);
60
+ const special = urlPath.startsWith('/routes-fares/schedules/seasonal')
61
+ ? undefined
62
+ : true;
63
+ const code = special ? codes.join('-') : codes[1];
64
+ return special
65
+ ? {
66
+ name,
67
+ code,
68
+ urlPath,
69
+ special,
70
+ }
71
+ : {
72
+ name,
73
+ code,
74
+ urlPath,
75
+ };
76
+ }),
77
+ };
78
+ }),
79
+ })),
80
+ };
81
+ }
82
+ function routeCodesFromUrl(urlPath) {
83
+ const routeCodePair = urlPath.split('/').at(-1);
84
+ if (!routeCodePair)
85
+ throw new Error(`Invalid route URL path: ${urlPath}`);
86
+ const routeCodes = routeCodePair.split('-');
87
+ if (routeCodes.length !== 2) {
88
+ throw new Error(`Invalid route code: ${routeCodePair}`);
89
+ }
90
+ return routeCodes;
91
+ }
92
+ }
93
+ //# sourceMappingURL=routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../../../src/lib/sources/bcf/routes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Sailing } from '../types';
2
+ export declare function sailing(from: string, to: string, departureTime: string, departureDate?: string): Promise<Sailing>;
3
+ //# sourceMappingURL=sailing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sailing.d.ts","sourceRoot":"","sources":["../../../../src/lib/sources/bcf/sailing.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AAcvC,wBAAgB,OAAO,CACrB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,aAAa,EAAE,MAAM,EACrB,aAAa,CAAC,EAAE,MAAM,oBA2DvB"}
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.sailing = sailing;
7
+ const dayjs_1 = __importDefault(require("dayjs"));
8
+ const scrape_it_1 = __importDefault(require("scrape-it"));
9
+ const urls_1 = require("./urls");
10
+ const utils_1 = require("./utils");
11
+ const config_1 = require("./config");
12
+ function sailing(from, to, departureTime, departureDate) {
13
+ const departTimestamp = (0, utils_1.buildTimestamp)(departureTime, departureDate);
14
+ const url = (0, urls_1.availabilityUrl)(from, to, departTimestamp.toISOString());
15
+ return (0, scrape_it_1.default)(url, {
16
+ body: {
17
+ selector: '.modal-body',
18
+ data: {
19
+ time: {
20
+ selector: '.modal-time > span',
21
+ eq: 0,
22
+ },
23
+ totalSpace: {
24
+ selector: '.standard-vehicle-space > p > span',
25
+ eq: 0,
26
+ },
27
+ standardSpace: {
28
+ selector: '.standard-vehicle-space > p > span',
29
+ eq: 2,
30
+ },
31
+ mixedSpace: {
32
+ selector: '.mixed-vehicle-space > p > span',
33
+ eq: 1,
34
+ },
35
+ },
36
+ },
37
+ }).then(transform);
38
+ function transform({ data: { body: { time, totalSpace, standardSpace, mixedSpace }, }, }) {
39
+ const [total, standard, mixed] = [
40
+ totalSpace,
41
+ standardSpace,
42
+ mixedSpace,
43
+ ].map((space) => parseInt(space.replace('%', '')) / 100);
44
+ const isotime = (0, dayjs_1.default)(departTimestamp.format('YYYY-MM-DD') +
45
+ ' ' +
46
+ (0, dayjs_1.default)(time, 'h:mma').format('HH:mm:ss'), 'YYYY-MM-DD HH:mm:ss', true)
47
+ .tz(config_1.tz)
48
+ .toISOString();
49
+ return {
50
+ url,
51
+ time: isotime,
52
+ space: {
53
+ total,
54
+ standard,
55
+ mixed,
56
+ },
57
+ };
58
+ }
59
+ }
60
+ //# sourceMappingURL=sailing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sailing.js","sourceRoot":"","sources":["../../../../src/lib/sources/bcf/sailing.ts"],"names":[],"mappings":";;;;;AAgBA,0BA+DC;AA/ED,kDAAyB;AACzB,0DAAgC;AAEhC,iCAAwC;AACxC,mCAAwC;AACxC,qCAA6B;AAW7B,SAAgB,OAAO,CACrB,IAAY,EACZ,EAAU,EACV,aAAqB,EACrB,aAAsB;IAEtB,MAAM,eAAe,GAAG,IAAA,sBAAc,EAAC,aAAa,EAAE,aAAa,CAAC,CAAA;IACpE,MAAM,GAAG,GAAG,IAAA,sBAAe,EAAC,IAAI,EAAE,EAAE,EAAE,eAAe,CAAC,WAAW,EAAE,CAAC,CAAA;IAEpE,OAAO,IAAA,mBAAQ,EAAc,GAAG,EAAE;QAChC,IAAI,EAAE;YACJ,QAAQ,EAAE,aAAa;YACvB,IAAI,EAAE;gBACJ,IAAI,EAAE;oBACJ,QAAQ,EAAE,oBAAoB;oBAC9B,EAAE,EAAE,CAAC;iBACN;gBACD,UAAU,EAAE;oBACV,QAAQ,EAAE,oCAAoC;oBAC9C,EAAE,EAAE,CAAC;iBACN;gBACD,aAAa,EAAE;oBACb,QAAQ,EAAE,oCAAoC;oBAC9C,EAAE,EAAE,CAAC;iBACN;gBACD,UAAU,EAAE;oBACV,QAAQ,EAAE,iCAAiC;oBAC3C,EAAE,EAAE,CAAC;iBACN;aACF;SACF;KACF,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IAElB,SAAS,SAAS,CAAC,EACjB,IAAI,EAAE,EACJ,IAAI,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,GACtD,GACkC;QACnC,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,GAAG;YAC/B,UAAU;YACV,aAAa;YACb,UAAU;SACX,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,CAAA;QACxD,MAAM,OAAO,GAAG,IAAA,eAAK,EACnB,eAAe,CAAC,MAAM,CAAC,YAAY,CAAC;YAClC,GAAG;YACH,IAAA,eAAK,EAAC,IAAI,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,EACzC,qBAAqB,EACrB,IAAI,CACL;aACE,EAAE,CAAC,WAAE,CAAC;aACN,WAAW,EAAE,CAAA;QAEhB,OAAO;YACL,GAAG;YACH,IAAI,EAAE,OAAO;YACb,KAAK,EAAE;gBACL,KAAK;gBACL,QAAQ;gBACR,KAAK;aACN;SACF,CAAA;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { SeasonalSchedule } from '../types';
2
+ export declare function seasonalSchedule(from: string, to: string): Promise<SeasonalSchedule>;
3
+ //# sourceMappingURL=seasonalSchedule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seasonalSchedule.d.ts","sourceRoot":"","sources":["../../../../src/lib/sources/bcf/seasonalSchedule.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAiBhD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,6BA2ExD"}
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.seasonalSchedule = seasonalSchedule;
7
+ const scrape_it_1 = __importDefault(require("scrape-it"));
8
+ const urls_1 = require("./urls");
9
+ function seasonalSchedule(from, to) {
10
+ const url = (0, urls_1.seasonalScheduleUrl)(from, to);
11
+ return (0, scrape_it_1.default)(url, {
12
+ seasonalSchedule: {
13
+ selector: '#seasonalSchedulesForm table.table-seasonal-schedule',
14
+ eq: 0,
15
+ data: {
16
+ days: {
17
+ listItem: 'thead',
18
+ data: {
19
+ day: {
20
+ selector: 'tr',
21
+ attr: 'data-schedule-day',
22
+ },
23
+ },
24
+ },
25
+ daySchedules: {
26
+ listItem: 'tbody',
27
+ data: {
28
+ schedules: {
29
+ listItem: 'tr',
30
+ data: {
31
+ depart: {
32
+ selector: 'td > span',
33
+ eq: 0,
34
+ convert: (depart) => depart.toUpperCase(),
35
+ },
36
+ arrive: {
37
+ selector: 'td',
38
+ eq: 2,
39
+ convert: (arrive) => arrive.toUpperCase(),
40
+ },
41
+ duration: {
42
+ selector: 'td',
43
+ eq: 3,
44
+ },
45
+ messages: {
46
+ listItem: 'td:nth-child(2) > p',
47
+ convert: (message) => typeof message === 'string' ? message : '',
48
+ },
49
+ },
50
+ },
51
+ },
52
+ },
53
+ },
54
+ },
55
+ }).then(transform);
56
+ function transform({ data: { seasonalSchedule: { days, daySchedules }, }, }) {
57
+ return {
58
+ url,
59
+ days: daySchedules
60
+ .filter(({ schedules }) => schedules.length > 0 &&
61
+ schedules.some(({ depart, arrive }) => depart && arrive))
62
+ .map(({ schedules }, index) => ({
63
+ day: days[index].day,
64
+ sailings: schedules
65
+ .filter(({ depart, arrive }) => depart && arrive)
66
+ .map(({ messages, ...schedule }) => ({
67
+ ...schedule,
68
+ messages: messages
69
+ .filter(({ message }) => message?.trim())
70
+ .map(({ message }) => message.trim()),
71
+ })),
72
+ })),
73
+ };
74
+ }
75
+ }
76
+ //# sourceMappingURL=seasonalSchedule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seasonalSchedule.js","sourceRoot":"","sources":["../../../../src/lib/sources/bcf/seasonalSchedule.ts"],"names":[],"mappings":";;;;;AAkBA,4CA2EC;AA7FD,0DAAgC;AAEhC,iCAA4C;AAgB5C,SAAgB,gBAAgB,CAAC,IAAY,EAAE,EAAU;IACvD,MAAM,GAAG,GAAG,IAAA,0BAAmB,EAAC,IAAI,EAAE,EAAE,CAAC,CAAA;IACzC,OAAO,IAAA,mBAAQ,EAAuB,GAAG,EAAE;QACzC,gBAAgB,EAAE;YAChB,QAAQ,EAAE,sDAAsD;YAChE,EAAE,EAAE,CAAC;YACL,IAAI,EAAE;gBACJ,IAAI,EAAE;oBACJ,QAAQ,EAAE,OAAO;oBACjB,IAAI,EAAE;wBACJ,GAAG,EAAE;4BACH,QAAQ,EAAE,IAAI;4BACd,IAAI,EAAE,mBAAmB;yBAC1B;qBACF;iBACF;gBACD,YAAY,EAAE;oBACZ,QAAQ,EAAE,OAAO;oBACjB,IAAI,EAAE;wBACJ,SAAS,EAAE;4BACT,QAAQ,EAAE,IAAI;4BACd,IAAI,EAAE;gCACJ,MAAM,EAAE;oCACN,QAAQ,EAAE,WAAW;oCACrB,EAAE,EAAE,CAAC;oCACL,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,WAAW,EAAE;iCAC1C;gCACD,MAAM,EAAE;oCACN,QAAQ,EAAE,IAAI;oCACd,EAAE,EAAE,CAAC;oCACL,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,WAAW,EAAE;iCAC1C;gCACD,QAAQ,EAAE;oCACR,QAAQ,EAAE,IAAI;oCACd,EAAE,EAAE,CAAC;iCACN;gCACD,QAAQ,EAAE;oCACR,QAAQ,EAAE,qBAAqB;oCAC/B,OAAO,EAAE,CAAC,OAAO,EAAE,EAAE,CACnB,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;iCAC7C;6BACF;yBACF;qBACF;iBACF;aACF;SACF;KACF,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IAElB,SAAS,SAAS,CAAC,EACjB,IAAI,EAAE,EACJ,gBAAgB,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,GACzC,GAC2C;QAC5C,OAAO;YACL,GAAG;YACH,IAAI,EAAE,YAAY;iBACf,MAAM,CACL,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAChB,SAAS,CAAC,MAAM,GAAG,CAAC;gBACpB,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,IAAI,MAAM,CAAC,CAC3D;iBACA,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;gBAC9B,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG;gBACpB,QAAQ,EAAE,SAAS;qBAChB,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,IAAI,MAAM,CAAC;qBAChD,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;oBACnC,GAAG,QAAQ;oBACX,QAAQ,EAAE,QAAQ;yBACf,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC;yBACxC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;iBACxC,CAAC,CAAC;aACN,CAAC,CAAC;SACN,CAAA;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=config.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.test.d.ts","sourceRoot":"","sources":["../../../../../src/lib/sources/bcf/tests/config.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const config_1 = require("../config");
4
+ describe('BCF Config', () => {
5
+ describe('baseUrl', () => {
6
+ it('should be the correct base URL', () => {
7
+ expect(config_1.baseUrl).toBe('https://www.bcferries.com');
8
+ });
9
+ });
10
+ describe('config', () => {
11
+ it('should be the correct config', () => {
12
+ expect(config_1.config).toStrictEqual({
13
+ baseUrl: config_1.baseUrl,
14
+ tz: config_1.tz,
15
+ });
16
+ });
17
+ });
18
+ describe('tz', () => {
19
+ it('should be the correct timezone', () => {
20
+ expect(config_1.tz).toBe('America/Vancouver');
21
+ });
22
+ });
23
+ });
24
+ //# sourceMappingURL=config.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.test.js","sourceRoot":"","sources":["../../../../../src/lib/sources/bcf/tests/config.test.ts"],"names":[],"mappings":";;AAAA,sCAA+C;AAE/C,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;QACvB,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;YACxC,MAAM,CAAC,gBAAO,CAAC,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAA;QACnD,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;QACtB,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;YACtC,MAAM,CAAC,eAAM,CAAC,CAAC,aAAa,CAAC;gBAC3B,OAAO,EAAP,gBAAO;gBACP,EAAE,EAAF,WAAE;aACH,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE;QAClB,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;YACxC,MAAM,CAAC,WAAE,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAA;QACtC,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=currentConditions.live.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"currentConditions.live.test.d.ts","sourceRoot":"","sources":["../../../../../src/lib/sources/bcf/tests/currentConditions.live.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const currentConditions_1 = require("../currentConditions");
4
+ describe('Current Conditions', () => {
5
+ // this is necessary for jest to not complain about an empty test suite
6
+ it('live tests disabled by default', () => { });
7
+ it.if(process.env.LIVE_TESTS, 'LIVE test', async () => {
8
+ const result = await (0, currentConditions_1.currentConditions)('HSB', 'LNG');
9
+ expect(result).toBeDefined();
10
+ expect(result.url).toBeDefined();
11
+ expect(result.lastUpdated).toBeDefined();
12
+ expect(result.nextSailing).toBeDefined();
13
+ expect(result.nextSailing.scheduled).toBeDefined();
14
+ expect(result.nextSailing.totalSpace).toBeDefined();
15
+ expect(result.trackingMap).toBeDefined();
16
+ expect(result.departures).toBeDefined();
17
+ expect(result.departures.length).toBeGreaterThan(0);
18
+ expect(result.departures[0].departure).toBeDefined();
19
+ expect(result.departures[0].departure.scheduled).toBeDefined();
20
+ expect(result.departures[0].departure.actual).toBeDefined();
21
+ expect(result.departures[0].departure.vessel).toBeDefined();
22
+ expect(result.departures[0].departure.vessel.name).toBeDefined();
23
+ expect(result.departures[0].departure.vessel.url).toBeDefined();
24
+ }, 30_000);
25
+ });
26
+ //# sourceMappingURL=currentConditions.live.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"currentConditions.live.test.js","sourceRoot":"","sources":["../../../../../src/lib/sources/bcf/tests/currentConditions.live.test.ts"],"names":[],"mappings":";;AAAA,4DAAwD;AAExD,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,uEAAuE;IACvE,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;IAE9C,EAAE,CAAC,EAAE,CACH,OAAO,CAAC,GAAG,CAAC,UAAU,EACtB,WAAW,EACX,KAAK,IAAI,EAAE;QACT,MAAM,MAAM,GAAG,MAAM,IAAA,qCAAiB,EAAC,KAAK,EAAE,KAAK,CAAC,CAAA;QAEpD,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAA;QAC5B,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAA;QAChC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,WAAW,EAAE,CAAA;QACxC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,WAAW,EAAE,CAAA;QACxC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAA;QAClD,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,CAAA;QACnD,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,WAAW,EAAE,CAAA;QACxC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,CAAA;QACvC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAA;QAEnD,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAA;QACpD,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAA;QAC9D,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAA;QAC3D,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAA;QAC3D,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAA;QAChE,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAA;IACjE,CAAC,EACD,MAAM,CACP,CAAA;AACH,CAAC,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=currentConditions.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"currentConditions.test.d.ts","sourceRoot":"","sources":["../../../../../src/lib/sources/bcf/tests/currentConditions.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,169 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const currentConditions_1 = require("../currentConditions");
7
+ const current_conditions_json_1 = __importDefault(require("./fixtures/current-conditions.json"));
8
+ jest.mock('axios');
9
+ const axiosMock = jest.requireMock('axios').default;
10
+ describe('Current Conditions', () => {
11
+ function scrape() {
12
+ return (0, currentConditions_1.currentConditions)('HSB', 'LNG');
13
+ }
14
+ beforeEach(() => {
15
+ axiosMock.mockResolvedValue({ data: current_conditions_json_1.default });
16
+ });
17
+ it('returns the current conditions for the provided route', async () => {
18
+ const result = await scrape();
19
+ const url = 'https://www.bcferries.com/current-conditions/HSB-LNG';
20
+ expect(axiosMock).toHaveBeenCalledWith(url);
21
+ expect(result).toStrictEqual({
22
+ url,
23
+ lastUpdated: '4:34 PM',
24
+ nextSailing: {
25
+ scheduled: '4:20 PM',
26
+ totalSpace: 0.17,
27
+ },
28
+ trackingMap: 'https://ccimg.bcferries.com/cc/support/vessels/route4.jpg',
29
+ departures: [
30
+ {
31
+ departure: {
32
+ scheduled: '7:30 AM',
33
+ actual: '7:30 AM',
34
+ vessel: {
35
+ name: 'Queen of Coquitlam',
36
+ url: '/ship-info/COQ',
37
+ },
38
+ },
39
+ status: 'Arrived: 8:09 am',
40
+ },
41
+ {
42
+ departure: {
43
+ scheduled: '9:45 AM',
44
+ actual: '9:44 AM',
45
+ vessel: {
46
+ name: 'Queen of Coquitlam',
47
+ url: '/ship-info/COQ',
48
+ },
49
+ },
50
+ status: 'Arrived: 10:22 am',
51
+ },
52
+ {
53
+ departure: {
54
+ scheduled: '11:55 AM',
55
+ actual: '12:01 PM',
56
+ vessel: {
57
+ name: 'Queen of Coquitlam',
58
+ url: '/ship-info/COQ',
59
+ },
60
+ },
61
+ status: 'Arrived: 12:39 pm',
62
+ },
63
+ {
64
+ departure: {
65
+ scheduled: '2:10 PM',
66
+ actual: '2:23 PM',
67
+ vessel: {
68
+ name: 'Queen of Coquitlam',
69
+ url: '/ship-info/COQ',
70
+ },
71
+ },
72
+ status: 'Arrived: 3:01 pm We are loading and unloading multiple ships',
73
+ },
74
+ {
75
+ departure: {
76
+ scheduled: '4:20 PM',
77
+ actual: '',
78
+ vessel: {
79
+ name: 'Queen of Coquitlam',
80
+ url: '/ship-info/COQ',
81
+ },
82
+ },
83
+ status: 'Estimated vehicle space available 17% Details We are loading and unloading multiple ships',
84
+ },
85
+ {
86
+ departure: {
87
+ scheduled: '5:30 PM',
88
+ actual: '',
89
+ vessel: {
90
+ name: 'Queen of Cowichan',
91
+ url: '/ship-info/COW',
92
+ },
93
+ },
94
+ status: 'Estimated vehicle space available 92% Details',
95
+ },
96
+ {
97
+ departure: {
98
+ scheduled: '7:50 PM',
99
+ actual: '',
100
+ vessel: {
101
+ name: 'Queen of Cowichan',
102
+ url: '/ship-info/COW',
103
+ },
104
+ },
105
+ status: 'Estimated vehicle space available 88% Details',
106
+ },
107
+ {
108
+ departure: {
109
+ scheduled: '10:55 PM',
110
+ actual: '',
111
+ vessel: {
112
+ name: 'Queen of Coquitlam',
113
+ url: '/ship-info/COQ',
114
+ },
115
+ },
116
+ status: 'Estimated vehicle space available 93% Details',
117
+ },
118
+ {
119
+ departure: {
120
+ scheduled: '7:30 AM',
121
+ actual: '',
122
+ vessel: {
123
+ name: 'Queen of Coquitlam',
124
+ url: '/ship-info/COQ',
125
+ },
126
+ },
127
+ status: 'Estimated vehicle space available 63% Details',
128
+ },
129
+ {
130
+ departure: {
131
+ scheduled: '9:45 AM',
132
+ actual: '',
133
+ vessel: {
134
+ name: 'Queen of Coquitlam',
135
+ url: '/ship-info/COQ',
136
+ },
137
+ },
138
+ status: 'Estimated vehicle space available 77% Details',
139
+ },
140
+ {
141
+ departure: {
142
+ scheduled: '11:55 AM',
143
+ actual: '',
144
+ vessel: {
145
+ name: 'Queen of Coquitlam',
146
+ url: '/ship-info/COQ',
147
+ },
148
+ },
149
+ status: 'Estimated vehicle space available 75% Details',
150
+ },
151
+ ],
152
+ terminal: {
153
+ name: 'Vancouver (Horseshoe Bay)',
154
+ address: '# 6750 Keith Rd , West Vancouver, V7W 2V1',
155
+ },
156
+ webcams: [
157
+ {
158
+ label: 'Traffic at the terminal',
159
+ url: 'https://ccimg.bcferries.com/cc/support/terminals/cam1_HSB.jpg',
160
+ },
161
+ {
162
+ label: 'Traffic to Sunshine Coast (Langdale)',
163
+ url: 'https://ccimg.bcferries.com/cc/support/terminals/cam3_HSB.jpg',
164
+ },
165
+ ],
166
+ });
167
+ });
168
+ });
169
+ //# sourceMappingURL=currentConditions.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"currentConditions.test.js","sourceRoot":"","sources":["../../../../../src/lib/sources/bcf/tests/currentConditions.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=dailySchedule.live.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dailySchedule.live.test.d.ts","sourceRoot":"","sources":["../../../../../src/lib/sources/bcf/tests/dailySchedule.live.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const dailySchedule_1 = require("../dailySchedule");
4
+ describe('Daily Schedule', () => {
5
+ // this is necessary for jest to not complain about an empty test suite
6
+ it('live tests disabled by default', () => { });
7
+ it.if(process.env.LIVE_TESTS, 'LIVE test', async () => {
8
+ const result = await (0, dailySchedule_1.dailySchedule)('HSB', 'LNG');
9
+ expect(result).toBeDefined();
10
+ expect(result.url).toBeDefined();
11
+ expect(result.sailings).toBeDefined();
12
+ expect(result.sailings.length).toBeGreaterThan(0);
13
+ expect(result.sailings[0].depart).toBeDefined();
14
+ expect(result.sailings[0].arrive).toBeDefined();
15
+ expect(result.sailings[0].duration).toBeDefined();
16
+ expect(result.sailings[0].type).toBeDefined();
17
+ }, 30_000);
18
+ });
19
+ //# sourceMappingURL=dailySchedule.live.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dailySchedule.live.test.js","sourceRoot":"","sources":["../../../../../src/lib/sources/bcf/tests/dailySchedule.live.test.ts"],"names":[],"mappings":";;AAAA,oDAAgD;AAEhD,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,uEAAuE;IACvE,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;IAE9C,EAAE,CAAC,EAAE,CACH,OAAO,CAAC,GAAG,CAAC,UAAU,EACtB,WAAW,EACX,KAAK,IAAI,EAAE;QACT,MAAM,MAAM,GAAG,MAAM,IAAA,6BAAa,EAAC,KAAK,EAAE,KAAK,CAAC,CAAA;QAEhD,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAA;QAC5B,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAA;QAChC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAA;QACrC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAA;QAEjD,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAA;QAC/C,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAA;QAC/C,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAA;QACjD,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAA;IAC/C,CAAC,EACD,MAAM,CACP,CAAA;AACH,CAAC,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=dailySchedule.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dailySchedule.test.d.ts","sourceRoot":"","sources":["../../../../../src/lib/sources/bcf/tests/dailySchedule.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const dailySchedule_1 = require("../dailySchedule");
7
+ const daily_json_1 = __importDefault(require("./fixtures/routes-fares/schedules/daily.json"));
8
+ jest.mock('axios');
9
+ const axiosMock = jest.requireMock('axios').default;
10
+ describe('Daily Schedule', () => {
11
+ function scrape() {
12
+ return (0, dailySchedule_1.dailySchedule)('HSB', 'LNG', '2025-01-01');
13
+ }
14
+ beforeEach(() => {
15
+ axiosMock.mockResolvedValue({ data: daily_json_1.default });
16
+ });
17
+ it('returns the daily schedule for the provided route and date', async () => {
18
+ const result = await scrape();
19
+ const url = 'https://www.bcferries.com/routes-fares/schedules/daily/HSB-LNG?scheduleDate=01/01/2025';
20
+ expect(axiosMock).toHaveBeenCalledWith(url);
21
+ expect(result).toStrictEqual({
22
+ url,
23
+ sailings: [
24
+ {
25
+ depart: '7:30 AM',
26
+ arrive: '8:10 AM',
27
+ duration: '00:40',
28
+ type: 'Non-stop',
29
+ },
30
+ {
31
+ depart: '9:45 AM',
32
+ arrive: '10:25 AM',
33
+ duration: '00:40',
34
+ type: 'Non-stop',
35
+ },
36
+ {
37
+ depart: '11:55 AM',
38
+ arrive: '12:35 PM',
39
+ duration: '00:40',
40
+ type: 'Non-stop',
41
+ },
42
+ {
43
+ depart: '2:10 PM',
44
+ arrive: '2:50 PM',
45
+ duration: '00:40',
46
+ type: 'Non-stop',
47
+ },
48
+ {
49
+ depart: '4:20 PM',
50
+ arrive: '5:00 PM',
51
+ duration: '00:40',
52
+ type: 'Non-stop',
53
+ },
54
+ {
55
+ depart: '5:30 PM',
56
+ arrive: '6:10 PM',
57
+ duration: '00:40',
58
+ type: 'Non-stop',
59
+ },
60
+ {
61
+ depart: '7:50 PM',
62
+ arrive: '8:30 PM',
63
+ duration: '00:40',
64
+ type: 'Non-stop',
65
+ },
66
+ {
67
+ depart: '10:55 PM',
68
+ arrive: '11:35 PM',
69
+ duration: '00:40',
70
+ type: 'Non-stop',
71
+ },
72
+ ],
73
+ });
74
+ });
75
+ });
76
+ //# sourceMappingURL=dailySchedule.test.js.map