flingit 0.0.30 → 0.0.31

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.
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Worker entry point factory for Cloudflare Workers.
3
+ *
4
+ * This module contains the actual entry logic that was previously
5
+ * generated as a string template in the bundler. It exports a factory
6
+ * function that creates the Worker's fetch handler.
7
+ *
8
+ * The bundler generates a minimal shim that wires the user app path:
9
+ * import { createWorkerEntry } from "./entry.js";
10
+ * export default createWorkerEntry(() => import("./user-app.js"));
11
+ */
12
+ import { __initEnv, __getApp, __runMigrations, __getCronHandlers } from "./index.js";
13
+ import { __handlePluginRequest as __handle_discord } from "./discord.js";
14
+ import { __handlePluginRequest as __handle_slack } from "./slack.js";
15
+ const pluginHandlers = {
16
+ discord: __handle_discord,
17
+ slack: __handle_slack,
18
+ };
19
+ const pluginPathPattern = /^\/__plugin\/(\w+)$/;
20
+ /**
21
+ * Create a Cloudflare Worker entry point.
22
+ *
23
+ * @param loadUserApp - Function that imports the user's app module (triggers route registration)
24
+ * @returns Worker module with fetch handler
25
+ */
26
+ export function createWorkerEntry(loadUserApp) {
27
+ let initialized = false;
28
+ let initError = null;
29
+ async function ensureInit(env) {
30
+ // If initialization previously failed, throw the same error
31
+ if (initError) {
32
+ throw initError instanceof Error
33
+ ? initError
34
+ : new Error(typeof initError === "string" ? initError : "Initialization failed");
35
+ }
36
+ if (!initialized) {
37
+ __initEnv(env);
38
+ try {
39
+ await loadUserApp();
40
+ await __runMigrations();
41
+ initialized = true;
42
+ }
43
+ catch (error) {
44
+ // Log the error clearly before re-throwing
45
+ console.error("=".repeat(60));
46
+ console.error("WORKER INITIALIZATION FAILED");
47
+ console.error("=".repeat(60));
48
+ console.error("Error:", error instanceof Error ? error.message : String(error));
49
+ if (error instanceof Error && error.stack) {
50
+ console.error("Stack:", error.stack);
51
+ }
52
+ console.error("=".repeat(60));
53
+ // Store the error so subsequent requests also fail clearly
54
+ initError = error;
55
+ throw error;
56
+ }
57
+ }
58
+ }
59
+ async function handleCronRequest(request, env) {
60
+ await ensureInit(env);
61
+ // Parse cron job name and scheduled time from request body
62
+ const body = (await request.json());
63
+ const { name } = body;
64
+ if (!name) {
65
+ return new Response(JSON.stringify({ success: false, error: "Missing cron job name" }), {
66
+ status: 400,
67
+ headers: { "Content-Type": "application/json" },
68
+ });
69
+ }
70
+ const handlers = __getCronHandlers();
71
+ const job = handlers.get(name);
72
+ if (!job) {
73
+ return new Response(JSON.stringify({ success: false, error: "Cron job not found: " + name }), {
74
+ status: 404,
75
+ headers: { "Content-Type": "application/json" },
76
+ });
77
+ }
78
+ try {
79
+ console.log("Running cron job " + name);
80
+ const result = await job.handler();
81
+ return new Response(JSON.stringify({
82
+ success: true,
83
+ result: result !== undefined ? result : null,
84
+ }), {
85
+ headers: { "Content-Type": "application/json" },
86
+ });
87
+ }
88
+ catch (error) {
89
+ const errorMessage = error instanceof Error ? error.message : String(error);
90
+ console.error("[cron:" + name + "] Error:", error);
91
+ return new Response(JSON.stringify({
92
+ success: false,
93
+ error: errorMessage,
94
+ }), {
95
+ status: 500,
96
+ headers: { "Content-Type": "application/json" },
97
+ });
98
+ }
99
+ }
100
+ return {
101
+ async fetch(request, env, ctx) {
102
+ const url = new URL(request.url);
103
+ // Handle internal cron requests
104
+ if (url.pathname === "/__cron" && request.method === "POST") {
105
+ return handleCronRequest(request, env);
106
+ }
107
+ // Handle plugin events (forwarded from plugin workers via internal paths)
108
+ const match = url.pathname.match(pluginPathPattern);
109
+ if (match?.[1] && request.method === "POST") {
110
+ const handler = pluginHandlers[match[1]];
111
+ if (handler) {
112
+ await ensureInit(env);
113
+ return handler(request);
114
+ }
115
+ }
116
+ await ensureInit(env);
117
+ return __getApp().fetch(request, env, ctx);
118
+ },
119
+ };
120
+ }
121
+ //# sourceMappingURL=entry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entry.js","sourceRoot":"","sources":["../../src/worker-runtime/entry.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flingit",
3
- "version": "0.0.30",
3
+ "version": "0.0.31",
4
4
  "description": "Personal Software Platform - Build and deploy personal tools through conversation",
5
5
  "type": "module",
