liftie 3.56.5 → 4.0.0

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 (311) hide show
  1. package/Makefile +2 -2
  2. package/app.js +33 -25
  3. package/lib/checker.js +1 -1
  4. package/lib/cli/curl.js +8 -8
  5. package/lib/cli/dirs.js +8 -6
  6. package/lib/cli/fetch.js +9 -9
  7. package/lib/cli/for-each-resort.js +3 -4
  8. package/lib/cli/generate.js +10 -10
  9. package/lib/cli/noaa.js +7 -12
  10. package/lib/client/about/index.js +2 -6
  11. package/lib/client/boot/height.js +2 -6
  12. package/lib/client/boot/index.js +8 -11
  13. package/lib/client/boot/service-worker.js +1 -5
  14. package/lib/client/minimax/index.js +1 -3
  15. package/lib/client/resort/dom.js +2 -7
  16. package/lib/client/resort/index.js +7 -10
  17. package/lib/client/resort/lifts.js +4 -5
  18. package/lib/client/resort/snow.js +3 -4
  19. package/lib/client/resort/weather.js +3 -4
  20. package/lib/client/resort/webcams.js +5 -8
  21. package/lib/client/state/index.js +4 -7
  22. package/lib/client/stats/index.js +1 -5
  23. package/lib/client/tag/index.js +1 -3
  24. package/lib/embed/index.js +0 -2
  25. package/lib/lifts/index.js +12 -12
  26. package/lib/lifts/parse.js +5 -5
  27. package/lib/lifts/parser.js +6 -10
  28. package/lib/lifts/pipe.js +3 -3
  29. package/lib/lifts/request.js +1 -3
  30. package/lib/lifts/rest.js +2 -4
  31. package/lib/lifts/stats.js +2 -5
  32. package/lib/loader.js +9 -12
  33. package/lib/loaders.js +7 -8
  34. package/lib/opening.js +6 -5
  35. package/lib/plugins.js +3 -8
  36. package/lib/resorts/3cime/index.js +1 -1
  37. package/lib/resorts/3cime/resort.json +1 -1
  38. package/lib/resorts/49-degrees-north/index.js +1 -1
  39. package/lib/resorts/abasin/index.js +2 -2
  40. package/lib/resorts/alpe-lusia-san-pellegrino/index.js +1 -1
  41. package/lib/resorts/alpe-lusia-san-pellegrino/resort.json +1 -1
  42. package/lib/resorts/alpine/index.js +1 -1
  43. package/lib/resorts/alta/index.js +6 -7
  44. package/lib/resorts/alta-badia/index.js +1 -1
  45. package/lib/resorts/alta-badia/resort.json +1 -1
  46. package/lib/resorts/alyeska/index.js +1 -1
  47. package/lib/resorts/angel-fire/index.js +1 -1
  48. package/lib/resorts/arabba/index.js +1 -1
  49. package/lib/resorts/arabba/resort.json +1 -1
  50. package/lib/resorts/aspen-highlands/index.js +1 -1
  51. package/lib/resorts/aspen-mountain/index.js +1 -1
  52. package/lib/resorts/attitash/index.js +1 -1
  53. package/lib/resorts/beavercreek/index.js +1 -1
  54. package/lib/resorts/berkshire-east/index.js +1 -1
  55. package/lib/resorts/big-sky/index.js +1 -1
  56. package/lib/resorts/big-white/index.js +1 -1
  57. package/lib/resorts/big-white/resort.json +1 -1
  58. package/lib/resorts/blue-mountain-pa/index.js +1 -1
  59. package/lib/resorts/bluemountain/index.js +1 -1
  60. package/lib/resorts/bogusbasin/index.js +5 -4
  61. package/lib/resorts/bolton-valley/index.js +2 -3
  62. package/lib/resorts/boreal/index.js +1 -1
  63. package/lib/resorts/breck/index.js +1 -1
  64. package/lib/resorts/brettonwoods/index.js +7 -5
  65. package/lib/resorts/brianhead/index.js +1 -1
  66. package/lib/resorts/bridger-bowl/index.js +4 -3
  67. package/lib/resorts/brighton/index.js +1 -1
  68. package/lib/resorts/bromley-mountain/index.js +1 -1
  69. package/lib/resorts/burke-mountain/index.js +1 -1
  70. package/lib/resorts/buttermilk/index.js +1 -1
  71. package/lib/resorts/caberfae-peaks/index.js +1 -1
  72. package/lib/resorts/camelback/index.js +1 -1
  73. package/lib/resorts/campo-felice/index.js +1 -1
  74. package/lib/resorts/campo-felice/resort.json +1 -1
  75. package/lib/resorts/canada-olympic-park/index.js +1 -1
  76. package/lib/resorts/cannon/index.js +1 -1
  77. package/lib/resorts/cataloochee/index.js +1 -1
  78. package/lib/resorts/catedral/index.js +1 -1
  79. package/lib/resorts/cervino/index.js +2 -2
  80. package/lib/resorts/chamonix/index.js +2 -2
  81. package/lib/resorts/chamonix/resort.json +1 -1
  82. package/lib/resorts/chinapeak/index.js +1 -1
  83. package/lib/resorts/civetta/index.js +1 -1
  84. package/lib/resorts/civetta/resort.json +1 -1
  85. package/lib/resorts/claviere/index.js +1 -1
  86. package/lib/resorts/copper/index.js +1 -1
  87. package/lib/resorts/coronetpeak/index.js +1 -1
  88. package/lib/resorts/coronetpeak/resort.json +1 -1
  89. package/lib/resorts/cortina-d-ampezzo/index.js +1 -1
  90. package/lib/resorts/cortina-d-ampezzo/resort.json +1 -1
  91. package/lib/resorts/courchevel/index.js +1 -1
  92. package/lib/resorts/courchevel/resort.json +2 -1
  93. package/lib/resorts/cranmore-mountain/index.js +1 -1
  94. package/lib/resorts/cransmontana/index.js +2 -2
  95. package/lib/resorts/crested-butte/index.js +1 -1
  96. package/lib/resorts/crystal-mountain/index.js +1 -1
  97. package/lib/resorts/cypress-mountain/index.js +1 -1
  98. package/lib/resorts/deer-valley/index.js +1 -1
  99. package/lib/resorts/devils-head/index.js +1 -1
  100. package/lib/resorts/diamondpeak/index.js +1 -1
  101. package/lib/resorts/falls-creek/index.js +5 -3
  102. package/lib/resorts/falls-creek/resort.json +1 -1
  103. package/lib/resorts/flims-laax-falera/index.js +1 -1
  104. package/lib/resorts/flims-laax-falera/resort.json +1 -1
  105. package/lib/resorts/folgaria/index.js +1 -1
  106. package/lib/resorts/folgaria/resort.json +1 -1
  107. package/lib/resorts/folgarida-marilleva/index.js +2 -1
  108. package/lib/resorts/forni/index.js +1 -1
  109. package/lib/resorts/forni/resort.json +1 -1
  110. package/lib/resorts/gore-mountain/index.js +1 -1
  111. package/lib/resorts/grand-targhee/index.js +1 -1
  112. package/lib/resorts/grouse/index.js +1 -1
  113. package/lib/resorts/gunstock/index.js +1 -1
  114. package/lib/resorts/heavenly/index.js +1 -1
  115. package/lib/resorts/hochfuegen/index.js +2 -2
  116. package/lib/resorts/homewood/index.js +1 -1
  117. package/lib/resorts/hoodoo/index.js +1 -1
  118. package/lib/resorts/hunter/index.js +1 -1
  119. package/lib/resorts/ischgl-silvretta-arena/index.js +1 -1
  120. package/lib/resorts/jackson-hole/index.js +5 -3
  121. package/lib/resorts/jay-peak/index.js +1 -1
  122. package/lib/resorts/jiminypeak/index.js +1 -1
  123. package/lib/resorts/june-mountain/index.js +1 -1
  124. package/lib/resorts/keystone/index.js +1 -1
  125. package/lib/resorts/killington/index.js +1 -1
  126. package/lib/resorts/king-pine/index.js +5 -3
  127. package/lib/resorts/kirkwood/index.js +1 -1
  128. package/lib/resorts/kitzbuehel/index.js +1 -1
  129. package/lib/resorts/lamolina/index.js +1 -1
  130. package/lib/resorts/lamolina/resort.json +1 -1
  131. package/lib/resorts/laplagne/index.js +1 -1
  132. package/lib/resorts/laplagne/resort.json +2 -1
  133. package/lib/resorts/larosiere/index.js +1 -1
  134. package/lib/resorts/lavarone/index.js +1 -1
  135. package/lib/resorts/lavarone/resort.json +1 -1
  136. package/lib/resorts/lesarcs/index.js +1 -1
  137. package/lib/resorts/lesmenuires/index.js +1 -1
  138. package/lib/resorts/lesmenuires/resort.json +2 -1
  139. package/lib/resorts/loon/index.js +1 -1
  140. package/lib/resorts/loveland/index.js +2 -2
  141. package/lib/resorts/mad-river-glen/index.js +2 -2
  142. package/lib/resorts/madonna-di-campiglio/index.js +2 -1
  143. package/lib/resorts/mammoth-lakes/index.js +1 -1
  144. package/lib/resorts/manning-park/index.js +1 -1
  145. package/lib/resorts/manning-park/resort.json +1 -1
  146. package/lib/resorts/megeve/index.js +1 -1
  147. package/lib/resorts/megeve/resort.json +2 -1
  148. package/lib/resorts/meribel/index.js +1 -1
  149. package/lib/resorts/meribel/resort.json +2 -1
  150. package/lib/resorts/monarch/index.js +2 -2
  151. package/lib/resorts/monte-amiata/index.js +1 -1
  152. package/lib/resorts/monte-amiata/resort.json +1 -1
  153. package/lib/resorts/monte-bondone/index.js +1 -1
  154. package/lib/resorts/montegenevre/index.js +1 -1
  155. package/lib/resorts/monterosa/index.js +1 -1
  156. package/lib/resorts/morzine/index.js +1 -1
  157. package/lib/resorts/morzine/resort.json +6 -2
  158. package/lib/resorts/mount-sunapee/index.js +1 -1
  159. package/lib/resorts/mountsnow/index.js +1 -1
  160. package/lib/resorts/mt-buller/index.js +1 -1
  161. package/lib/resorts/mt-hotham/index.js +5 -3
  162. package/lib/resorts/mt-seymour/index.js +1 -1
  163. package/lib/resorts/mt-spokane/index.js +1 -1
  164. package/lib/resorts/mtbachelor/index.js +1 -1
  165. package/lib/resorts/mtbrighton/index.js +1 -1
  166. package/lib/resorts/mthigh/index.js +1 -1
  167. package/lib/resorts/mthood/index.js +1 -1
  168. package/lib/resorts/mtpeter/index.js +1 -1
  169. package/lib/resorts/mtpeter/resort.json +1 -1
  170. package/lib/resorts/mtrose/index.js +1 -1
  171. package/lib/resorts/niseko/index.js +1 -1
  172. package/lib/resorts/niseko/resort.json +1 -1
  173. package/lib/resorts/northstar/index.js +1 -1
  174. package/lib/resorts/okemo/index.js +1 -1
  175. package/lib/resorts/ovindoli/index.js +1 -1
  176. package/lib/resorts/ovindoli/resort.json +1 -1
  177. package/lib/resorts/owlshead/index.js +1 -1
  178. package/lib/resorts/paganella/index.js +1 -1
  179. package/lib/resorts/paganella/resort.json +1 -1
  180. package/lib/resorts/palisades/index.js +1 -1
  181. package/lib/resorts/parkcity/index.js +1 -1
  182. package/lib/resorts/pats-peak/index.js +4 -2
  183. package/lib/resorts/peio/index.js +2 -2
  184. package/lib/resorts/perisher/index.js +1 -1
  185. package/lib/resorts/perisher/resort.json +1 -1
  186. package/lib/resorts/piancavallo/index.js +1 -1
  187. package/lib/resorts/piancavallo/resort.json +1 -1
  188. package/lib/resorts/pico/index.js +1 -1
  189. package/lib/resorts/pinzolo/index.js +2 -1
  190. package/lib/resorts/plan-de-corones/index.js +1 -1
  191. package/lib/resorts/plan-de-corones/resort.json +1 -1
  192. package/lib/resorts/pleasant-mountain/index.js +1 -1
  193. package/lib/resorts/pontedilegno-tonale/index.js +1 -1
  194. package/lib/resorts/ragged-mountain/index.js +1 -1
  195. package/lib/resorts/ravascletto-zoncolan/index.js +1 -1
  196. package/lib/resorts/ravascletto-zoncolan/resort.json +1 -1
  197. package/lib/resorts/red-lodge-mountain/index.js +1 -1
  198. package/lib/resorts/red-mountain/index.js +2 -3
  199. package/lib/resorts/rio-pusteria-bressanone/index.js +1 -1
  200. package/lib/resorts/rio-pusteria-bressanone/resort.json +1 -1
  201. package/lib/resorts/roccaraso/index.js +1 -1
  202. package/lib/resorts/roccaraso/resort.json +1 -1
  203. package/lib/resorts/saddleback/index.js +1 -1
  204. package/lib/resorts/san-martino-di-castrozza-passo-rolle/index.js +1 -1
  205. package/lib/resorts/san-martino-di-castrozza-passo-rolle/resort.json +1 -1
  206. package/lib/resorts/sansicario/index.js +1 -1
  207. package/lib/resorts/sappada/index.js +1 -1
  208. package/lib/resorts/sappada/resort.json +1 -1
  209. package/lib/resorts/sasquatch-mountain/index.js +1 -1
  210. package/lib/resorts/sauris/index.js +1 -1
  211. package/lib/resorts/sauris/resort.json +1 -1
  212. package/lib/resorts/sauze/index.js +1 -1
  213. package/lib/resorts/schweitzer/index.js +1 -1
  214. package/lib/resorts/sella/index.js +1 -1
  215. package/lib/resorts/sella/resort.json +1 -1
  216. package/lib/resorts/serfaus-fiss-ladis/index.js +1 -1
  217. package/lib/resorts/sestriere/index.js +1 -1
  218. package/lib/resorts/sestriere/resort.json +1 -1
  219. package/lib/resorts/shawnee-mountain/index.js +4 -2
  220. package/lib/resorts/sierra/index.js +1 -1
  221. package/lib/resorts/silver-star/index.js +2 -2
  222. package/lib/resorts/skiwelt/index.js +1 -1
  223. package/lib/resorts/smuggs/index.js +1 -1
  224. package/lib/resorts/snow-valley/index.js +2 -2
  225. package/lib/resorts/snowbasin/index.js +1 -1
  226. package/lib/resorts/snowbird/index.js +2 -3
  227. package/lib/resorts/snowmass/index.js +1 -1
  228. package/lib/resorts/snowshoe/index.js +1 -1
  229. package/lib/resorts/soelden/index.js +1 -1
  230. package/lib/resorts/solitude/index.js +1 -1
  231. package/lib/resorts/st-anton-am-arlberg/index.js +1 -1
  232. package/lib/resorts/steamboat/index.js +1 -1
  233. package/lib/resorts/stevens/index.js +1 -1
  234. package/lib/resorts/stowe/index.js +1 -1
  235. package/lib/resorts/stratton/index.js +1 -1
  236. package/lib/resorts/sugarbowl/index.js +1 -1
  237. package/lib/resorts/sugarbush/index.js +1 -1
  238. package/lib/resorts/sugarloaf/index.js +1 -1
  239. package/lib/resorts/sun-peaks/index.js +1 -1
  240. package/lib/resorts/sun-peaks/resort.json +1 -1
  241. package/lib/resorts/sunday-river/index.js +1 -1
  242. package/lib/resorts/sunshine-village/index.js +6 -3
  243. package/lib/resorts/sunvalley/index.js +1 -1
  244. package/lib/resorts/tahoe-donner/index.js +1 -1
  245. package/lib/resorts/taos/index.js +1 -1
  246. package/lib/resorts/tarvisio/index.js +1 -1
  247. package/lib/resorts/tarvisio/resort.json +1 -1
  248. package/lib/resorts/telluride/index.js +1 -1
  249. package/lib/resorts/thredbo/index.js +1 -1
  250. package/lib/resorts/tignes/index.js +1 -1
  251. package/lib/resorts/tignes/resort.json +1 -1
  252. package/lib/resorts/timberline-lodge/index.js +1 -1
  253. package/lib/resorts/tremblant/index.js +1 -1
  254. package/lib/resorts/vail/index.js +1 -1
  255. package/lib/resorts/val-di-fassa/index.js +1 -1
  256. package/lib/resorts/val-di-fassa/resort.json +1 -1
  257. package/lib/resorts/val-di-fiemme/index.js +1 -1
  258. package/lib/resorts/val-di-fiemme/resort.json +1 -1
  259. package/lib/resorts/val-gardena/index.js +1 -1
  260. package/lib/resorts/val-gardena/resort.json +1 -1
  261. package/lib/resorts/valdisere/index.js +1 -1
  262. package/lib/resorts/valdisere/resort.json +1 -1
  263. package/lib/resorts/verbier/index.js +1 -1
  264. package/lib/resorts/waterville/index.js +1 -1
  265. package/lib/resorts/whistler-blackcomb/index.js +2 -2
  266. package/lib/resorts/whistler-blackcomb/resort.json +1 -1
  267. package/lib/resorts/whiteface/index.js +1 -1
  268. package/lib/resorts/whitefish/index.js +1 -1
  269. package/lib/resorts/wildcat/index.js +1 -1
  270. package/lib/resorts/windham/index.js +1 -1
  271. package/lib/resorts/winter-park/index.js +1 -1
  272. package/lib/resorts/winterplace/index.js +1 -1
  273. package/lib/routes/cache.js +4 -4
  274. package/lib/routes/canonical.js +1 -3
  275. package/lib/routes/data.js +10 -12
  276. package/lib/routes/database.js +6 -7
  277. package/lib/routes/headers.js +2 -2
  278. package/lib/routes/index.js +9 -11
  279. package/lib/routes/plan.js +2 -4
  280. package/lib/routes/service-worker.js +6 -7
  281. package/lib/routes/sorter.js +2 -4
  282. package/lib/routes/tags.js +2 -4
  283. package/lib/select.js +3 -5
  284. package/lib/tools/aspen.js +4 -4
  285. package/lib/tools/boyne.js +4 -4
  286. package/lib/tools/campiglio-dolomiti.js +1 -1
  287. package/lib/tools/coerce.js +4 -4
  288. package/lib/tools/dolomitisuperski.js +1 -1
  289. package/lib/tools/domutil.js +11 -18
  290. package/lib/tools/infosnow.js +6 -6
  291. package/lib/tools/intrawest.js +3 -3
  292. package/lib/tools/limiter.js +2 -4
  293. package/lib/tools/lumiplan.js +2 -2
  294. package/lib/tools/millis.js +4 -11
  295. package/lib/tools/powdr.js +4 -4
  296. package/lib/tools/prism.js +5 -5
  297. package/lib/tools/skiplan.js +1 -1
  298. package/lib/tools/turismofvg.js +2 -2
  299. package/lib/tools/vail.js +8 -10
  300. package/lib/tools/vialattea.js +1 -1
  301. package/lib/weather/icons.js +3 -8
  302. package/lib/weather/index.js +5 -6
  303. package/lib/weather/noaa.js +5 -3
  304. package/lib/weather/openweather.js +6 -7
  305. package/lib/webcams.js +6 -6
  306. package/package.json +3 -2
  307. package/public/scripts/liftie-embed.js +41 -0
  308. package/public/scripts/liftie-embed.js.map +7 -0
  309. package/public/scripts/liftie.js +1561 -0
  310. package/public/scripts/liftie.js.map +7 -0
  311. package/public/stylesheets/style.css +864 -0
