flingit 0.0.1
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/README.md +84 -0
- package/dist/cli/commands/db.d.ts +9 -0
- package/dist/cli/commands/db.d.ts.map +1 -0
- package/dist/cli/commands/db.js +215 -0
- package/dist/cli/commands/db.js.map +1 -0
- package/dist/cli/commands/dev.d.ts +6 -0
- package/dist/cli/commands/dev.d.ts.map +1 -0
- package/dist/cli/commands/dev.js +145 -0
- package/dist/cli/commands/dev.js.map +1 -0
- package/dist/cli/commands/feedback.d.ts +6 -0
- package/dist/cli/commands/feedback.d.ts.map +1 -0
- package/dist/cli/commands/feedback.js +116 -0
- package/dist/cli/commands/feedback.js.map +1 -0
- package/dist/cli/commands/init.d.ts +6 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +161 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/launch.d.ts +12 -0
- package/dist/cli/commands/launch.d.ts.map +1 -0
- package/dist/cli/commands/launch.js +176 -0
- package/dist/cli/commands/launch.js.map +1 -0
- package/dist/cli/commands/login.d.ts +6 -0
- package/dist/cli/commands/login.d.ts.map +1 -0
- package/dist/cli/commands/login.js +90 -0
- package/dist/cli/commands/login.js.map +1 -0
- package/dist/cli/commands/logout.d.ts +6 -0
- package/dist/cli/commands/logout.d.ts.map +1 -0
- package/dist/cli/commands/logout.js +32 -0
- package/dist/cli/commands/logout.js.map +1 -0
- package/dist/cli/commands/logs.d.ts +12 -0
- package/dist/cli/commands/logs.d.ts.map +1 -0
- package/dist/cli/commands/logs.js +261 -0
- package/dist/cli/commands/logs.js.map +1 -0
- package/dist/cli/commands/onboard.d.ts +22 -0
- package/dist/cli/commands/onboard.d.ts.map +1 -0
- package/dist/cli/commands/onboard.js +244 -0
- package/dist/cli/commands/onboard.js.map +1 -0
- package/dist/cli/commands/project.d.ts +6 -0
- package/dist/cli/commands/project.d.ts.map +1 -0
- package/dist/cli/commands/project.js +142 -0
- package/dist/cli/commands/project.js.map +1 -0
- package/dist/cli/commands/push.d.ts +6 -0
- package/dist/cli/commands/push.d.ts.map +1 -0
- package/dist/cli/commands/push.js +351 -0
- package/dist/cli/commands/push.js.map +1 -0
- package/dist/cli/commands/register.d.ts +6 -0
- package/dist/cli/commands/register.d.ts.map +1 -0
- package/dist/cli/commands/register.js +115 -0
- package/dist/cli/commands/register.js.map +1 -0
- package/dist/cli/commands/secret.d.ts +11 -0
- package/dist/cli/commands/secret.d.ts.map +1 -0
- package/dist/cli/commands/secret.js +124 -0
- package/dist/cli/commands/secret.js.map +1 -0
- package/dist/cli/commands/whoami.d.ts +6 -0
- package/dist/cli/commands/whoami.d.ts.map +1 -0
- package/dist/cli/commands/whoami.js +54 -0
- package/dist/cli/commands/whoami.js.map +1 -0
- package/dist/cli/deploy/assets.d.ts +73 -0
- package/dist/cli/deploy/assets.d.ts.map +1 -0
- package/dist/cli/deploy/assets.js +167 -0
- package/dist/cli/deploy/assets.js.map +1 -0
- package/dist/cli/deploy/base64-stream.d.ts +16 -0
- package/dist/cli/deploy/base64-stream.d.ts.map +1 -0
- package/dist/cli/deploy/base64-stream.js +44 -0
- package/dist/cli/deploy/base64-stream.js.map +1 -0
- package/dist/cli/deploy/bucket-stream.d.ts +18 -0
- package/dist/cli/deploy/bucket-stream.d.ts.map +1 -0
- package/dist/cli/deploy/bucket-stream.js +63 -0
- package/dist/cli/deploy/bucket-stream.js.map +1 -0
- package/dist/cli/deploy/bundler.d.ts +22 -0
- package/dist/cli/deploy/bundler.d.ts.map +1 -0
- package/dist/cli/deploy/bundler.js +131 -0
- package/dist/cli/deploy/bundler.js.map +1 -0
- package/dist/cli/deploy/worker-entry.d.ts +14 -0
- package/dist/cli/deploy/worker-entry.d.ts.map +1 -0
- package/dist/cli/deploy/worker-entry.js +60 -0
- package/dist/cli/deploy/worker-entry.js.map +1 -0
- package/dist/cli/deploy/wrangler-config.d.ts +20 -0
- package/dist/cli/deploy/wrangler-config.d.ts.map +1 -0
- package/dist/cli/deploy/wrangler-config.js +54 -0
- package/dist/cli/deploy/wrangler-config.js.map +1 -0
- package/dist/cli/index.d.ts +10 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +72 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/utils/config.d.ts +39 -0
- package/dist/cli/utils/config.d.ts.map +1 -0
- package/dist/cli/utils/config.js +105 -0
- package/dist/cli/utils/config.js.map +1 -0
- package/dist/cli/utils/duration.d.ts +21 -0
- package/dist/cli/utils/duration.d.ts.map +1 -0
- package/dist/cli/utils/duration.js +44 -0
- package/dist/cli/utils/duration.js.map +1 -0
- package/dist/cli/utils/environment.d.ts +17 -0
- package/dist/cli/utils/environment.d.ts.map +1 -0
- package/dist/cli/utils/environment.js +27 -0
- package/dist/cli/utils/environment.js.map +1 -0
- package/dist/cli/utils/project.d.ts +24 -0
- package/dist/cli/utils/project.d.ts.map +1 -0
- package/dist/cli/utils/project.js +47 -0
- package/dist/cli/utils/project.js.map +1 -0
- package/dist/cli/utils/registry.d.ts +34 -0
- package/dist/cli/utils/registry.d.ts.map +1 -0
- package/dist/cli/utils/registry.js +94 -0
- package/dist/cli/utils/registry.js.map +1 -0
- package/dist/cli/utils/token.d.ts +12 -0
- package/dist/cli/utils/token.d.ts.map +1 -0
- package/dist/cli/utils/token.js +27 -0
- package/dist/cli/utils/token.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/runtime/cron.d.ts +50 -0
- package/dist/runtime/cron.d.ts.map +1 -0
- package/dist/runtime/cron.js +80 -0
- package/dist/runtime/cron.js.map +1 -0
- package/dist/runtime/db.d.ts +93 -0
- package/dist/runtime/db.d.ts.map +1 -0
- package/dist/runtime/db.js +137 -0
- package/dist/runtime/db.js.map +1 -0
- package/dist/runtime/http.d.ts +33 -0
- package/dist/runtime/http.d.ts.map +1 -0
- package/dist/runtime/http.js +36 -0
- package/dist/runtime/http.js.map +1 -0
- package/dist/runtime/log.d.ts +90 -0
- package/dist/runtime/log.d.ts.map +1 -0
- package/dist/runtime/log.js +211 -0
- package/dist/runtime/log.js.map +1 -0
- package/dist/runtime/migrate.d.ts +54 -0
- package/dist/runtime/migrate.d.ts.map +1 -0
- package/dist/runtime/migrate.js +130 -0
- package/dist/runtime/migrate.js.map +1 -0
- package/dist/runtime/secrets.d.ts +36 -0
- package/dist/runtime/secrets.d.ts.map +1 -0
- package/dist/runtime/secrets.js +75 -0
- package/dist/runtime/secrets.js.map +1 -0
- package/dist/worker-runtime/index.d.ts +79 -0
- package/dist/worker-runtime/index.d.ts.map +1 -0
- package/dist/worker-runtime/index.js +203 -0
- package/dist/worker-runtime/index.js.map +1 -0
- package/package.json +81 -0
- package/templates/default/.nvmrc +1 -0
- package/templates/default/CLAUDE.md +197 -0
- package/templates/default/index.html +13 -0
- package/templates/default/package.json +25 -0
- package/templates/default/public/vite.svg +1 -0
- package/templates/default/skills/fling/API.md +335 -0
- package/templates/default/skills/fling/EXAMPLES.md +204 -0
- package/templates/default/skills/fling/FEEDBACK.md +73 -0
- package/templates/default/skills/fling/SKILL.md +159 -0
- package/templates/default/src/react-app/App.css +34 -0
- package/templates/default/src/react-app/App.tsx +27 -0
- package/templates/default/src/react-app/index.css +15 -0
- package/templates/default/src/react-app/main.tsx +10 -0
- package/templates/default/src/react-app/vite-env.d.ts +1 -0
- package/templates/default/src/worker/index.ts +27 -0
- package/templates/default/tsconfig.app.json +22 -0
- package/templates/default/tsconfig.json +7 -0
- package/templates/default/tsconfig.worker.json +11 -0
- package/templates/default/vite.config.ts +21 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database primitive using SQLite
|
|
3
|
+
*
|
|
4
|
+
* The database API matches Cloudflare D1 for portability.
|
|
5
|
+
* Locally, this runs against SQLite via better-sqlite3.
|
|
6
|
+
* In production, it runs against Cloudflare D1.
|
|
7
|
+
*/
|
|
8
|
+
import Database from "better-sqlite3";
|
|
9
|
+
import { existsSync, mkdirSync } from "node:fs";
|
|
10
|
+
import { dirname, join } from "node:path";
|
|
11
|
+
// Database path - configurable via environment
|
|
12
|
+
const DB_PATH = process.env["FLING_DB_PATH"] ?? join(process.cwd(), ".fling", "data", "local.db");
|
|
13
|
+
let database = null;
|
|
14
|
+
function getDatabase() {
|
|
15
|
+
if (!database) {
|
|
16
|
+
// Ensure directory exists
|
|
17
|
+
const dir = dirname(DB_PATH);
|
|
18
|
+
if (!existsSync(dir)) {
|
|
19
|
+
mkdirSync(dir, { recursive: true });
|
|
20
|
+
}
|
|
21
|
+
database = new Database(DB_PATH);
|
|
22
|
+
database.pragma("journal_mode = WAL");
|
|
23
|
+
}
|
|
24
|
+
return database;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* D1-compatible prepared statement wrapper
|
|
28
|
+
*/
|
|
29
|
+
class PreparedStatement {
|
|
30
|
+
sql;
|
|
31
|
+
params = [];
|
|
32
|
+
constructor(sql) {
|
|
33
|
+
this.sql = sql;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Bind parameters to the statement
|
|
37
|
+
*/
|
|
38
|
+
bind(...params) {
|
|
39
|
+
this.params = params;
|
|
40
|
+
return this;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Execute and return the first row
|
|
44
|
+
*/
|
|
45
|
+
first() {
|
|
46
|
+
const db = getDatabase();
|
|
47
|
+
const stmt = db.prepare(this.sql);
|
|
48
|
+
return (stmt.get(...this.params) ?? null);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Execute and return all rows
|
|
52
|
+
*/
|
|
53
|
+
all() {
|
|
54
|
+
const db = getDatabase();
|
|
55
|
+
const stmt = db.prepare(this.sql);
|
|
56
|
+
const results = stmt.all(...this.params);
|
|
57
|
+
return { results };
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Execute a statement (INSERT/UPDATE/DELETE)
|
|
61
|
+
*/
|
|
62
|
+
run() {
|
|
63
|
+
const db = getDatabase();
|
|
64
|
+
const stmt = db.prepare(this.sql);
|
|
65
|
+
const result = stmt.run(...this.params);
|
|
66
|
+
return {
|
|
67
|
+
success: true,
|
|
68
|
+
meta: {
|
|
69
|
+
changes: result.changes,
|
|
70
|
+
last_row_id: Number(result.lastInsertRowid),
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* D1-compatible database interface
|
|
77
|
+
*/
|
|
78
|
+
export const db = {
|
|
79
|
+
/**
|
|
80
|
+
* Prepare a SQL statement with parameter binding
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```typescript
|
|
84
|
+
* const episode = await db.prepare("SELECT * FROM episodes WHERE id = ?")
|
|
85
|
+
* .bind(episodeId)
|
|
86
|
+
* .first();
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
prepare(sql) {
|
|
90
|
+
return new PreparedStatement(sql);
|
|
91
|
+
},
|
|
92
|
+
/**
|
|
93
|
+
* Execute raw SQL (for DDL statements like CREATE TABLE)
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* ```typescript
|
|
97
|
+
* await db.exec(`
|
|
98
|
+
* CREATE TABLE IF NOT EXISTS episodes (
|
|
99
|
+
* id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
100
|
+
* title TEXT NOT NULL
|
|
101
|
+
* )
|
|
102
|
+
* `);
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
exec(sql) {
|
|
106
|
+
const db = getDatabase();
|
|
107
|
+
db.exec(sql);
|
|
108
|
+
},
|
|
109
|
+
/**
|
|
110
|
+
* Execute multiple statements atomically
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* ```typescript
|
|
114
|
+
* await db.batch([
|
|
115
|
+
* db.prepare("INSERT INTO users (id, name) VALUES (?, ?)").bind(id, name),
|
|
116
|
+
* db.prepare("INSERT INTO projects (id, user_id) VALUES (?, ?)").bind(projId, id),
|
|
117
|
+
* ]);
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
batch(statements) {
|
|
121
|
+
const database = getDatabase();
|
|
122
|
+
const transaction = database.transaction(() => {
|
|
123
|
+
return statements.map((stmt) => stmt.run());
|
|
124
|
+
});
|
|
125
|
+
return transaction();
|
|
126
|
+
},
|
|
127
|
+
/**
|
|
128
|
+
* Close the database connection (internal use)
|
|
129
|
+
*/
|
|
130
|
+
close() {
|
|
131
|
+
if (database) {
|
|
132
|
+
database.close();
|
|
133
|
+
database = null;
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
//# sourceMappingURL=db.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/runtime/db.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP primitive using Hono
|
|
3
|
+
*
|
|
4
|
+
* Fling uses Hono for HTTP. This module exports a configured Hono app
|
|
5
|
+
* that works identically in local development and production deployment.
|
|
6
|
+
*/
|
|
7
|
+
import { Hono } from "hono";
|
|
8
|
+
type Variables = {
|
|
9
|
+
requestId: string;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* The main Hono app instance.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* import { app } from "fling";
|
|
17
|
+
*
|
|
18
|
+
* app.get("/", (c) => {
|
|
19
|
+
* return c.text("Hello from Fling!");
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* app.get("/feed.xml", async (c) => {
|
|
23
|
+
* const episodes = await db.prepare("SELECT * FROM episodes").all();
|
|
24
|
+
* const xml = buildRssFeed(episodes);
|
|
25
|
+
* return c.text(xml, 200, { "Content-Type": "application/rss+xml" });
|
|
26
|
+
* });
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export declare const app: Hono<{
|
|
30
|
+
Variables: Variables;
|
|
31
|
+
}, import("hono/types").BlankSchema, "/">;
|
|
32
|
+
export {};
|
|
33
|
+
//# sourceMappingURL=http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/runtime/http.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAK5B,KAAK,SAAS,GAAG;IACf,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,GAAG;eAAyB,SAAS;yCAAK,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP primitive using Hono
|
|
3
|
+
*
|
|
4
|
+
* Fling uses Hono for HTTP. This module exports a configured Hono app
|
|
5
|
+
* that works identically in local development and production deployment.
|
|
6
|
+
*/
|
|
7
|
+
import { Hono } from "hono";
|
|
8
|
+
import { randomUUID } from "node:crypto";
|
|
9
|
+
import { withLogContext } from "./log.js";
|
|
10
|
+
/**
|
|
11
|
+
* The main Hono app instance.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* import { app } from "fling";
|
|
16
|
+
*
|
|
17
|
+
* app.get("/", (c) => {
|
|
18
|
+
* return c.text("Hello from Fling!");
|
|
19
|
+
* });
|
|
20
|
+
*
|
|
21
|
+
* app.get("/feed.xml", async (c) => {
|
|
22
|
+
* const episodes = await db.prepare("SELECT * FROM episodes").all();
|
|
23
|
+
* const xml = buildRssFeed(episodes);
|
|
24
|
+
* return c.text(xml, 200, { "Content-Type": "application/rss+xml" });
|
|
25
|
+
* });
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export const app = new Hono();
|
|
29
|
+
// Add request ID middleware for log context
|
|
30
|
+
app.use("*", async (c, next) => {
|
|
31
|
+
const requestId = randomUUID();
|
|
32
|
+
c.set("requestId", requestId);
|
|
33
|
+
// Wrap handler execution with log context
|
|
34
|
+
return withLogContext({ requestId }, () => next());
|
|
35
|
+
});
|
|
36
|
+
//# sourceMappingURL=http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/runtime/http.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAO1C;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,GAAG,GAAG,IAAI,IAAI,EAA4B,CAAC;AAExD,4CAA4C;AAC5C,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;IAC7B,MAAM,SAAS,GAAG,UAAU,EAAE,CAAC;IAC/B,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IAE9B,0CAA0C;IAC1C,OAAO,cAAc,CAAC,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,CAAkB,CAAC;AACtE,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logging primitive with structured output and persistent storage
|
|
3
|
+
*
|
|
4
|
+
* Logs are structured (JSON) and include automatic context
|
|
5
|
+
* (timestamp, request ID for HTTP handlers, cron job name).
|
|
6
|
+
* Logs are stored in SQLite for querying via `fling logs`.
|
|
7
|
+
*/
|
|
8
|
+
export type LogLevel = "debug" | "info" | "warn" | "error";
|
|
9
|
+
interface LogContext {
|
|
10
|
+
requestId?: string;
|
|
11
|
+
cronJob?: string;
|
|
12
|
+
[key: string]: unknown;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Structured logging interface
|
|
16
|
+
*/
|
|
17
|
+
export declare const log: {
|
|
18
|
+
/**
|
|
19
|
+
* Log a debug message
|
|
20
|
+
*/
|
|
21
|
+
debug(message: string, data?: Record<string, unknown>): void;
|
|
22
|
+
/**
|
|
23
|
+
* Log an info message
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* log.info("Processing episode", { title, date });
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
info(message: string, data?: Record<string, unknown>): void;
|
|
31
|
+
/**
|
|
32
|
+
* Log a warning message
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* log.warn("Rate limit approaching", { remaining: 10 });
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
warn(message: string, data?: Record<string, unknown>): void;
|
|
40
|
+
/**
|
|
41
|
+
* Log an error message
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```typescript
|
|
45
|
+
* log.error("Failed to fetch feed", { url, error: e.message });
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
error(message: string, data?: Record<string, unknown>): void;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Run a function with logging context (internal use)
|
|
52
|
+
*/
|
|
53
|
+
export declare function withLogContext<T>(context: LogContext, fn: () => T | Promise<T>): T | Promise<T>;
|
|
54
|
+
/**
|
|
55
|
+
* Query options for retrieving stored logs
|
|
56
|
+
*/
|
|
57
|
+
export interface LogQueryOptions {
|
|
58
|
+
level?: LogLevel;
|
|
59
|
+
since?: Date;
|
|
60
|
+
cronJob?: string;
|
|
61
|
+
requestId?: string;
|
|
62
|
+
limit?: number;
|
|
63
|
+
offset?: number;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* A stored log entry
|
|
67
|
+
*/
|
|
68
|
+
export interface StoredLogEntry {
|
|
69
|
+
id: number;
|
|
70
|
+
timestamp: string;
|
|
71
|
+
level: LogLevel;
|
|
72
|
+
message: string;
|
|
73
|
+
requestId: string | null;
|
|
74
|
+
cronJob: string | null;
|
|
75
|
+
data: Record<string, unknown> | null;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Query stored logs with optional filters
|
|
79
|
+
*/
|
|
80
|
+
export declare function queryLogs(options?: LogQueryOptions): StoredLogEntry[];
|
|
81
|
+
/**
|
|
82
|
+
* Close the log database connection (call on shutdown)
|
|
83
|
+
*/
|
|
84
|
+
export declare function closeLogDatabase(): void;
|
|
85
|
+
/**
|
|
86
|
+
* Clear all stored logs (for testing)
|
|
87
|
+
*/
|
|
88
|
+
export declare function clearLogs(): void;
|
|
89
|
+
export {};
|
|
90
|
+
//# sourceMappingURL=log.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../../src/runtime/log.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAE3D,UAAU,UAAU;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAsHD;;GAEG;AACH,eAAO,MAAM,GAAG;IACd;;OAEG;mBACY,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAK5D;;;;;;;OAOG;kBACW,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAK3D;;;;;;;OAOG;kBACW,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAK3D;;;;;;;OAOG;mBACY,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;CAI7D,CAAC;AAEF;;GAEG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAC9B,OAAO,EAAE,UAAU,EACnB,EAAE,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GACvB,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAEhB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,KAAK,CAAC,EAAE,IAAI,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,QAAQ,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CACtC;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,GAAE,eAAoB,GAAG,cAAc,EAAE,CAsDzE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAKvC;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI,IAAI,CAGhC"}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logging primitive with structured output and persistent storage
|
|
3
|
+
*
|
|
4
|
+
* Logs are structured (JSON) and include automatic context
|
|
5
|
+
* (timestamp, request ID for HTTP handlers, cron job name).
|
|
6
|
+
* Logs are stored in SQLite for querying via `fling logs`.
|
|
7
|
+
*/
|
|
8
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
9
|
+
import Database from "better-sqlite3";
|
|
10
|
+
import { existsSync, mkdirSync } from "node:fs";
|
|
11
|
+
import { dirname, join } from "node:path";
|
|
12
|
+
// Configuration
|
|
13
|
+
const LOG_DB_PATH = process.env["FLING_DB_PATH"] ?? join(process.cwd(), ".fling", "data", "local.db");
|
|
14
|
+
const MAX_LOG_ENTRIES = parseInt(process.env["FLING_LOG_MAX_ENTRIES"] ?? "10000", 10);
|
|
15
|
+
// AsyncLocalStorage for request/cron context
|
|
16
|
+
const contextStorage = new AsyncLocalStorage();
|
|
17
|
+
// Database connection for log storage
|
|
18
|
+
let logDb = null;
|
|
19
|
+
let writeCount = 0;
|
|
20
|
+
function getLogDatabase() {
|
|
21
|
+
if (!logDb) {
|
|
22
|
+
const dir = dirname(LOG_DB_PATH);
|
|
23
|
+
if (!existsSync(dir)) {
|
|
24
|
+
mkdirSync(dir, { recursive: true });
|
|
25
|
+
}
|
|
26
|
+
logDb = new Database(LOG_DB_PATH);
|
|
27
|
+
logDb.pragma("journal_mode = WAL");
|
|
28
|
+
// Create logs table
|
|
29
|
+
logDb.exec(`
|
|
30
|
+
CREATE TABLE IF NOT EXISTS _fling_logs (
|
|
31
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
32
|
+
timestamp TEXT NOT NULL,
|
|
33
|
+
level TEXT NOT NULL,
|
|
34
|
+
message TEXT NOT NULL,
|
|
35
|
+
request_id TEXT,
|
|
36
|
+
cron_job TEXT,
|
|
37
|
+
data TEXT,
|
|
38
|
+
created_at INTEGER DEFAULT (unixepoch())
|
|
39
|
+
)
|
|
40
|
+
`);
|
|
41
|
+
// Create indexes for common queries
|
|
42
|
+
logDb.exec(`
|
|
43
|
+
CREATE INDEX IF NOT EXISTS idx_logs_timestamp ON _fling_logs(timestamp DESC);
|
|
44
|
+
CREATE INDEX IF NOT EXISTS idx_logs_level ON _fling_logs(level);
|
|
45
|
+
CREATE INDEX IF NOT EXISTS idx_logs_cron_job ON _fling_logs(cron_job);
|
|
46
|
+
CREATE INDEX IF NOT EXISTS idx_logs_created_at ON _fling_logs(created_at);
|
|
47
|
+
`);
|
|
48
|
+
}
|
|
49
|
+
return logDb;
|
|
50
|
+
}
|
|
51
|
+
function storeLog(level, message, data) {
|
|
52
|
+
try {
|
|
53
|
+
const context = contextStorage.getStore() ?? {};
|
|
54
|
+
const db = getLogDatabase();
|
|
55
|
+
const stmt = db.prepare(`
|
|
56
|
+
INSERT INTO _fling_logs (timestamp, level, message, request_id, cron_job, data)
|
|
57
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
58
|
+
`);
|
|
59
|
+
stmt.run(new Date().toISOString(), level, message, context.requestId ?? null, context.cronJob ?? null, data ? JSON.stringify(data) : null);
|
|
60
|
+
// Periodic cleanup
|
|
61
|
+
writeCount++;
|
|
62
|
+
if (writeCount >= 100) {
|
|
63
|
+
writeCount = 0;
|
|
64
|
+
cleanupOldLogs();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
// Silently ignore storage errors to not break logging
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function cleanupOldLogs() {
|
|
72
|
+
try {
|
|
73
|
+
const db = getLogDatabase();
|
|
74
|
+
db.exec(`
|
|
75
|
+
DELETE FROM _fling_logs
|
|
76
|
+
WHERE id NOT IN (
|
|
77
|
+
SELECT id FROM _fling_logs
|
|
78
|
+
ORDER BY created_at DESC
|
|
79
|
+
LIMIT ${MAX_LOG_ENTRIES}
|
|
80
|
+
)
|
|
81
|
+
`);
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
// Silently ignore cleanup errors
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
function formatLog(level, message, data) {
|
|
88
|
+
const context = contextStorage.getStore() ?? {};
|
|
89
|
+
const logEntry = {
|
|
90
|
+
timestamp: new Date().toISOString(),
|
|
91
|
+
level,
|
|
92
|
+
message,
|
|
93
|
+
...context,
|
|
94
|
+
...data,
|
|
95
|
+
};
|
|
96
|
+
return JSON.stringify(logEntry);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Structured logging interface
|
|
100
|
+
*/
|
|
101
|
+
export const log = {
|
|
102
|
+
/**
|
|
103
|
+
* Log a debug message
|
|
104
|
+
*/
|
|
105
|
+
debug(message, data) {
|
|
106
|
+
console.debug(formatLog("debug", message, data));
|
|
107
|
+
storeLog("debug", message, data);
|
|
108
|
+
},
|
|
109
|
+
/**
|
|
110
|
+
* Log an info message
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* ```typescript
|
|
114
|
+
* log.info("Processing episode", { title, date });
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
info(message, data) {
|
|
118
|
+
console.info(formatLog("info", message, data));
|
|
119
|
+
storeLog("info", message, data);
|
|
120
|
+
},
|
|
121
|
+
/**
|
|
122
|
+
* Log a warning message
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* ```typescript
|
|
126
|
+
* log.warn("Rate limit approaching", { remaining: 10 });
|
|
127
|
+
* ```
|
|
128
|
+
*/
|
|
129
|
+
warn(message, data) {
|
|
130
|
+
console.warn(formatLog("warn", message, data));
|
|
131
|
+
storeLog("warn", message, data);
|
|
132
|
+
},
|
|
133
|
+
/**
|
|
134
|
+
* Log an error message
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* ```typescript
|
|
138
|
+
* log.error("Failed to fetch feed", { url, error: e.message });
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
error(message, data) {
|
|
142
|
+
console.error(formatLog("error", message, data));
|
|
143
|
+
storeLog("error", message, data);
|
|
144
|
+
},
|
|
145
|
+
};
|
|
146
|
+
/**
|
|
147
|
+
* Run a function with logging context (internal use)
|
|
148
|
+
*/
|
|
149
|
+
export function withLogContext(context, fn) {
|
|
150
|
+
return contextStorage.run(context, fn);
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Query stored logs with optional filters
|
|
154
|
+
*/
|
|
155
|
+
export function queryLogs(options = {}) {
|
|
156
|
+
const db = getLogDatabase();
|
|
157
|
+
const conditions = [];
|
|
158
|
+
const params = [];
|
|
159
|
+
if (options.level) {
|
|
160
|
+
conditions.push("level = ?");
|
|
161
|
+
params.push(options.level);
|
|
162
|
+
}
|
|
163
|
+
if (options.since) {
|
|
164
|
+
conditions.push("timestamp >= ?");
|
|
165
|
+
params.push(options.since.toISOString());
|
|
166
|
+
}
|
|
167
|
+
if (options.cronJob) {
|
|
168
|
+
conditions.push("cron_job = ?");
|
|
169
|
+
params.push(options.cronJob);
|
|
170
|
+
}
|
|
171
|
+
if (options.requestId) {
|
|
172
|
+
conditions.push("request_id = ?");
|
|
173
|
+
params.push(options.requestId);
|
|
174
|
+
}
|
|
175
|
+
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
176
|
+
const limit = options.limit ?? 100;
|
|
177
|
+
const offset = options.offset ?? 0;
|
|
178
|
+
const query = `
|
|
179
|
+
SELECT * FROM _fling_logs
|
|
180
|
+
${whereClause}
|
|
181
|
+
ORDER BY timestamp DESC
|
|
182
|
+
LIMIT ? OFFSET ?
|
|
183
|
+
`;
|
|
184
|
+
const rows = db.prepare(query).all(...params, limit, offset);
|
|
185
|
+
return rows.map((row) => ({
|
|
186
|
+
id: row.id,
|
|
187
|
+
timestamp: row.timestamp,
|
|
188
|
+
level: row.level,
|
|
189
|
+
message: row.message,
|
|
190
|
+
requestId: row.request_id,
|
|
191
|
+
cronJob: row.cron_job,
|
|
192
|
+
data: row.data ? JSON.parse(row.data) : null,
|
|
193
|
+
}));
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Close the log database connection (call on shutdown)
|
|
197
|
+
*/
|
|
198
|
+
export function closeLogDatabase() {
|
|
199
|
+
if (logDb) {
|
|
200
|
+
logDb.close();
|
|
201
|
+
logDb = null;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Clear all stored logs (for testing)
|
|
206
|
+
*/
|
|
207
|
+
export function clearLogs() {
|
|
208
|
+
const db = getLogDatabase();
|
|
209
|
+
db.exec("DELETE FROM _fling_logs");
|
|
210
|
+
}
|
|
211
|
+
//# sourceMappingURL=log.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.js","sourceRoot":"","sources":["../../src/runtime/log.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database migrations for Fling
|
|
3
|
+
*
|
|
4
|
+
* Migrations run automatically on app startup. Each migration runs exactly once,
|
|
5
|
+
* tracked in the `_migrations` table. Migrations execute in alphabetical order
|
|
6
|
+
* by name.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* import { migrate, db } from "fling";
|
|
11
|
+
*
|
|
12
|
+
* migrate("001_create_users", async () => {
|
|
13
|
+
* await db.prepare(`
|
|
14
|
+
* CREATE TABLE users (
|
|
15
|
+
* id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
16
|
+
* name TEXT NOT NULL
|
|
17
|
+
* )
|
|
18
|
+
* `).run();
|
|
19
|
+
* });
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
interface Migration {
|
|
23
|
+
name: string;
|
|
24
|
+
handler: () => Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Register a database migration.
|
|
28
|
+
*
|
|
29
|
+
* @param name - Unique identifier for the migration (use numeric prefix for ordering, e.g., "001_create_users")
|
|
30
|
+
* @param handler - Async function that performs the migration
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```typescript
|
|
34
|
+
* migrate("001_create_users", async () => {
|
|
35
|
+
* await db.prepare(`CREATE TABLE users (...)`).run();
|
|
36
|
+
* });
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export declare function migrate(name: string, handler: () => Promise<void>): void;
|
|
40
|
+
/**
|
|
41
|
+
* Run all pending migrations.
|
|
42
|
+
* Called automatically by the Fling runtime on startup.
|
|
43
|
+
*/
|
|
44
|
+
export declare function runMigrations(): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Get all registered migrations (for testing/debugging).
|
|
47
|
+
*/
|
|
48
|
+
export declare function getMigrations(): Map<string, Migration>;
|
|
49
|
+
/**
|
|
50
|
+
* Clear all registered migrations (for testing).
|
|
51
|
+
*/
|
|
52
|
+
export declare function clearMigrations(): void;
|
|
53
|
+
export {};
|
|
54
|
+
//# sourceMappingURL=migrate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/runtime/migrate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAIH,UAAU,SAAS;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAKD;;;;;;;;;;;;GAYG;AACH,wBAAgB,OAAO,CACrB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAC3B,IAAI,CAKN;AAED;;;GAGG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAmFnD;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAEtD;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAEtC"}
|