summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuval Adam <_@yuv.al>2025-10-03 11:52:01 +0200
committerYuval Adam <_@yuv.al>2025-10-03 11:52:01 +0200
commit7b6314f480d4f7a0932d6463e5341e21566a37c2 (patch)
tree852174e337af4ec373e966b642dc59ca0a7e5c74
parentdc4d65708c92cba5652597af8eb49d1297026e15 (diff)
Implement loading of unauthenticated radar GIS images
-rw-r--r--astro.config.mjs5
-rw-r--r--package-lock.json84
-rw-r--r--package.json2
-rw-r--r--src/functions/scheduled.ts229
-rw-r--r--src/worker.ts18
-rw-r--r--worker-configuration.d.ts28
-rw-r--r--wrangler.jsonc10
7 files changed, 232 insertions, 144 deletions
diff --git a/astro.config.mjs b/astro.config.mjs
index 2674216..fff01e2 100644
--- a/astro.config.mjs
+++ b/astro.config.mjs
@@ -18,7 +18,10 @@ export default defineConfig({
},
adapter: cloudflare({
- imageService: "compile"
+ imageService: "compile",
+ workerEntryPoint: {
+ path: 'src/worker.ts'
+ }
}),
devToolbar: {
diff --git a/package-lock.json b/package-lock.json
index caa9127..2729cdc 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -23,7 +23,7 @@
"tailwindcss": "^4.1.13"
},
"devDependencies": {
- "wrangler": "^4.39.0"
+ "wrangler": "^4.41.0"
}
},
"node_modules/@astrojs/cloudflare": {
@@ -1490,14 +1490,14 @@
}
},
"node_modules/@cloudflare/unenv-preset": {
- "version": "2.7.4",
- "resolved": "https://registry.npmjs.org/@cloudflare/unenv-preset/-/unenv-preset-2.7.4.tgz",
- "integrity": "sha512-KIjbu/Dt50zseJIoOOK5y4eYpSojD9+xxkePYVK1Rg9k/p/st4YyMtz1Clju/zrenJHrOH+AAcjNArOPMwH4Bw==",
+ "version": "2.7.5",
+ "resolved": "https://registry.npmjs.org/@cloudflare/unenv-preset/-/unenv-preset-2.7.5.tgz",
+ "integrity": "sha512-eB3UAIVhrvY+CMZrRXS/bAv5kWdNiH+dgwu+1M1S7keDeonxkfKIGVIrhcCLTkcqYlN30MPURPuVFUEzIWuuvg==",
"dev": true,
"license": "MIT OR Apache-2.0",
"peerDependencies": {
"unenv": "2.0.0-rc.21",
- "workerd": "^1.20250912.0"
+ "workerd": "^1.20250924.0"
},
"peerDependenciesMeta": {
"workerd": {
@@ -1506,9 +1506,9 @@
}
},
"node_modules/@cloudflare/workerd-darwin-64": {
- "version": "1.20250923.0",
- "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20250923.0.tgz",
- "integrity": "sha512-CUyVkdTaREdT/wynh5/VX3prawWpYeoqGjcEyo920/HqXaRuA/owp9ijg1vh1rmHyxN0XvsjHuRwBfnrptGmrg==",
+ "version": "1.20251001.0",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20251001.0.tgz",
+ "integrity": "sha512-y1ST/cCscaRewWRnsHZdWbgiLJbki5UMGd0hMo/FLqjlztwPeDgQ5CGm5jMiCDdw/IBCpWxEukftPYR34rWNog==",
"cpu": [
"x64"
],
@@ -1523,9 +1523,9 @@
}
},
"node_modules/@cloudflare/workerd-darwin-arm64": {
- "version": "1.20250923.0",
- "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20250923.0.tgz",
- "integrity": "sha512-wblU5WYlNRnrTMupeWFRoysJH/Y7d6h+Wc1G+GTmaMV6TcxyXj804Hk8Tk3jqvaS0SXmkh5sIQ38MBVrBs7sag==",
+ "version": "1.20251001.0",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20251001.0.tgz",
+ "integrity": "sha512-+z4QHHZ/Yix82zLFYS+ZS2UV09IENFPwDCEKUWfnrM9Km2jOOW3Ua4hJNob1EgQUYs8fFZo7k5O/tpwxMsSbbQ==",
"cpu": [
"arm64"
],
@@ -1540,9 +1540,9 @@
}
},
"node_modules/@cloudflare/workerd-linux-64": {
- "version": "1.20250923.0",
- "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20250923.0.tgz",
- "integrity": "sha512-WFP0KBJWhdDJWChIw3HJmrtYLNQDB8X9R3o548FcE5NiD05J0rI5Pnhno008lanjmXzia1lghWIQErfpjpmQzg==",
+ "version": "1.20251001.0",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20251001.0.tgz",
+ "integrity": "sha512-hGS+O2V9Mm2XjJUaB9ZHMA5asDUaDjKko42e+accbew0PQR7zrAl1afdII6hMqCLV4tk4GAjvhv281pN4g48rg==",
"cpu": [
"x64"
],
@@ -1557,9 +1557,9 @@
}
},
"node_modules/@cloudflare/workerd-linux-arm64": {
- "version": "1.20250923.0",
- "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20250923.0.tgz",
- "integrity": "sha512-h5VegEhn9CPfGnTc4JTFLGzR806naeIcKUHWi8ejc1hO38YthC6mBNsOjbZrSkp4B3H/kstuhuW16x2rGX0oBg==",
+ "version": "1.20251001.0",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20251001.0.tgz",
+ "integrity": "sha512-QYaMK+pRgt28N7CX1JlJ+ToegJF9LxzqdT7MjWqPgVj9D2WTyIhBVYl3wYjJRcgOlnn+DRt42+li4T64CPEeuA==",
"cpu": [
"arm64"
],
@@ -1574,9 +1574,9 @@
}
},
"node_modules/@cloudflare/workerd-windows-64": {
- "version": "1.20250923.0",
- "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20250923.0.tgz",
- "integrity": "sha512-S1E2Vm11ClrwHLqbVO59pKpxllHkq3APRdt3wCbVZNG7jGctxEYLH2uE0K1O1JBfbk2fKMaa+sbmtMpXDXi1tw==",
+ "version": "1.20251001.0",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20251001.0.tgz",
+ "integrity": "sha512-ospnDR/FlyRvrv9DSHuxDAXmzEBLDUiAHQrQHda1iUH9HqxnNQ8giz9VlPfq7NIRc7bQ1ZdIYPGLJOY4Q366Ng==",
"cpu": [
"x64"
],
@@ -1591,9 +1591,9 @@
}
},
"node_modules/@cloudflare/workers-types": {
- "version": "4.20250924.0",
- "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20250924.0.tgz",
- "integrity": "sha512-pi/OYCroYdwjFWbkciC5oYzlyimDF4ymNotDK0zpLNq91Ogz1IXnVBAYV7fCFAJ/zIxU0RiIBrJIOll/C0pR9Q==",
+ "version": "4.20251003.0",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20251003.0.tgz",
+ "integrity": "sha512-rtg7FqYVNHsltn1GOV+P3hQpVf1WDI3wH8Mj4IjK99fidJ4ttzUPuCX/uYE/PIF/HBPK66TqVwToO+GN4Lmx0Q==",
"license": "MIT OR Apache-2.0"
},
"node_modules/@cspotcode/source-map-support": {
@@ -6105,9 +6105,9 @@
}
},
"node_modules/miniflare": {
- "version": "4.20250923.0",
- "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-4.20250923.0.tgz",
- "integrity": "sha512-CtO0w3tKr8rl5nS5TchYNGQaXuYLfl1T+IqKQiEoIRAUpVWdiziK49+mKV+Vz6yRENqHEGMYV8EjhfvmEHrJpA==",
+ "version": "4.20251001.0",
+ "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-4.20251001.0.tgz",
+ "integrity": "sha512-OHd31D2LT8JH+85nVXClV0Z18jxirCohzKNAcZs/fgt4mIkUDtidX3VqR3ovAM0jWooNxrFhB9NSs3iDbiJF7Q==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6119,7 +6119,7 @@
"sharp": "^0.33.5",
"stoppable": "1.1.0",
"undici": "7.14.0",
- "workerd": "1.20250923.0",
+ "workerd": "1.20251001.0",
"ws": "8.18.0",
"youch": "4.1.0-beta.10",
"zod": "3.22.3"
@@ -8191,9 +8191,9 @@
}
},
"node_modules/workerd": {
- "version": "1.20250923.0",
- "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20250923.0.tgz",
- "integrity": "sha512-avGZgJe3Vug0ff8oq5Hpa//x0dF9b12jKhDKqaEZaWl7mVGQk+GaA9lrO8TyJxzlfPIr/rXdvcRYJi/hbdgIJw==",
+ "version": "1.20251001.0",
+ "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20251001.0.tgz",
+ "integrity": "sha512-oT/K4YWNhmwpVmGeaHNmF7mLRfgjszlVr7lJtpS4jx5khmxmMzWZEEQRrJEpgzeHP6DOq9qWLPNT0bjMK7TchQ==",
"dev": true,
"hasInstallScript": true,
"license": "Apache-2.0",
@@ -8204,28 +8204,28 @@
"node": ">=16"
},
"optionalDependencies": {
- "@cloudflare/workerd-darwin-64": "1.20250923.0",
- "@cloudflare/workerd-darwin-arm64": "1.20250923.0",
- "@cloudflare/workerd-linux-64": "1.20250923.0",
- "@cloudflare/workerd-linux-arm64": "1.20250923.0",
- "@cloudflare/workerd-windows-64": "1.20250923.0"
+ "@cloudflare/workerd-darwin-64": "1.20251001.0",
+ "@cloudflare/workerd-darwin-arm64": "1.20251001.0",
+ "@cloudflare/workerd-linux-64": "1.20251001.0",
+ "@cloudflare/workerd-linux-arm64": "1.20251001.0",
+ "@cloudflare/workerd-windows-64": "1.20251001.0"
}
},
"node_modules/wrangler": {
- "version": "4.39.0",
- "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.39.0.tgz",
- "integrity": "sha512-DP/iJdxXiLCCSshCwsMl7PjOTZNJq5vzeN/hgEHHU7m85GIjPCLH0VvR/T2IFO5twyd4CukPveM4blhVUmRy2A==",
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.41.0.tgz",
+ "integrity": "sha512-SPiBk/5SgCSIdcWw8EXc8DzqtrjbIU+/n22fQjyz4RnULAqCFJjy84F5crcWnb1J/iPiOzm7mS9bMGFFtpwS/w==",
"dev": true,
"license": "MIT OR Apache-2.0",
"dependencies": {
"@cloudflare/kv-asset-handler": "0.4.0",
- "@cloudflare/unenv-preset": "2.7.4",
+ "@cloudflare/unenv-preset": "2.7.5",
"blake3-wasm": "2.1.5",
"esbuild": "0.25.4",
- "miniflare": "4.20250923.0",
+ "miniflare": "4.20251001.0",
"path-to-regexp": "6.3.0",
"unenv": "2.0.0-rc.21",
- "workerd": "1.20250923.0"
+ "workerd": "1.20251001.0"
},
"bin": {
"wrangler": "bin/wrangler.js",
@@ -8238,7 +8238,7 @@
"fsevents": "~2.3.2"
},
"peerDependencies": {
- "@cloudflare/workers-types": "^4.20250923.0"
+ "@cloudflare/workers-types": "^4.20251001.0"
},
"peerDependenciesMeta": {
"@cloudflare/workers-types": {
diff --git a/package.json b/package.json
index 6286687..dd43f7e 100644
--- a/package.json
+++ b/package.json
@@ -24,6 +24,6 @@
"tailwindcss": "^4.1.13"
},
"devDependencies": {
- "wrangler": "^4.39.0"
+ "wrangler": "^4.41.0"
}
}
diff --git a/src/functions/scheduled.ts b/src/functions/scheduled.ts
index ae43469..f92d556 100644
--- a/src/functions/scheduled.ts
+++ b/src/functions/scheduled.ts
@@ -1,51 +1,97 @@
// Cloudflare Workers scheduled handler for cron jobs
import type { ScheduledController, ScheduledEvent } from '@cloudflare/workers-types';
+import { DateTime } from 'luxon';
interface Env {
- BASE_URL: string;
- AUTH_USER: string;
- AUTH_PASS: string;
IMGS_BUCKET: R2Bucket;
}
+interface RadarImage {
+ id: string;
+ forecast_time: string;
+ modified: string;
+ created: string;
+ file_name: string;
+ type: string;
+}
+
+interface RadarResponse {
+ data: {
+ types: {
+ IMSRadar: RadarImage[];
+ };
+ };
+}
+
class GeshemUpdate {
private bucket: R2Bucket;
- private env: Env;
+ private static readonly API_URL = 'https://ims.gov.il/he/radar_satellite';
+ private static readonly BASE_URL = 'https://ims.gov.il';
- constructor(bucket: R2Bucket, env: Env) {
+ constructor(bucket: R2Bucket) {
this.bucket = bucket;
- this.env = env;
}
- private async authenticate(request: Request): Promise<Request> {
- const headers = new Headers(request.headers);
- const credentials = btoa(`${this.env.AUTH_USER}:${this.env.AUTH_PASS}`);
- headers.set('Authorization', `Basic ${credentials}`);
+ private convertIsraeliToUTC(dateStr: string, timeStr: string): { date: string; time: string } {
+ // Parse YYYYMMDD HHMM format in Israeli timezone
+ const israeliTime = DateTime.fromFormat(
+ `${dateStr} ${timeStr}`,
+ 'yyyyMMdd HHmm',
+ { zone: 'Asia/Jerusalem' }
+ );
- return new Request(request.url, {
- method: request.method,
- headers,
- body: request.body
- });
+ // Convert to UTC
+ const utcTime = israeliTime.toUTC();
+
+ // Format as YYYYMMDD and HHMM
+ return {
+ date: utcTime.toFormat('yyyyMMdd'),
+ time: utcTime.toFormat('HHmm')
+ };
}
- private async getLatestImages(): Promise<string[]> {
- const authenticatedRequest = await this.authenticate(new Request(this.env.BASE_URL));
- const response = await fetch(authenticatedRequest);
- const html = await response.text();
+ private async getLatestImage(): Promise<RadarImage | null> {
+ const response = await fetch(GeshemUpdate.API_URL);
- const regex = /radar280comp_\d+\.png/g;
- const matches = html.match(regex) || [];
- const uniqueImages = [...new Set(matches)];
+ if (!response.ok) {
+ throw new Error(`Failed to fetch radar data: ${response.statusText}`);
+ }
+
+ const data: RadarResponse = await response.json();
+ const images = data.data.types.IMSRadar;
+
+ if (!images || images.length === 0) {
+ return null;
+ }
- return uniqueImages.sort().slice(-10);
+ // Get the latest image (last in the array)
+ return images[images.length - 1];
}
- private async getLatestBucketKeys(): Promise<string[]> {
- const yesterday = new Date();
- yesterday.setDate(yesterday.getDate() - 1);
- const yesterdayStr = yesterday.toISOString().slice(0, 10).replace(/-/g, '');
+ private parseFilename(filepath: string): { date: string; time: string } | null {
+ // Extract filename from path: /sites/default/files/ims_data/map_images/IMSRadar4GIS/IMSRadar4GIS_202510030935_0.png
+ const filename = filepath.split('/').pop();
+ if (!filename) return null;
+
+ // Match pattern: IMSRadar4GIS_YYYYMMDDHHMM_0.png
+ const match = filename.match(/IMSRadar4GIS_(\d{8})(\d{4})_\d\.png/);
+ if (!match) return null;
+
+ const dateStr = match[1]; // YYYYMMDD
+ const timeStr = match[2]; // HHMM
+
+ return { date: dateStr, time: timeStr };
+ }
+
+ private async getExistingGisKeys(): Promise<Set<string>> {
+ // Get yesterday's date in YYYYMMDD format
+ const yesterday = DateTime.utc().minus({ days: 1 });
+ const yesterdayStr = yesterday.toFormat('yyyyMMdd');
+
+ console.log(`Listing bucket keys starting from ${yesterdayStr}`);
+
+ const existingKeys = new Set<string>();
try {
const objects = await this.bucket.list({
@@ -53,42 +99,70 @@ class GeshemUpdate {
startAfter: `imgs/${yesterdayStr}`
});
- return objects.objects.map(obj => obj.key);
+ for (const obj of objects.objects) {
+ // Only include keys that end with gis.png
+ if (obj.key.endsWith('gis.png')) {
+ existingKeys.add(obj.key);
+ }
+ }
+
+ console.log(`Found ${existingKeys.size} existing gis.png files since ${yesterdayStr}`);
} catch (error) {
console.error('Error listing bucket objects:', error);
- return [];
}
+
+ return existingKeys;
}
- private async fetchMissingImages(): Promise<boolean> {
- const images = await this.getLatestImages();
- const s3Images = await this.getLatestBucketKeys();
- let updated = false;
+ private async fetchAndStoreImages(): Promise<number> {
+ // Get all images from API
+ const apiImage = await this.getLatestImage();
+ if (!apiImage) {
+ console.log('No images found in API response');
+ return 0;
+ }
+
+ // Get existing gis.png keys in bucket
+ const existingKeys = await this.getExistingGisKeys();
- for (const img of images) {
- const key = this.keyFromFilename(img);
- if (!s3Images.includes(key)) {
- await this.fetchImage(img, key);
- updated = true;
- }
+ let savedCount = 0;
+
+ console.log(`Processing image: ${apiImage.file_name}`);
+
+ // Parse filename to get date and time
+ const parsed = this.parseFilename(apiImage.file_name);
+ if (!parsed) {
+ console.error(`Failed to parse filename: ${apiImage.file_name}`);
+ return 0;
}
- return updated;
- }
+ console.log(`Parsed Israeli time - Date: ${parsed.date}, Time: ${parsed.time}`);
- private async fetchImage(imgName: string, key: string): Promise<void> {
- console.log(`Downloading ${imgName} from web server`);
+ // Convert Israeli time to UTC
+ const utc = this.convertIsraeliToUTC(parsed.date, parsed.time);
+ console.log(`Converted to UTC - Date: ${utc.date}, Time: ${utc.time}`);
- const imageUrl = `${this.env.BASE_URL}/${imgName}`;
- const authenticatedRequest = await this.authenticate(new Request(imageUrl));
- const response = await fetch(authenticatedRequest);
+ // Build R2 key: imgs/YYYYMMDD/HHMM/gis.png
+ const key = `imgs/${utc.date}/${utc.time}/gis.png`;
+
+ // Check if already exists
+ if (existingKeys.has(key)) {
+ console.log(`Image already exists at ${key}`);
+ return 0;
+ }
+ // Fetch the image
+ const imageUrl = `${GeshemUpdate.BASE_URL}${apiImage.file_name}`;
+ console.log(`Downloading from ${imageUrl}`);
+
+ const response = await fetch(imageUrl);
if (!response.ok) {
throw new Error(`Failed to fetch image: ${response.statusText}`);
}
const imageData = await response.arrayBuffer();
+ // Upload to R2
console.log(`Uploading to ${key}`);
await this.bucket.put(key, imageData, {
httpMetadata: {
@@ -96,30 +170,17 @@ class GeshemUpdate {
cacheControl: 'public, max-age=31536000'
}
});
- }
-
- private keyFromFilename(filename: string): string {
- const [name, dateStr] = filename.split('.')[0].split('_');
- const res = 280;
- // Parse date: YYYYMMDDHHMM
- const year = dateStr.slice(0, 4);
- const month = dateStr.slice(4, 6);
- const day = dateStr.slice(6, 8);
- const hour = dateStr.slice(8, 10);
- const minute = dateStr.slice(10, 12);
+ savedCount++;
- const d = `${year}${month}${day}`;
- const t = `${hour}${minute}`;
-
- return `imgs/${d}/${t}/${res}.png`;
+ return savedCount;
}
async run(): Promise<string> {
try {
- const updated = await this.fetchMissingImages();
- return `Updated: ${updated}`;
+ const savedCount = await this.fetchAndStoreImages();
+ return `Saved ${savedCount} new images`;
} catch (error) {
console.error('Error in GeshemUpdate.run():', error);
throw error;
@@ -127,30 +188,34 @@ class GeshemUpdate {
}
}
+export async function handleSchedule(
+ controller: ScheduledController,
+ env: Env,
+ ctx: ExecutionContext
+): Promise<void> {
+ console.log('Cron job triggered at', new Date().toISOString());
+
+ try {
+ if (!env.IMGS_BUCKET) {
+ throw new Error('R2 bucket not configured');
+ }
+
+ const updater = new GeshemUpdate(env.IMGS_BUCKET);
+ const result = await updater.run();
+
+ console.log(`Cron job completed: ${result}`);
+ } catch (error) {
+ console.error('Error in scheduled function:', error);
+ throw error;
+ }
+}
+
export default {
async scheduled(
controller: ScheduledController,
env: Env,
ctx: ExecutionContext
): Promise<void> {
- console.log('Cron job triggered at', new Date().toISOString());
-
- try {
- if (!env?.BASE_URL || !env?.AUTH_USER || !env?.AUTH_PASS) {
- throw new Error('Missing environment variables');
- }
-
- if (!env.IMGS_BUCKET) {
- throw new Error('R2 bucket not configured');
- }
-
- const updater = new GeshemUpdate(env.IMGS_BUCKET, env);
- const result = await updater.run();
-
- console.log(`Cron job completed: ${result}`);
- } catch (error) {
- console.error('Error in scheduled function:', error);
- throw error;
- }
+ return handleSchedule(controller, env, ctx);
}
}; \ No newline at end of file
diff --git a/src/worker.ts b/src/worker.ts
new file mode 100644
index 0000000..e982634
--- /dev/null
+++ b/src/worker.ts
@@ -0,0 +1,18 @@
+import type { SSRManifest } from 'astro';
+import { App } from 'astro/app';
+import { handle } from '@astrojs/cloudflare/handler';
+import { handleSchedule } from './functions/scheduled';
+
+export function createExports(manifest: SSRManifest) {
+ const app = new App(manifest);
+ return {
+ default: {
+ async fetch(request, env, ctx) {
+ return handle(manifest, app, request, env, ctx);
+ },
+ async scheduled(controller, env, ctx) {
+ return await handleSchedule(controller, env, ctx);
+ }
+ }
+ };
+}
diff --git a/worker-configuration.d.ts b/worker-configuration.d.ts
index 5d6133a..a7db243 100644
--- a/worker-configuration.d.ts
+++ b/worker-configuration.d.ts
@@ -1,6 +1,6 @@
/* eslint-disable */
// Generated by Wrangler by running `wrangler types` (hash: 86ac7c910eaa8ed87087e10bf93f5438)
-// Runtime types generated with workerd@1.20250923.0 2025-09-24 nodejs_compat
+// Runtime types generated with workerd@1.20251001.0 2025-09-24 nodejs_compat
declare namespace Cloudflare {
interface GlobalProps {
mainModule: typeof import("./dist/_worker.js/index");
@@ -7465,6 +7465,19 @@ interface MediaError extends Error {
readonly message: string;
readonly stack?: string;
}
+declare module 'cloudflare:node' {
+ interface NodeStyleServer {
+ listen(...args: unknown[]): this;
+ address(): {
+ port?: number | null | undefined;
+ };
+ }
+ export function httpServerHandler(port: number): ExportedHandler;
+ export function httpServerHandler(options: {
+ port: number;
+ }): ExportedHandler;
+ export function httpServerHandler(server: NodeStyleServer): ExportedHandler;
+}
type Params<P extends string = any> = Record<P, string | string[]>;
type EventContext<Env, P extends string, Data> = {
request: Request<unknown, IncomingRequestCfProperties<unknown>>;
@@ -7722,19 +7735,6 @@ declare namespace Cloudflare {
& (K extends GlobalProp<"durableNamespaces", never> ? MainModule[K] extends new (...args: any[]) => infer DoInstance ? DoInstance extends Rpc.DurableObjectBranded ? DurableObjectNamespace<DoInstance> : DurableObjectNamespace<undefined> : DurableObjectNamespace<undefined> : {});
};
}
-declare module 'cloudflare:node' {
- export interface DefaultHandler {
- fetch?(request: Request): Response | Promise<Response>;
- tail?(events: TraceItem[]): void | Promise<void>;
- trace?(traces: TraceItem[]): void | Promise<void>;
- scheduled?(controller: ScheduledController): void | Promise<void>;
- queue?(batch: MessageBatch<unknown>): void | Promise<void>;
- test?(controller: TestController): void | Promise<void>;
- }
- export function httpServerHandler(options: {
- port: number;
- }, handlers?: Omit<DefaultHandler, 'fetch'>): DefaultHandler;
-}
declare namespace CloudflareWorkersModule {
export type RpcStub<T extends Rpc.Stubable> = Rpc.Stub<T>;
export const RpcStub: {
diff --git a/wrangler.jsonc b/wrangler.jsonc
index db8f5e7..052b59e 100644
--- a/wrangler.jsonc
+++ b/wrangler.jsonc
@@ -27,8 +27,10 @@
"pattern": "www.geshem.space",
"custom_domain": true
}
- ]
- // "triggers": {
- // "crons": ["* * * * *"]
- // }
+ ],
+ "triggers": {
+ "crons": [
+ "* * * * *"
+ ]
+ }
} \ No newline at end of file