@@ -1,17 +1,15 @@
1
- const debug = require('debug')('liftie:data');
2
- const checkNames = require('../checker');
3
- const database = require('./database');
4
- const plugins = require('../plugins');
5
- const loaders = require('../loaders');
6
- const tags = require('./tags');
7
- const stats = require('../lifts/stats');
1
+ import Debug from 'debug';
2
+ import checkNames from '../checker.js';
3
+ import { summary } from '../lifts/stats.js';
4
+ import * as loaders from '../loaders.js';
5
+ import * as plugins from '../plugins.js';
6
+ import database from './database.js';
7
+ import tags from './tags.js';
8
8
 
9
- module.exports = data;
10
-
11
- /*global setInterval */
9
+ const debug = Debug('liftie:data');
12
10
 
13
11
  // data structure
14
- function data() {
12
+ export default function data() {
15
13
  const // meta and data for each resort
16
14
  cache = {};
17
15
 
@@ -146,7 +144,7 @@ function data() {
146
144
 
147
145
  function getStats(requestedNames) {
148
146
  const names = checkNames(requestedNames, cache, my.names);
149
- return stats.summary(
147
+ return summary(
150
148
  names.map(id => {
151
149
  const lifts = cache[id].data.lifts;
152
150
  return lifts?.stats;
@@ -1,13 +1,12 @@
1
- const path = require('node:path');
2
- const plugins = require('../plugins');
3
- const dbCache = require('./cache');
1
+ import { tmpdir } from 'node:os';
2
+ import path from 'node:path';
3
+ import * as plugins from '../plugins.js';
4
+ import dbCache from './cache.js';
4
5
 
5
- module.exports = database;
6
-
7
- const dbFileName = path.resolve(process.env.LOG_DIR || require('node:os').tmpdir(), 'liftie.db.json');
6
+ const dbFileName = path.resolve(process.env.LOG_DIR || tmpdir(), 'liftie.db.json');
8
7
 
9
8
  // persistent storage status for each resort
10
- function database(cache) {
9
+ export default function database(cache) {
11
10
  const db = dbCache(dbFileName);
12
11
  let loaded;
13
12
 
@@ -1,6 +1,6 @@
1
- const crypto = require('node:crypto');
1
+ import crypto from 'node:crypto';
2
2
 
3
- module.exports = [csp, referrer, feature, link];
3
+ export default [csp, referrer, feature, link];
4
4
 
5
5
  const { LIFTIE_STATIC_HOST: staticHost = '', LIFTIE_CSP_ENFORCE, CSP_REPORT_URI } = process.env;
6
6
 
@@ -1,13 +1,11 @@
1
- const sorter = require('./sorter');
2
- const canonical = require('./canonical');
3
- const plan = require('./plan');
4
- const serviceWorker = require('./service-worker');
5
- const headers = require('./headers');
6
- const Router = require('@pirxpilot/router');
7
- const parseurl = require('parseurl');
8
- const qs = require('qs');
9
-
10
- module.exports = routes;
1
+ import Router from '@pirxpilot/router';
2
+ import parseurl from 'parseurl';
3
+ import qs from 'qs';
4
+ import canonical from './canonical.js';
5
+ import headers from './headers.js';
6
+ import plan from './plan.js';
7
+ import serviceWorker from './service-worker.js';
8
+ import sorter from './sorter.js';
11
9
 
12
10
  function title(suffix) {
13
11
  let t = 'Liftie';
@@ -164,7 +162,7 @@ function meta(req, res, next) {
164
162
  });
165
163
  }
166
164
 
167
- function routes(app) {
165
+ export default function routes(app) {
168
166
  const router = new Router();
169
167
 
170
168
  function reqData(req, _res, next) {
@@ -1,8 +1,6 @@
1
- const qs = require('qs');
1
+ import qs from 'qs';
2
2
 
3
- module.exports = addToTrip;
4
-
5
- function addToTrip(resort) {
3
+ export default function addToTrip(resort) {
6
4
  return qs.stringify({
7
5
  stop: {
8
6
  name: resort.name,
@@ -1,13 +1,12 @@
1
- const esbuild = require('esbuild');
2
- const fs = require('node:fs');
3
-
4
- module.exports = renderServiceWorker;
1
+ import fs from 'node:fs';
2
+ import esbuild from 'esbuild';
3
+ import packageJSON from '../../package.json' with { type: 'json' };
5
4
 
6
5
  const { NODE_ENV, SITE_URL: siteUrl, LIFTIE_STATIC_HOST: staticHost = '' } = process.env;
7
6
 
8
7
  const DEBUG = NODE_ENV !== 'production';
9
8
 
10
- function renderServiceWorker(_req, res) {
9
+ export default function renderServiceWorker(_req, res) {
11
10
  createServiceWorkerScript(res.locals).then(serviceWorkerScript => {
12
11
  // do not cache service worker
13
12
  res.setHeader('Cache-Control', 'no-cache, max-age=0, must-revalidate');
@@ -47,7 +46,7 @@ let serviceWorkerScriptPromise;
47
46
  function createServiceWorkerScript({ cachify }) {
48
47
  if (!serviceWorkerScriptPromise) {
49
48
  const serviceWorkerOptions = {
50
- version: require('../../package.json').version,
49
+ version: packageJSON.version,
51
50
  prefetch: [
52
51
  '/img/noaa-logo.svg',
53
52
  '/scripts/liftie.js',
@@ -63,7 +62,7 @@ function createServiceWorkerScript({ cachify }) {
63
62
  serviceWorkerScriptPromise = minify({
64
63
  debug: DEBUG,
65
64
  vars: `var options = ${JSON.stringify(serviceWorkerOptions)};`,
66
- script: fs.readFileSync(`${__dirname}/sw.template.js`, 'utf-8')
65
+ script: fs.readFileSync(`${import.meta.dirname}/sw.template.js`, 'utf-8')
67
66
  });
68
67
  }
69
68
  return serviceWorkerScriptPromise;
@@ -1,6 +1,4 @@
1
- const _ = require('lodash');
2
-
3
- module.exports = markOpen;
1
+ import _ from 'lodash';
4
2
 
5
3
  function getOpenResorts(cookie) {
6
4
  const open = cookie['resorts-open'];
@@ -20,7 +18,7 @@ function sortByOpen(resorts) {
20
18
  return open.concat(closed);
21
19
  }
22
20
 
23
- function markOpen(resorts, cookie) {
21
+ export default function markOpen(resorts, cookie) {
24
22
  let openList = getOpenResorts(cookie);
25
23
  if (!openList && resorts.length > 5) {
26
24
  // no cookie and a lot of resorts - display everything as closed
@@ -1,6 +1,4 @@
1
- const canonical = require('./canonical');
2
-
3
- module.exports = tags;
1
+ import canonical from './canonical.js';
4
2
 
5
3
  /**
6
4
  * Converts an array of objects into tags structure.
@@ -10,7 +8,7 @@ module.exports = tags;
10
8
  *
11
9
  * @param {Object} objects to be converted
12
10
  */
13
- function tags(objects) {
11
+ export default function tags(objects) {
14
12
  const result = Object.create(null);
15
13
 
16
14
  Object.keys(objects).forEach(n => {
package/lib/select.js CHANGED
@@ -1,8 +1,6 @@
1
- const cssSelect = require('css-select');
1
+ import { selectAll } from 'css-select';
2
2
 
3
3
  // select we were using before had reverse order of the parameters
4
- function select(dom, selector) {
5
- return cssSelect.selectAll(selector, dom);
4
+ export default function select(dom, selector) {
5
+ return selectAll(selector, dom);
6
6
  }
7
-
8
- module.exports = select;
@@ -1,9 +1,9 @@
1
- const debug = require('debug')('liftie:resort:aspen');
2
- const coerce = require('./coerce');
1
+ import Debug from 'debug';
2
+ import coerce from './coerce.js';
3
3
 
4
- module.exports = parse;
4
+ const debug = Debug('liftie:resort:aspen');
5
5
 
6
- function parse(data) {
6
+ export default function parse(data) {
7
7
  const liftStatus = {};
8
8
 
9
9
  data.liftStatuses.forEach(lift => {
@@ -1,9 +1,9 @@
1
- const coerce = require('./coerce');
2
- const debug = require('debug')('liftie:resort:boyne');
1
+ import Debug from 'debug';
2
+ import coerce from './coerce.js';
3
3
 
4
- module.exports = parse;
4
+ const debug = Debug('liftie:resort:boyne');
5
5
 
6
- function parse(data) {
6
+ export default function parse(data) {
7
7
  const liftStatus = {};
8
8
 
9
9
  data.forEach(({ name, status }) => {
@@ -1,4 +1,4 @@
1
- module.exports = index => ({
1
+ export default index => ({
2
2
  selector: `.piste-overview:nth-of-type(${index}) .col-6:first-child dt`,
3
3
  parse: {
4
4
  name: 2,
@@ -1,6 +1,6 @@
1
- const debug = require('debug')('liftie:coerce');
1
+ import Debug from 'debug';
2
2
 
3
- module.exports = coerceStatus;
3
+ const debug = Debug('liftie:coerce');
4
4
 
5
5
  const map = {
6
6
  o: 'open',
@@ -90,12 +90,12 @@ function slice(str, [from, to]) {
90
90
  * slice, trim, lowercase and coerce to standard liftie statuses
91
91
  * If no usable status is found, return 'scheduled'
92
92
  */
93
- function coerceStatus(status, ...dels) {
93
+ export default function coerceStatus(status, ...dels) {
94
94
  if (status) {
95
95
  if (dels.length > 0) {
96
96
  status = slice(status, dels);
97
97
  }
98
- status = status.replace(/[\s_\-]+/g, '').toLowerCase();
98
+ status = status.replace(/[\s_-]+/g, '').toLowerCase();
99
99
  }
100
100
  let s = map[status];
101
101
  if (!s) {
@@ -1,4 +1,4 @@
1
- module.exports = {
1
+ export default {
2
2
  selector: '.table tbody tr',
3
3
  parse: {
4
4
  name: '1',
@@ -1,9 +1,11 @@
1
- const debug = require('debug')('liftie:domutil');
1
+ import Debug from 'debug';
2
2
 
3
- const select = require('../select');
4
- const coerce = require('./coerce');
3
+ const debug = Debug('liftie:domutil');
5
4
 
6
- function findText(node) {
5
+ import select from '../select.js';
6
+ import coerce from './coerce.js';
7
+
8
+ export function findText(node) {
7
9
  while (node && node.type !== 'text') {
8
10
  node = node.children?.[0];
9
11
  }
@@ -12,7 +14,7 @@ function findText(node) {
12
14
  }
13
15
  }
14
16
 
15
- function allText(node) {
17
+ export function allText(node) {
16
18
  if (node.type === 'text') {
17
19
  return node.data;
18
20
  }
@@ -25,7 +27,7 @@ function allText(node) {
25
27
  .join('');
26
28
  }
27
29
 
28
- function child(node, path) {
30
+ export function child(node, path) {
29
31
  if (typeof path === 'string') {
30
32
  path = path.split('/');
31
33
  } else if (typeof path === 'number') {
@@ -61,11 +63,11 @@ function child(node, path) {
61
63
  }, node);
62
64
  }
63
65
 
64
- function childText(node, path) {
66
+ export function childText(node, path) {
65
67
  return findText(child(node, path));
66
68
  }
67
69
 
68
- function text(node, descriptor) {
70
+ export function text(node, descriptor) {
69
71
  if (typeof descriptor === 'function') {
70
72
  return descriptor(node);
71
73
  }
@@ -99,7 +101,7 @@ function text(node, descriptor) {
99
101
 
100
102
  // parseFn can be either a function that calculates { name, status } pair
101
103
  // or an object with paths to name and status
102
- function collect(dom, selector, parse = { name: 0, status: 1 }) {
104
+ export function collect(dom, selector, parse = { name: 0, status: 1 }) {
103
105
  const parseFn =
104
106
  typeof parse === 'function'
105
107
  ? parse
@@ -132,12 +134,3 @@ function collect(dom, selector, parse = { name: 0, status: 1 }) {
132
134
 
133
135
  return ls;
134
136
  }
135
-
136
- module.exports = {
137
- child,
138
- childText,
139
- collect,
140
- findText,
141
- allText,
142
- text
143
- };
@@ -1,8 +1,10 @@
1
- const domutil = require('./domutil');
2
- const select = require('../select');
3
- const debug = require('debug')('liftie:resort:infosnow');
1
+ import Debug from 'debug';
2
+ import select from '../select.js';
3
+ import * as domutil from './domutil.js';
4
4
 
5
- function parse(dom) {
5
+ const debug = Debug('liftie:resort:infosnow');
6
+
7
+ export default function parse(dom) {
6
8
  const nodes = select(dom, '.block table tr');
7
9
  let liftStatus;
8
10
 
@@ -20,5 +22,3 @@ function parse(dom) {
20
22
  debug('Infosnow APGSGA Lift Status:', liftStatus);
21
23
  return liftStatus;
22
24
  }
23
-
24
- module.exports = parse;
@@ -1,8 +1,8 @@
1
- const coerce = require('./coerce');
1
+ import coerce from './coerce.js';
2
+
2
3
  // common parser for Intrawest http://www.intrawest.com/about-us/who-we-are.aspx
3
- module.exports = parse;
4
4
 
5
- function parse(lifts) {
5
+ export default function parse(lifts) {
6
6
  return lifts.reduce((ls, { Name: name, StatusEnglish: status }) => {
7
7
  ls[name] = coerce(status);
8
8
  return ls;
@@ -1,8 +1,6 @@
1
- const { RateLimiter } = require('limiter');
1
+ import { RateLimiter } from 'limiter';
2
2
 
3
- module.exports = Limiter;
4
-
5
- function Limiter(...args) {
3
+ export default function Limiter(...args) {
6
4
  const items = argsToLimiters(args);
7
5
  return limit;
8
6
 
@@ -1,6 +1,6 @@
1
- const toTitleCase = require('to-title-case');
1
+ import toTitleCase from 'to-title-case';
2
2
 
3
- module.exports = {
3
+ export default {
4
4
  selector: '.text:contains(Lifts) + .prl_affichage .prl_group',
5
5
  parse: {
6
6
  name: {
@@ -1,11 +1,4 @@
1
- const second = 1000;
2
- const minute = 60 * second;
3
- const hour = 60 * minute;
4
- const day = 24 * hour;
5
-
6
- module.exports = {
7
- second,
8
- minute,
9
- hour,
10
- day
11
- };
1
+ export const second = 1000;
2
+ export const minute = 60 * second;
3
+ export const hour = 60 * minute;
4
+ export const day = 24 * hour;
@@ -1,9 +1,9 @@
1
- const coerce = require('./coerce');
2
- const debug = require('debug')('liftie:resort:powdr');
1
+ import Debug from 'debug';
2
+ import coerce from './coerce.js';
3
3
 
4
- module.exports = parse;
4
+ const debug = Debug('liftie:resort:powdr');
5
5
 
6
- function parse(data) {
6
+ export default function parse(data) {
7
7
  const liftStatus = {};
8
8
 
9
9
  data.forEach(({ name, status }) => {
@@ -1,7 +1,9 @@
1
- const domutil = require('./domutil');
2
- const debug = require('debug')('liftie:resort');
1
+ import Debug from 'debug';
2
+ import * as domutil from './domutil.js';
3
3
 
4
- function parse(dom) {
4
+ const debug = Debug('liftie:resort');
5
+
6
+ export default function parse(dom) {
5
7
  const liftStatus = domutil.collect(dom, '.lift_list_table tbody tr', tr => {
6
8
  const last = tr.children[tr.children.length - 1];
7
9
  let status = domutil.findText(last);
@@ -21,5 +23,3 @@ function parse(dom) {
21
23
  debug('Lift Status:', liftStatus);
22
24
  return liftStatus;
23
25
  }
24
-
25
- module.exports = parse;
@@ -1,4 +1,4 @@
1
- module.exports = {
1
+ export default {
2
2
  selector: '.rm',
3
3
  parse: {
4
4
  name: 2,
@@ -1,4 +1,4 @@
1
- module.exports = {
1
+ export default {
2
2
  // Can't use `.c-snowreportdetail__tablerowcontent@landscape` because the @ symbol breaks the selector
3
3
  selector: '[class*="c-snowreportdetail__tablerowcontent@landscape"]',
4
4
  parse: {
@@ -8,7 +8,7 @@ module.exports = {
8
8
  status: {
9
9
  child: '0',
10
10
  attribute: 'class',
11
- regex: /o\-status\-\-(\w+)$/
11
+ regex: /o-status--(\w+)$/
12
12
  }
13
13
  }
14
14
  };
package/lib/tools/vail.js CHANGED
@@ -1,13 +1,11 @@
1
- const vm = require('node:vm');
2
- const debug = require('debug')('liftie:resort:vail');
1
+ import vm from 'node:vm';
2
+ import Debug from 'debug';
3
+ import { Parser as htmlparser } from 'htmlparser2';
4
+ import request from '../lifts/request.js';
5
+ import select from '../select.js';
6
+ import * as domutil from './domutil.js';
3
7
 
4
- const domutil = require('./domutil');
5
- const select = require('../select');
6
-
7
- const request = require('../lifts/request');
8
- const htmlparser = require('htmlparser2');
9
-
10
- module.exports = parse;
8
+ const debug = Debug('liftie:resort:vail');
11
9
 
12
10
  const statuses = ['closed', 'open', 'hold', 'scheduled'];
13
11
 
@@ -51,7 +49,7 @@ function followWaitingRoom(waitingRoom) {
51
49
  }
52
50
 
53
51
  // common parser for Vail Resorts lift status
54
- function parse(dom) {
52
+ export default function parse(dom) {
55
53
  const waitingRoom = select(dom, 'script')
56
54
  .map(script => domutil.allText(script).trim())
57
55
  .find(script => script.includes("document.location.href = '/?c=vailresorts"));
@@ -3,7 +3,7 @@ const ICON_MAP = {
3
3
  remove_circle: 'close'
4
4
  };
5
5
 
6
- module.exports = {
6
+ export default {
7
7
  selector: 'h2 + table tbody tr',
8
8
  parse: {
9
9
  name: 3,
@@ -1,9 +1,4 @@
1
- const url = require('node:url');
2
-
3
- module.exports = {
4
- iconsFromUrl,
5
- iconsFrom
6
- };
1
+ import url from 'node:url';
7
2
 
8
3
  const DAY = {
9
4
  skc: ['basenone', 'icon-sun'],
@@ -74,12 +69,12 @@ const NIGHT = {
74
69
 
75
70
  const ICONS = { DAY, NIGHT };
76
71
 
77
- function iconsFromUrl(iconUrl) {
72
+ export function iconsFromUrl(iconUrl) {
78
73
  const { pathname } = url.parse(iconUrl);
79
74
  return iconsFrom(...pathname.split('/').slice(-2));
80
75
  }
81
76
 
82
- function iconsFrom(period = '', key = '') {
77
+ export function iconsFrom(period = '', key = '') {
83
78
  key = key.split(',')[0];
84
79
  period = period.toUpperCase();
85
80
 
@@ -1,9 +1,8 @@
1
- const openweather = require('./openweather');
2
- const noaa = require('./noaa');
3
- const { hour } = require('../tools/millis');
1
+ import { hour } from '../tools/millis.js';
2
+ import noaa from './noaa.js';
3
+ import openweather from './openweather.js';
4
4
 
5
- module.exports = fetch;
6
- module.exports.interval = {
5
+ fetch.interval = {
7
6
  active: 2 * hour, // once every 2 hours for active resorts
8
7
  inactive: Number.POSITIVE_INFINITY // don't fetch on inactive
9
8
  };
@@ -11,7 +10,7 @@ module.exports.interval = {
11
10
  // see: https://openweathermap.org/forecast5
12
11
  const { OPENWEATHER_API_KEY } = process.env;
13
12
 
14
- function fetch(resort, fn) {
13
+ export default function fetch(resort, fn) {
15
14
  if (resort.noaa) {
16
15
  noaa(resort, fn);
17
16
  } else if (OPENWEATHER_API_KEY) {
@@ -1,7 +1,9 @@
1
- const debug = require('debug')('liftie:weather');
2
- const { iconsFromUrl } = require('./icons');
1
+ import Debug from 'debug';
3
2
 
4
- module.exports = fetchWeather;
3
+ const debug = Debug('liftie:weather');
4
+
5
+ import { iconsFromUrl } from './icons.js';
6
+ export default fetchWeather;
5
7
 
6
8
  const userAgent = 'Mozilla/5.0 (compatible; Liftie/1.0; +https://liftie.info)';
7
9
 
@@ -1,14 +1,13 @@
1
- const debug = require('debug')('liftie:weather');
1
+ import Debug from 'debug';
2
+ import limiter from '../tools/limiter.js';
3
+ import * as millis from '../tools/millis.js';
4
+ import { iconsFrom } from './icons.js';
2
5
 
3
- const millis = require('../tools/millis');
4
- const limiter = require('../tools/limiter');
5
- const { iconsFrom } = require('./icons');
6
+ const debug = Debug('liftie:weather');
6
7
 
7
8
  // not more than 30 a minute (60 per documentation)
8
9
  const limit = limiter(30, millis.minute);
9
10
 
10
- module.exports = fetchForecast;
11
-
12
11
  function tempInF(kelvins) {
13
12
  return Math.round((kelvins - 273.15) * 1.8) + 32;
14
13
  }
@@ -73,7 +72,7 @@ function sanitize({ city, list }) {
73
72
  };
74
73
  }
75
74
 
76
- function fetchForecast(resort, appid, fn) {
75
+ export default function fetchForecast(resort, appid, fn) {
77
76
  limit(err => {
78
77
  if (err) {
79
78
  debug('Weather API limit %s', resort.id);
package/lib/webcams.js CHANGED
@@ -1,12 +1,12 @@
1
- const debug = require('debug')('liftie:webcams');
1
+ import Debug from 'debug';
2
+ import limiter from './tools/limiter.js';
3
+ import { minute } from './tools/millis.js';
2
4
 
3
- const { minute } = require('./tools/millis');
4
- const limiter = require('./tools/limiter');
5
+ const debug = Debug('liftie:webcams');
5
6
 
6
7
  const userAgent = 'Mozilla/5.0 (compatible; Liftie/1.0; +https://liftie.info)';
7
8
 
8
- module.exports = fetchWebcams;
9
- module.exports.interval = {
9
+ fetchWebcams.interval = {
10
10
  active: 8.5 * minute, // v3 API images are only valid for 10 minutes
11
11
  inactive: Number.POSITIVE_INFINITY
12
12
  };
@@ -33,7 +33,7 @@ function getStatic({ webcams }) {
33
33
  }
34
34
  }
35
35
 
36
- function fetchWebcams(resort, fn) {
36
+ export default function fetchWebcams(resort, fn) {
37
37
  debug('Fetching webcams for %s', resort.id);
38
38
  const { WEBCAMS_API_KEY } = process.env;
39
39
  if (!resort.ll || !WEBCAMS_API_KEY) {
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "liftie",
3
- "version": "3.56.5",
3
+ "version": "4.0.0",
4
4
  "description": "Clean, simple, easy to read, fast ski resort lift status",
5
+ "type": "module",
5
6
  "keywords": [
6
7
  "ski",
7
8
  "snowboard"
@@ -57,7 +58,7 @@
57
58
  "to-title-case": "^1.0.0"
58
59
  },
59
60
  "devDependencies": {
60
- "@biomejs/biome": "^1.5.1",
61
+ "@biomejs/biome": "2.2.6",
61
62
  "@pirxpilot/stylus": "^1.2.0",
62
63
  "commander": "~13",
63
64
  "postcss": "~8",