6
6
  "engines": {
@@ -38,6 +38,7 @@
38
38
  "files": [
39
39
  "dist",
40
40
  "!dist/cli-admin",
41
+ "!dist/cli-infra",
41
42
  "templates"
42
43
  ],
43
44
  "repository": {
@@ -51,6 +52,7 @@
51
52
  "start": "npm run cli --",
52
53
  "cli": "npm run build && node dist/cli/index.js",
53
54
  "cli-admin": "npm run build && node dist/cli-admin/index.js",
55
+ "cli-infra": "npm run build && node dist/cli-infra/index.js",
54
56
  "typecheck": "tsc --noEmit",
55
57
  "lint": "eslint src/ platform/",
56
58
  "lint:fix": "eslint src/ platform/ --fix",
@@ -1 +1 @@
1
- 22899e72887b1287e26b8e8d78f0a6e2
1
+ 339299253f11e387255fd5be8d99e37d
@@ -314,3 +314,18 @@ npm exec fling plugin remove discord # Disconnect, release all servers
314
314
  3. **One project per server** — A Discord server can only be claimed by one Fling project at a time.
315
315
 
316
316
  4. **Plugin must be installed first** — Run `fling plugin install discord` before using any Discord features. Check with `fling plugin permissions discord`.
317
+
318
+ 5. **Rate limit: 60 things/hour per project** — `reply`, `followup`, `sendMessage`, `editMessage`, and `addReaction` all count as "things". When exceeded, methods throw an error containing `PLUGIN_RATE_LIMIT_EXCEEDED`.
319
+
320
+ ```typescript
321
+ try {
322
+ await discord.sendMessage({ channelId, content: "Update" });
323
+ } catch (error) {
324
+ const message = error instanceof Error ? error.message : String(error);
325
+ if (message.includes("PLUGIN_RATE_LIMIT_EXCEEDED")) {
326
+ // Back off and retry in the next window.
327
+ return;
328
+ }
329
+ throw error;
330
+ }
331
+ ```
@@ -150,6 +150,7 @@ npm exec fling project slug:set <new-slug> # Change project slug (affects URL)
150
150
  npm exec fling cron list # List registered cron jobs
151
151
  npm exec fling cron history <name> # View invocation history
152
152
  npm exec fling cron trigger <name> # Manually trigger a cron job
153
+ npm exec fling cron trigger <name> --port 4000 # If dev API uses custom port
153
154
  npm exec fling storage list # List storage objects
154
155
  npm exec fling storage put <key> <file> # Upload file to storage
155
156
  npm exec fling storage get <key> [output] # Download object (stdout if no output)
@@ -189,6 +190,7 @@ npm exec fling -- --prod secret list # Deployed secrets
189
190
  npm exec fling -- --prod logs # Deployed logs
190
191
  npm exec fling -- --prod db sql "SELECT 1" # Deployed D1
191
192
  npm exec fling -- --prod storage list # R2 storage
193
+ npm exec fling -- --prod cron list # Deployed cron jobs
192
194
  ```
193
195
 
194
196
  **Note:** Production logs have a delay of ~10 seconds or more before they appear.
@@ -212,3 +212,18 @@ npm exec fling plugin remove slack # Disconnect, release all workspaces
212
212
  3. **One project per workspace** — A Slack workspace can only be claimed by one Fling project at a time.
213
213
 
214
214
  4. **Plugin must be installed first** — Run `fling plugin install slack` before using any Slack features. Check with `fling plugin permissions slack`.
215
+
216
+ 5. **Rate limit: 60 things/hour per project** — `sendMessage`, `editMessage`, `addReaction`, and thread replies all count as "things". When exceeded, methods throw an error containing `PLUGIN_RATE_LIMIT_EXCEEDED`.
217
+
218
+ ```typescript
219
+ try {
220
+ await slack.sendMessage({ channelId, text: "Update" });
221
+ } catch (error) {
222
+ const message = error instanceof Error ? error.message : String(error);
223
+ if (message.includes("PLUGIN_RATE_LIMIT_EXCEEDED")) {
224
+ // Back off and retry in the next window.
225
+ return;
226
+ }
227
+ throw error;
228
+ }
229
+ ```
@@ -3,19 +3,22 @@ import tailwindcss from "@tailwindcss/vite";
3
3
  import react from "@vitejs/plugin-react";
4
4
 
5
5
  export default defineConfig({
6
- base: process.env["VITE_BASE"] || "/",
7
- plugins: [tailwindcss(), react()],
8
- build: {
9
- outDir: "dist/client",
10
- emptyOutDir: true,
11
- },
12
- server: {
13
- port: 5173,
14
- proxy: {
15
- "/api": {
16
- target: "http://localhost:3210",
17
- changeOrigin: true,
18
- },
6
+ base: process.env["VITE_BASE"] || "/",
7
+ plugins: [tailwindcss(), react()],
8
+ build: {
9
+ outDir: "dist/client",
10
+ emptyOutDir: true,
11
+ },
12
+ server: {
13
+ port: 5173,
14
+ watch: {
15
+ ignored: ["**/.fling/**"],
16
+ },
17
+ proxy: {
18
+ "/api": {
19
+ target: "http://localhost:3210",
20
+ changeOrigin: true,
21
+ },
22
+ },
19
23
  },
20
- },
21
24
  });