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,261 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* fling logs - View application logs
|
|
3
|
+
*
|
|
4
|
+
* Query stored logs with filters for level, time range, and cron job.
|
|
5
|
+
* Supports both local SQLite logs and deployed worker logs.
|
|
6
|
+
*
|
|
7
|
+
* Default: local logs
|
|
8
|
+
* With --prod: deployed worker logs (requires login)
|
|
9
|
+
*/
|
|
10
|
+
import { Command } from "commander";
|
|
11
|
+
import Database from "better-sqlite3";
|
|
12
|
+
import { existsSync } from "node:fs";
|
|
13
|
+
import { join } from "node:path";
|
|
14
|
+
import { parseDuration } from "../utils/duration.js";
|
|
15
|
+
import { platformFetch } from "../utils/config.js";
|
|
16
|
+
import { getTargetEnv, requireProdAuth } from "../utils/environment.js";
|
|
17
|
+
const DB_PATH = join(process.cwd(), ".fling", "data", "local.db");
|
|
18
|
+
export const logsCommand = new Command("logs")
|
|
19
|
+
.description("View application logs (local or production)")
|
|
20
|
+
.option("-l, --level <level>", "Filter by log level (debug, info, warn, error)")
|
|
21
|
+
.option("-s, --since <duration>", "Show logs from last duration (e.g., 1h, 30m, 2d)")
|
|
22
|
+
.option("-c, --cron <name>", "Filter logs from specific cron job (local only)")
|
|
23
|
+
.option("-f, --follow", "Follow log output in real-time (local only)")
|
|
24
|
+
.option("-n, --limit <count>", "Number of logs to show", "50")
|
|
25
|
+
.option("--search <text>", "Full-text search in log messages (prod only)")
|
|
26
|
+
.addHelpText("after", `
|
|
27
|
+
Environment:
|
|
28
|
+
By default, shows logs from local SQLite database.
|
|
29
|
+
Use --prod flag to fetch logs from deployed worker.
|
|
30
|
+
|
|
31
|
+
Duration format for --since:
|
|
32
|
+
1h = 1 hour, 30m = 30 minutes, 2d = 2 days
|
|
33
|
+
|
|
34
|
+
Feature availability:
|
|
35
|
+
Local only: --cron (filter by cron job), --follow (real-time)
|
|
36
|
+
Prod only: --search (full-text search)
|
|
37
|
+
|
|
38
|
+
Examples:
|
|
39
|
+
fling logs Last 50 local logs
|
|
40
|
+
fling logs -n 100 Last 100 local logs
|
|
41
|
+
fling logs -l error Only error logs
|
|
42
|
+
fling logs -s 1h Logs from last hour
|
|
43
|
+
fling logs -l warn -s 30m Warnings from last 30 minutes
|
|
44
|
+
fling logs -f Follow local logs in real-time
|
|
45
|
+
fling logs -c daily-cleanup Logs from specific cron job
|
|
46
|
+
fling --prod logs Last 50 production logs
|
|
47
|
+
fling --prod logs --search payment Search for "payment" in prod logs
|
|
48
|
+
fling --prod logs -l error -s 2d Prod errors from last 2 days
|
|
49
|
+
`)
|
|
50
|
+
.action(async (options, command) => {
|
|
51
|
+
const env = getTargetEnv(command);
|
|
52
|
+
// Handle deployed logs mode
|
|
53
|
+
if (env === "prod") {
|
|
54
|
+
requireProdAuth(env);
|
|
55
|
+
await queryDeployedLogs(options);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (!existsSync(DB_PATH)) {
|
|
59
|
+
console.error("No logs found. Database does not exist.");
|
|
60
|
+
console.error("Run 'fling dev' to start the server and generate logs.");
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
const db = new Database(DB_PATH, { readonly: true });
|
|
64
|
+
// Check if logs table exists
|
|
65
|
+
const tableExists = db
|
|
66
|
+
.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='_fling_logs'")
|
|
67
|
+
.get();
|
|
68
|
+
if (!tableExists) {
|
|
69
|
+
console.error("No logs found. The logs table does not exist yet.");
|
|
70
|
+
console.error("Run 'fling dev' to start the server and generate logs.");
|
|
71
|
+
db.close();
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
74
|
+
// Build query
|
|
75
|
+
const conditions = [];
|
|
76
|
+
const params = [];
|
|
77
|
+
if (options.level) {
|
|
78
|
+
const validLevels = ["debug", "info", "warn", "error"];
|
|
79
|
+
if (!validLevels.includes(options.level)) {
|
|
80
|
+
console.error(`Invalid level: ${options.level}. Must be one of: ${validLevels.join(", ")}`);
|
|
81
|
+
process.exit(1);
|
|
82
|
+
}
|
|
83
|
+
conditions.push("level = ?");
|
|
84
|
+
params.push(options.level);
|
|
85
|
+
}
|
|
86
|
+
if (options.since) {
|
|
87
|
+
try {
|
|
88
|
+
const ms = parseDuration(options.since);
|
|
89
|
+
const sinceTime = new Date(Date.now() - ms).toISOString();
|
|
90
|
+
conditions.push("timestamp >= ?");
|
|
91
|
+
params.push(sinceTime);
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
console.error(error.message);
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (options.cron) {
|
|
99
|
+
conditions.push("cron_job = ?");
|
|
100
|
+
params.push(options.cron);
|
|
101
|
+
}
|
|
102
|
+
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
103
|
+
const limit = parseInt(options.limit, 10);
|
|
104
|
+
if (options.follow) {
|
|
105
|
+
// Follow mode: poll for new logs
|
|
106
|
+
let lastId = 0;
|
|
107
|
+
// Initial fetch
|
|
108
|
+
const initialQuery = `
|
|
109
|
+
SELECT * FROM _fling_logs
|
|
110
|
+
${whereClause}
|
|
111
|
+
ORDER BY id DESC
|
|
112
|
+
LIMIT ?
|
|
113
|
+
`;
|
|
114
|
+
const initialLogs = db
|
|
115
|
+
.prepare(initialQuery)
|
|
116
|
+
.all(...params, limit);
|
|
117
|
+
initialLogs.reverse().forEach((log) => {
|
|
118
|
+
printLog(log);
|
|
119
|
+
lastId = Math.max(lastId, log.id);
|
|
120
|
+
});
|
|
121
|
+
// Poll loop
|
|
122
|
+
const pollQuery = `
|
|
123
|
+
SELECT * FROM _fling_logs
|
|
124
|
+
${whereClause ? whereClause + " AND" : "WHERE"} id > ?
|
|
125
|
+
ORDER BY id ASC
|
|
126
|
+
`;
|
|
127
|
+
console.log("\nFollowing logs (Ctrl+C to stop)...\n");
|
|
128
|
+
setInterval(() => {
|
|
129
|
+
const newLogs = db
|
|
130
|
+
.prepare(pollQuery)
|
|
131
|
+
.all(...params, lastId);
|
|
132
|
+
newLogs.forEach((log) => {
|
|
133
|
+
printLog(log);
|
|
134
|
+
lastId = Math.max(lastId, log.id);
|
|
135
|
+
});
|
|
136
|
+
}, 1000);
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
// One-shot mode
|
|
140
|
+
const query = `
|
|
141
|
+
SELECT * FROM _fling_logs
|
|
142
|
+
${whereClause}
|
|
143
|
+
ORDER BY timestamp DESC
|
|
144
|
+
LIMIT ?
|
|
145
|
+
`;
|
|
146
|
+
const logs = db.prepare(query).all(...params, limit);
|
|
147
|
+
if (logs.length === 0) {
|
|
148
|
+
console.log("No logs found matching the criteria.");
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
logs.reverse().forEach(printLog);
|
|
152
|
+
}
|
|
153
|
+
db.close();
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
function printLog(entry) {
|
|
157
|
+
const levelColors = {
|
|
158
|
+
debug: "\x1b[90m", // gray
|
|
159
|
+
info: "\x1b[36m", // cyan
|
|
160
|
+
warn: "\x1b[33m", // yellow
|
|
161
|
+
error: "\x1b[31m", // red
|
|
162
|
+
};
|
|
163
|
+
const reset = "\x1b[0m";
|
|
164
|
+
const dim = "\x1b[90m";
|
|
165
|
+
const magenta = "\x1b[35m";
|
|
166
|
+
const color = levelColors[entry.level] ?? "";
|
|
167
|
+
const levelPadded = entry.level.toUpperCase().padEnd(5);
|
|
168
|
+
let output = `${dim}${entry.timestamp}${reset} ${color}${levelPadded}${reset} ${entry.message}`;
|
|
169
|
+
if (entry.cron_job) {
|
|
170
|
+
output += ` ${magenta}[cron:${entry.cron_job}]${reset}`;
|
|
171
|
+
}
|
|
172
|
+
if (entry.request_id) {
|
|
173
|
+
output += ` ${dim}[req:${entry.request_id.slice(0, 8)}]${reset}`;
|
|
174
|
+
}
|
|
175
|
+
if (entry.data) {
|
|
176
|
+
try {
|
|
177
|
+
const parsed = JSON.parse(entry.data);
|
|
178
|
+
output += ` ${dim}${JSON.stringify(parsed)}${reset}`;
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
output += ` ${entry.data}`;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
console.log(output);
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Query logs from the deployed worker via the platform API.
|
|
188
|
+
* Auth is checked by requireProdAuth before this is called.
|
|
189
|
+
*/
|
|
190
|
+
async function queryDeployedLogs(options) {
|
|
191
|
+
// Build query params
|
|
192
|
+
const params = new URLSearchParams();
|
|
193
|
+
if (options.since) {
|
|
194
|
+
params.set("since", options.since);
|
|
195
|
+
}
|
|
196
|
+
if (options.level) {
|
|
197
|
+
const validLevels = ["debug", "info", "warn", "error"];
|
|
198
|
+
if (!validLevels.includes(options.level)) {
|
|
199
|
+
console.error(`Invalid level: ${options.level}. Must be one of: ${validLevels.join(", ")}`);
|
|
200
|
+
process.exit(1);
|
|
201
|
+
}
|
|
202
|
+
params.set("level", options.level);
|
|
203
|
+
}
|
|
204
|
+
if (options.search) {
|
|
205
|
+
params.set("search", options.search);
|
|
206
|
+
}
|
|
207
|
+
if (options.limit) {
|
|
208
|
+
params.set("limit", options.limit);
|
|
209
|
+
}
|
|
210
|
+
try {
|
|
211
|
+
const queryString = params.toString();
|
|
212
|
+
const path = `/project/default/logs${queryString ? `?${queryString}` : ""}`;
|
|
213
|
+
const response = await platformFetch(path);
|
|
214
|
+
const data = (await response.json());
|
|
215
|
+
if (!response.ok) {
|
|
216
|
+
console.error(`Failed to fetch logs: ${data.error ?? "Unknown error"}`);
|
|
217
|
+
process.exit(1);
|
|
218
|
+
}
|
|
219
|
+
if (data.error) {
|
|
220
|
+
console.error(`Warning: ${data.error}`);
|
|
221
|
+
}
|
|
222
|
+
if (data.logs.length === 0) {
|
|
223
|
+
console.log("No logs found matching the criteria.");
|
|
224
|
+
if (!options.since) {
|
|
225
|
+
console.log("Tip: Logs are retained for 3 days (free) or 7 days (paid).");
|
|
226
|
+
}
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
// Sort logs by timestamp (oldest first) and print
|
|
230
|
+
data.logs
|
|
231
|
+
.sort((a, b) => a.timestamp - b.timestamp)
|
|
232
|
+
.forEach(printDeployedLog);
|
|
233
|
+
}
|
|
234
|
+
catch (error) {
|
|
235
|
+
console.error("Error fetching logs:", error.message);
|
|
236
|
+
process.exit(1);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Print a deployed log entry with colors.
|
|
241
|
+
*/
|
|
242
|
+
function printDeployedLog(entry) {
|
|
243
|
+
const levelColors = {
|
|
244
|
+
debug: "\x1b[90m", // gray
|
|
245
|
+
info: "\x1b[36m", // cyan
|
|
246
|
+
warn: "\x1b[33m", // yellow
|
|
247
|
+
error: "\x1b[31m", // red
|
|
248
|
+
};
|
|
249
|
+
const reset = "\x1b[0m";
|
|
250
|
+
const dim = "\x1b[90m";
|
|
251
|
+
const color = levelColors[entry.level] ?? "";
|
|
252
|
+
const levelPadded = entry.level.toUpperCase().padEnd(5);
|
|
253
|
+
// Format timestamp as ISO string
|
|
254
|
+
const timestamp = new Date(entry.timestamp).toISOString();
|
|
255
|
+
let output = `${dim}${timestamp}${reset} ${color}${levelPadded}${reset} ${entry.message}`;
|
|
256
|
+
if (entry.rayId) {
|
|
257
|
+
output += ` ${dim}[ray:${entry.rayId.slice(0, 8)}]${reset}`;
|
|
258
|
+
}
|
|
259
|
+
console.log(output);
|
|
260
|
+
}
|
|
261
|
+
//# sourceMappingURL=logs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logs.js","sourceRoot":"","sources":["../../../src/cli/commands/logs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* fling onboard - Interactive onboarding for first-time users
|
|
3
|
+
*/
|
|
4
|
+
import { Command } from "commander";
|
|
5
|
+
/**
|
|
6
|
+
* Result from the onboarding flow.
|
|
7
|
+
*/
|
|
8
|
+
export interface OnboardingResult {
|
|
9
|
+
authenticated: boolean;
|
|
10
|
+
setupProject: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Run the interactive onboarding flow.
|
|
14
|
+
*
|
|
15
|
+
* This can be called programmatically (from launch.ts) or via the command.
|
|
16
|
+
* Returns whether the user authenticated and whether to set up the default project.
|
|
17
|
+
*/
|
|
18
|
+
export declare function runOnboarding(options?: {
|
|
19
|
+
apiUrl?: string;
|
|
20
|
+
}): Promise<OnboardingResult>;
|
|
21
|
+
export declare const onboardCommand: Command;
|
|
22
|
+
//# sourceMappingURL=onboard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"onboard.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/onboard.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAcpC;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;CACvB;AA0ID;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,OAAO,CAAC,EAAE;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAuG5B;AAED,eAAO,MAAM,cAAc,SA0BvB,CAAC"}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* fling onboard - Interactive onboarding for first-time users
|
|
3
|
+
*/
|
|
4
|
+
import { Command } from "commander";
|
|
5
|
+
import * as p from "@clack/prompts";
|
|
6
|
+
import { setToken, isLoggedIn, clearToken, platformFetch, getApiUrl, setApiUrl, } from "../utils/config.js";
|
|
7
|
+
import { normalizeInviteToken } from "../utils/token.js";
|
|
8
|
+
/**
|
|
9
|
+
* Handle the API token login flow.
|
|
10
|
+
* Returns true if authentication succeeded, or the symbol if cancelled.
|
|
11
|
+
*/
|
|
12
|
+
async function handleApiTokenFlow() {
|
|
13
|
+
const token = await p.password({
|
|
14
|
+
message: "Paste your token",
|
|
15
|
+
validate: (value) => {
|
|
16
|
+
if (!value)
|
|
17
|
+
return "Token is required";
|
|
18
|
+
if (!value.startsWith("usr_"))
|
|
19
|
+
return "Token must start with 'usr_'";
|
|
20
|
+
return undefined;
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
if (p.isCancel(token))
|
|
24
|
+
return token;
|
|
25
|
+
// Store token temporarily
|
|
26
|
+
setToken(token);
|
|
27
|
+
// Verify token by calling /me
|
|
28
|
+
const s = p.spinner();
|
|
29
|
+
s.start("Verifying token...");
|
|
30
|
+
try {
|
|
31
|
+
const response = await platformFetch("/me");
|
|
32
|
+
const data = (await response.json());
|
|
33
|
+
if (!response.ok) {
|
|
34
|
+
clearToken();
|
|
35
|
+
s.stop(`Login failed: ${data.error ?? "Invalid token"}`, 1);
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
const project = data.projects?.[0];
|
|
39
|
+
s.stop(`Logged in as ${data.user?.name} (${data.user?.email})`);
|
|
40
|
+
if (project) {
|
|
41
|
+
p.log.info(`Project: ${project.slug}\n URL: ${project.url}`);
|
|
42
|
+
}
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
clearToken();
|
|
47
|
+
s.stop(`Login failed: ${error instanceof Error ? error.message : "Network error"}`, 1);
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Handle the invite token registration flow.
|
|
53
|
+
* Returns true if registration succeeded, or the symbol if cancelled.
|
|
54
|
+
*/
|
|
55
|
+
async function handleInviteFlow() {
|
|
56
|
+
const inviteTokenRaw = await p.text({
|
|
57
|
+
message: "Paste your token",
|
|
58
|
+
placeholder: "inv_...",
|
|
59
|
+
validate: (value) => {
|
|
60
|
+
if (!value)
|
|
61
|
+
return "Invite token is required";
|
|
62
|
+
return undefined;
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
if (p.isCancel(inviteTokenRaw))
|
|
66
|
+
return inviteTokenRaw;
|
|
67
|
+
const inviteToken = normalizeInviteToken(inviteTokenRaw);
|
|
68
|
+
const email = await p.text({
|
|
69
|
+
message: "Email",
|
|
70
|
+
validate: (value) => {
|
|
71
|
+
if (!value)
|
|
72
|
+
return "Email is required";
|
|
73
|
+
return undefined;
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
if (p.isCancel(email))
|
|
77
|
+
return email;
|
|
78
|
+
const name = await p.text({
|
|
79
|
+
message: "Name",
|
|
80
|
+
validate: (value) => {
|
|
81
|
+
if (!value)
|
|
82
|
+
return "Name is required";
|
|
83
|
+
return undefined;
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
if (p.isCancel(name))
|
|
87
|
+
return name;
|
|
88
|
+
// Register via API
|
|
89
|
+
const s = p.spinner();
|
|
90
|
+
s.start("Registering...");
|
|
91
|
+
try {
|
|
92
|
+
const response = await fetch(`${getApiUrl()}/me`, {
|
|
93
|
+
method: "POST",
|
|
94
|
+
headers: {
|
|
95
|
+
Authorization: `Bearer ${inviteToken}`,
|
|
96
|
+
"Content-Type": "application/json",
|
|
97
|
+
},
|
|
98
|
+
body: JSON.stringify({ email, name }),
|
|
99
|
+
});
|
|
100
|
+
const data = (await response.json());
|
|
101
|
+
if (!response.ok) {
|
|
102
|
+
s.stop(`Registration failed: ${data.error ?? "Unknown error"}`, 1);
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
if (!data.token) {
|
|
106
|
+
s.stop("Registration failed: No token returned", 1);
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
// Store the user token
|
|
110
|
+
setToken(data.token);
|
|
111
|
+
s.stop(`Welcome to Fling, ${data.name}!`);
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
s.stop(`Registration failed: ${error instanceof Error ? error.message : "Network error"}`, 1);
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Run the interactive onboarding flow.
|
|
121
|
+
*
|
|
122
|
+
* This can be called programmatically (from launch.ts) or via the command.
|
|
123
|
+
* Returns whether the user authenticated and whether to set up the default project.
|
|
124
|
+
*/
|
|
125
|
+
export async function runOnboarding(options) {
|
|
126
|
+
// Set API URL if provided
|
|
127
|
+
if (options?.apiUrl) {
|
|
128
|
+
setApiUrl(options.apiUrl);
|
|
129
|
+
}
|
|
130
|
+
p.intro("Welcome to Fling!");
|
|
131
|
+
// Check if already logged in
|
|
132
|
+
if (isLoggedIn()) {
|
|
133
|
+
const replace = await p.confirm({
|
|
134
|
+
message: "You're already logged in. Replace existing token?",
|
|
135
|
+
initialValue: false,
|
|
136
|
+
});
|
|
137
|
+
if (p.isCancel(replace) || !replace) {
|
|
138
|
+
p.outro("Keeping existing credentials.");
|
|
139
|
+
return { authenticated: true, setupProject: true };
|
|
140
|
+
}
|
|
141
|
+
clearToken();
|
|
142
|
+
}
|
|
143
|
+
// State machine for navigation
|
|
144
|
+
let step = "credential-choice";
|
|
145
|
+
let authenticated = false;
|
|
146
|
+
while (step !== "project-choice") {
|
|
147
|
+
switch (step) {
|
|
148
|
+
case "credential-choice": {
|
|
149
|
+
const choice = await p.select({
|
|
150
|
+
message: "How would you like to onboard?",
|
|
151
|
+
options: [
|
|
152
|
+
{ value: "invite", label: "I have an invite link/token" },
|
|
153
|
+
{ value: "api-token", label: "I have an API token" },
|
|
154
|
+
{ value: "skip", label: "Skip for now", hint: "local development only" },
|
|
155
|
+
],
|
|
156
|
+
});
|
|
157
|
+
if (p.isCancel(choice)) {
|
|
158
|
+
p.cancel("Onboarding cancelled.");
|
|
159
|
+
return { authenticated: false, setupProject: false };
|
|
160
|
+
}
|
|
161
|
+
if (choice === "invite") {
|
|
162
|
+
step = "invite-flow";
|
|
163
|
+
}
|
|
164
|
+
else if (choice === "api-token") {
|
|
165
|
+
step = "api-token";
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
// skip
|
|
169
|
+
p.log.info("No problem! You can still use Fling for local development.");
|
|
170
|
+
p.log.message("To deploy later, run:\n" +
|
|
171
|
+
" fling onboard - Interactive setup\n" +
|
|
172
|
+
" fling login <token> - If you have an API token\n" +
|
|
173
|
+
" fling register <inv> - If you have an invite link");
|
|
174
|
+
step = "project-choice";
|
|
175
|
+
}
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
case "api-token": {
|
|
179
|
+
const result = await handleApiTokenFlow();
|
|
180
|
+
if (p.isCancel(result)) {
|
|
181
|
+
step = "credential-choice";
|
|
182
|
+
}
|
|
183
|
+
else if (!result) {
|
|
184
|
+
return { authenticated: false, setupProject: false };
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
authenticated = true;
|
|
188
|
+
step = "project-choice";
|
|
189
|
+
}
|
|
190
|
+
break;
|
|
191
|
+
}
|
|
192
|
+
case "invite-flow": {
|
|
193
|
+
const result = await handleInviteFlow();
|
|
194
|
+
if (p.isCancel(result)) {
|
|
195
|
+
step = "credential-choice";
|
|
196
|
+
}
|
|
197
|
+
else if (!result) {
|
|
198
|
+
return { authenticated: false, setupProject: false };
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
authenticated = true;
|
|
202
|
+
step = "project-choice";
|
|
203
|
+
}
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
// Ask about project directory
|
|
209
|
+
const setupProject = await p.confirm({
|
|
210
|
+
message: "Create your Fling project at ~/fling?",
|
|
211
|
+
initialValue: true,
|
|
212
|
+
});
|
|
213
|
+
if (p.isCancel(setupProject)) {
|
|
214
|
+
p.cancel("Onboarding cancelled.");
|
|
215
|
+
return { authenticated, setupProject: false };
|
|
216
|
+
}
|
|
217
|
+
p.outro("You're all set!");
|
|
218
|
+
return { authenticated, setupProject };
|
|
219
|
+
}
|
|
220
|
+
export const onboardCommand = new Command("onboard")
|
|
221
|
+
.description("Interactive setup for new Fling users")
|
|
222
|
+
.option("--api-url <url>", "Override API endpoint (internal/testing use only)")
|
|
223
|
+
.addHelpText("after", `
|
|
224
|
+
What it does:
|
|
225
|
+
- Guides you through account setup (login or registration)
|
|
226
|
+
- Optionally creates your first Fling project at ~/fling
|
|
227
|
+
|
|
228
|
+
When to use:
|
|
229
|
+
- First time using Fling
|
|
230
|
+
- Re-authenticate after logging out
|
|
231
|
+
- Start fresh with a new account
|
|
232
|
+
|
|
233
|
+
Alternatives:
|
|
234
|
+
fling login <token> Skip interactive setup with a token
|
|
235
|
+
fling register <invite> Register directly with an invite
|
|
236
|
+
fling init Initialize a project without account setup
|
|
237
|
+
|
|
238
|
+
Examples:
|
|
239
|
+
fling onboard Start interactive setup
|
|
240
|
+
`)
|
|
241
|
+
.action(async (options) => {
|
|
242
|
+
await runOnboarding(options.apiUrl ? { apiUrl: options.apiUrl } : undefined);
|
|
243
|
+
});
|
|
244
|
+
//# sourceMappingURL=onboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"onboard.js","sourceRoot":"","sources":["../../../src/cli/commands/onboard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/project.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqBpC,eAAO,MAAM,cAAc,SAUzB,CAAC"}
|