diff --git a/package.json b/package.json
--- a/package.json
+++ b/package.json
@@ -29,7 +29,8 @@
"db:pgpull": "cargo run -p rockskyd --release -- pull && rm -f rocksky-analytics.ddb* rocksky-feed.ddb* && curl -o rocksky-analytics.ddb https://backup.rocksky.app/rocksky-analytics.ddb && curl -o rocksky-feed.ddb https://backup.rocksky.app/rocksky-feed.ddb",
"mb": "cd musicbrainz && go run main.go",
"spotify": "cd apps/api && bun run spotify",
- "build:raichu": "cd crates/raichu && wasm-pack build --release --target web && cp -r pkg ../../apps/web/src"
+ "build:raichu": "cd crates/raichu && wasm-pack build --release --target web && cp -r pkg ../../apps/web/src",
+ "cron": "tools/cron.ts"
},
"workspaces": [
"apps/api",
diff --git a/tools/cron.ts b/tools/cron.ts
new file mode 100644
--- /dev/null
+++ b/tools/cron.ts
@@ -0,0 +1,35 @@
+#!/usr/bin/env -S deno run --unstable-cron -A
+
+///
+///
+
+import chalk from "chalk";
+
+const args = Deno.args;
+
+if (args.length < 2) {
+ console.log(
+ chalk.greenBright("Usage: cron [args...]")
+ );
+ Deno.exit(0);
+}
+
+const interval = parseInt(args[0], 10);
+if (Number.isNaN(interval) || interval <= 0) {
+ console.error("Interval must be a positive integer");
+ Deno.exit(1);
+}
+
+Deno.cron("cron", { minute: { every: interval } }, async () => {
+ const command = new Deno.Command(args[1], {
+ args: args.slice(2),
+ stdout: "inherit",
+ stderr: "inherit",
+ });
+ const child = command.spawn();
+ const status = await child.status;
+ if (!status.success) {
+ console.error(`Cron job failed with code ${status.code}`);
+ }
+ console.log(`Cron job executed at ${new Date().toISOString()}`);
+});
diff --git a/tools/deno.json b/tools/deno.json
new file mode 100644
--- /dev/null
+++ b/tools/deno.json
@@ -0,0 +1,9 @@
+{
+ "tasks": {
+ "cron": "deno run cron.ts"
+ },
+ "imports": {
+ "@std/assert": "jsr:@std/assert@1",
+ "chalk": "npm:chalk@^5.6.2"
+ }
+}
\ No newline at end of file
diff --git a/tools/deno.lock b/tools/deno.lock
new file mode 100644
--- /dev/null
+++ b/tools/deno.lock
@@ -0,0 +1,30 @@
+{
+ "version": "5",
+ "specifiers": {
+ "jsr:@std/assert@1": "1.0.15",
+ "jsr:@std/internal@^1.0.12": "1.0.12",
+ "npm:chalk@^5.6.2": "5.6.2"
+ },
+ "jsr": {
+ "@std/assert@1.0.15": {
+ "integrity": "d64018e951dbdfab9777335ecdb000c0b4e3df036984083be219ce5941e4703b",
+ "dependencies": [
+ "jsr:@std/internal"
+ ]
+ },
+ "@std/internal@1.0.12": {
+ "integrity": "972a634fd5bc34b242024402972cd5143eac68d8dffaca5eaa4dba30ce17b027"
+ }
+ },
+ "npm": {
+ "chalk@5.6.2": {
+ "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="
+ }
+ },
+ "workspace": {
+ "dependencies": [
+ "jsr:@std/assert@1",
+ "npm:chalk@^5.6.2"
+ ]
+ }
+}