shabbat-gate 0.2.1 → 0.3.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.
package/CHANGELOG.md CHANGED
@@ -3,7 +3,22 @@
3
3
  All notable changes to this package are documented here. Format loosely follows
4
4
  [Keep a Changelog](https://keepachangelog.com/).
5
5
 
6
- ## [0.2.1] - Unreleased
6
+ ## [0.3.0] - Unreleased
7
+
8
+ ### Added
9
+
10
+ - `ShabbatGateConfig.geonameid` (and `FetchWindowsOptions.geonameid`) - set the site's home city
11
+ by Hebcal geonameid instead of `latitude`/`longitude`, so the base Shabbat/holiday times come
12
+ out at Hebcal's *official* times for that city. This matters because a city's official
13
+ candle-lighting can differ from a raw sunset-minus-default computation at the same coordinates:
14
+ e.g. Haifa (`294801`) lights ~10 minutes earlier than its bare lat/long - a real gap for a
15
+ Shabbat-observant site owner. When set, `latitude`/`longitude` are ignored for the base window
16
+ (and the internal cache key is namespaced by the geonameid so switching location doesn't serve
17
+ stale coordinate-based windows). Does not affect `enforceVisitorLocation` - visitor windows
18
+ always come from the visitor's `request.cf` coordinates. Common Israeli IDs: Jerusalem=281184,
19
+ Haifa=294801, Tel Aviv=293397, Beer Sheva=295530.
20
+
21
+ ## [0.2.1] - 2026-07-19
7
22
 
8
23
  ### Fixed
9
24
 
package/README.he.md CHANGED
@@ -80,10 +80,19 @@ export interface ShabbatGateConfig {
80
80
  siteName: string;
81
81
 
82
82
  /** קווי אורך/רוחב עשרוניים לחישוב זמנים. ברירת מחדל לשניהם היא ירושלים (31.7683,
83
- * 35.2137) אם לא סופקו - נקודת ייחוס טובה לכל ישראל ברזולוציה הזו. */
83
+ * 35.2137) אם לא סופקו - נקודת ייחוס טובה לכל ישראל ברזולוציה הזו. מתעלמים ממנו
84
+ * כאשר מוגדר `geonameid`. */
84
85
  latitude?: number;
85
86
  longitude?: number;
86
87
 
88
+ /** geonameid של Hebcal לעיר הבית של האתר. כשמוגדר, זמני השבת/חג של האתר נלקחים
89
+ * מהזמנים ה*רשמיים* של אותה עיר ב-Hebcal, במקום חישוב שקיעה-פחות-ברירת-מחדל
90
+ * בקואורדינטות גולמיות (ההפרש אמיתי - למשל חיפה `294801` מדליקה נרות ~10 דק'
91
+ * מוקדם יותר מה-lat/long הגולמי שלה). `latitude`/`longitude` לא בשימוש כשזה מוגדר.
92
+ * לא משפיע על `enforceVisitorLocation` (חלונות הגולש תמיד לפי `request.cf`).
93
+ * ירושלים=281184, חיפה=294801, תל אביב=293397, באר שבע=295530. */
94
+ geonameid?: number;
95
+
87
96
  /** שם פרמטר + ערך נדרש ב-query string שעוקפים את השער לגמרי, כדי שבעל האתר יוכל
88
97
  * לבדוק/לתצוגה מקדימה בכל יום. חשוב לבחור ערך שלא ניתן לניחוש - זו נוחות לבדיקות,
89
98
  * לא הרשאה אמיתית. */
package/README.md CHANGED
@@ -80,10 +80,18 @@ export interface ShabbatGateConfig {
80
80
  siteName: string;
81
81
 
82
82
  /** Decimal lat/long for zmanim. Both default to Jerusalem (31.7683, 35.2137) if
83
- * omitted - a fine single reference point for all of Israel at this granularity. */
83
+ * omitted - a fine single reference point for all of Israel at this granularity.
84
+ * Ignored when `geonameid` is set. */
84
85
  latitude?: number;
85
86
  longitude?: number;
86
87
 
88
+ /** Hebcal geonameid of the site's home city. When set, the base Shabbat/holiday times use
89
+ * Hebcal's *official* times for that city instead of sunset-minus-default at raw coordinates
90
+ * (they can differ - e.g. Haifa `294801` lights ~10 min earlier than its bare lat/long).
91
+ * `latitude`/`longitude` are ignored when set. Does not affect `enforceVisitorLocation`.
92
+ * Jerusalem=281184, Haifa=294801, Tel Aviv=293397, Beer Sheva=295530. */
93
+ geonameid?: number;
94
+
87
95
  /** Query param name + required value that bypasses the gate entirely, so the site
88
96
  * owner can preview/test on any day. Keep the value non-guessable - this is a
89
97
  * testing convenience, not real auth. */
package/dist/hebcal.d.ts CHANGED
@@ -62,6 +62,15 @@ export interface FetchWindowsOptions {
62
62
  * computing their local windows so day boundaries line up with their sunset,
63
63
  * not Jerusalem's. */
64
64
  tzid?: string;
65
+ /** Hebcal geonameid of a specific city. When set, the query uses this city
66
+ * instead of `latitude`/`longitude`, so candle-lighting/havdalah come out at
67
+ * Hebcal's *official* times for that city - which can differ from a raw
68
+ * sunset-minus-18-minutes computation at the same coordinates (e.g. Haifa,
69
+ * geonameid 294801, lights ~10 min earlier than its bare lat/long). Use this
70
+ * for the site's own reference location when you want the exact city time;
71
+ * `latitude`/`longitude` are ignored when it is present. Jerusalem=281184,
72
+ * Haifa=294801, Tel Aviv=293397, Beer Sheva=295530. */
73
+ geonameid?: number;
65
74
  }
66
75
  /**
67
76
  * Fetches and merges Shabbat + major-holiday windows for the next ~45 days from
package/dist/hebcal.js CHANGED
@@ -85,13 +85,18 @@ export async function fetchWindows(latitude, longitude, options = {}) {
85
85
  const end = new Date(start.getTime() + 45 * 24 * 60 * 60 * 1000);
86
86
  const startParam = toISODate(start);
87
87
  const endParam = toISODate(end);
88
+ // A specific city (geonameid) yields Hebcal's official times for that city;
89
+ // otherwise fall back to raw coordinates (sunset-minus-default at that point).
90
+ const locationParam = options.geonameid != null
91
+ ? `geonameid=${options.geonameid}`
92
+ : `latitude=${latitude}&longitude=${longitude}`;
88
93
  // i=on = Israel single-day Yom Tov reckoning; i=off = diaspora 2-day.
89
94
  // c=on = attach candles/havdalah entries to holidays, not just bare dates.
90
- // ss=on = weekly Shabbat candle-lighting/havdalah, localized to lat/long.
95
+ // ss=on = weekly Shabbat candle-lighting/havdalah, localized to the location.
91
96
  // maj=on + everything else off = only real work-restricted Yom Tov days.
92
97
  const iParam = israelMode ? 'on' : 'off';
93
98
  const url = `https://www.hebcal.com/hebcal?cfg=json&v=1&maj=on&min=off&mod=off&nx=off&mf=off&ss=on` +
94
- `&c=on&i=${iParam}&latitude=${latitude}&longitude=${longitude}&tzid=${encodeURIComponent(tzid)}` +
99
+ `&c=on&i=${iParam}&${locationParam}&tzid=${encodeURIComponent(tzid)}` +
95
100
  `&start=${startParam}&end=${endParam}`;
96
101
  const res = await fetch(url);
97
102
  if (!res.ok) {
package/dist/index.d.ts CHANGED
@@ -9,9 +9,19 @@ export { defaultRenderHoldingPage } from './holdingPage.js';
9
9
  export interface ShabbatGateConfig {
10
10
  siteName: string;
11
11
  /** Decimal lat/long for zmanim. Both default to Jerusalem if omitted - a fine
12
- * single reference point for all of Israel at this granularity. */
12
+ * single reference point for all of Israel at this granularity. Ignored when
13
+ * `geonameid` is set. */
13
14
  latitude?: number;
14
15
  longitude?: number;
16
+ /** Hebcal geonameid of the site's home city. When set, the site's own
17
+ * Shabbat/holiday times come from Hebcal's *official* times for that city
18
+ * (rather than sunset-minus-default at raw coordinates), and `latitude`/
19
+ * `longitude` are ignored for the base window. Preferred over lat/long when
20
+ * you want a specific Israeli city exactly - e.g. Haifa (`294801`) lights
21
+ * ~10 min earlier than its bare coordinates. Jerusalem=281184, Haifa=294801,
22
+ * Tel Aviv=293397, Beer Sheva=295530. Does not affect `enforceVisitorLocation`
23
+ * (visitor windows always come from the visitor's `request.cf` coordinates). */
24
+ geonameid?: number;
15
25
  /** Query param name + required value that bypasses the gate entirely, for
16
26
  * the site owner to preview/test on any day. Keep the value non-guessable -
17
27
  * this is a testing convenience, not real auth. */
package/dist/index.js CHANGED
@@ -56,9 +56,13 @@ function readVisitorLocation(request) {
56
56
  }
57
57
  return { latitude, longitude, tzid, israelMode: cf.country === 'IL' };
58
58
  }
59
- /** Israel/Jerusalem windows - the base gate, always computed. */
60
- function getIsraelWindows(latitude, longitude) {
61
- return getCachedWindows(INTERNAL_CACHE_KEY_URL, () => fetchWindows(latitude, longitude));
59
+ /** Israel windows - the base gate, always computed. When `geonameid` is set the
60
+ * site's own times come from Hebcal's official city times (and the cache key is
61
+ * namespaced by it so switching location doesn't serve stale coordinate-based
62
+ * windows for up to 24h). */
63
+ function getIsraelWindows(latitude, longitude, geonameid) {
64
+ const cacheKey = geonameid != null ? `${INTERNAL_CACHE_KEY_URL}?geonameid=${geonameid}` : INTERNAL_CACHE_KEY_URL;
65
+ return getCachedWindows(cacheKey, () => fetchWindows(latitude, longitude, geonameid != null ? { geonameid } : {}));
62
66
  }
63
67
  /** Windows for a specific visitor location, cached per rounded cell. */
64
68
  function getVisitorWindows(loc) {
@@ -111,7 +115,7 @@ async function evaluateGate(config, request) {
111
115
  // local-time display shown to a visitor outside Israel.
112
116
  const visitor = readVisitorLocation(request);
113
117
  const isAbroad = visitor !== null && !visitor.israelMode;
114
- let windows = applyBuffer(await getIsraelWindows(latitude, longitude), bufferMinutes);
118
+ let windows = applyBuffer(await getIsraelWindows(latitude, longitude, config.geonameid), bufferMinutes);
115
119
  if (config.enforceVisitorLocation && visitor) {
116
120
  const visitorWindows = applyBuffer(await getVisitorWindows(visitor), bufferMinutes);
117
121
  // Union of both calendars: block if it's Shabbat/Yom Tov in Israel OR
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shabbat-gate",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Cloudflare Pages/Workers middleware that closes a site to human visitors during Shabbat and major Jewish holidays (Israel-observance rules), while always letting search engines and AI crawlers through.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",