clawfire 0.6.3 → 0.6.5
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/dist/cli.js +1 -1
- package/dist/{dev-server-NWB66EJT.js → dev-server-LCKIGM6U.js} +133 -1
- package/dist/dev.cjs +132 -0
- package/dist/dev.cjs.map +1 -1
- package/dist/dev.js +133 -1
- package/dist/dev.js.map +1 -1
- package/package.json +1 -1
package/dist/dev.js
CHANGED
|
@@ -2953,7 +2953,7 @@ function generateDashboardHtml(options) {
|
|
|
2953
2953
|
import { execFile as execFile2, spawn } from "child_process";
|
|
2954
2954
|
import { existsSync as existsSync6, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "fs";
|
|
2955
2955
|
import { resolve as resolve5, join as join4 } from "path";
|
|
2956
|
-
import { tmpdir, platform } from "os";
|
|
2956
|
+
import { tmpdir, platform, homedir } from "os";
|
|
2957
2957
|
var FirebaseSetup = class {
|
|
2958
2958
|
projectDir;
|
|
2959
2959
|
stateFilePath;
|
|
@@ -3377,8 +3377,119 @@ var FirebaseSetup = class {
|
|
|
3377
3377
|
return { success: true, message: `${service} enabled in firebase.json.` };
|
|
3378
3378
|
}
|
|
3379
3379
|
// ─── Firestore Database Automation ──────────────────────────────────
|
|
3380
|
+
/**
|
|
3381
|
+
* Read Firebase CLI's stored OAuth token and exchange for access token.
|
|
3382
|
+
* No gcloud CLI needed — uses the token from `firebase login`.
|
|
3383
|
+
*/
|
|
3384
|
+
async getFirebaseAccessToken() {
|
|
3385
|
+
const home = homedir();
|
|
3386
|
+
const configPath = join4(home, ".config", "configstore", "firebase-tools.json");
|
|
3387
|
+
if (!existsSync6(configPath)) return null;
|
|
3388
|
+
try {
|
|
3389
|
+
const config = JSON.parse(readFileSync4(configPath, "utf-8"));
|
|
3390
|
+
let refreshToken = null;
|
|
3391
|
+
if (config?.activeAccounts) {
|
|
3392
|
+
const activeEmail = config?.user?.email;
|
|
3393
|
+
if (activeEmail && config.activeAccounts[activeEmail]?.tokens?.refresh_token) {
|
|
3394
|
+
refreshToken = config.activeAccounts[activeEmail].tokens.refresh_token;
|
|
3395
|
+
}
|
|
3396
|
+
if (!refreshToken) {
|
|
3397
|
+
for (const account of Object.values(config.activeAccounts)) {
|
|
3398
|
+
if (account?.tokens?.refresh_token) {
|
|
3399
|
+
refreshToken = account.tokens.refresh_token;
|
|
3400
|
+
break;
|
|
3401
|
+
}
|
|
3402
|
+
}
|
|
3403
|
+
}
|
|
3404
|
+
}
|
|
3405
|
+
if (!refreshToken && config?.tokens?.refresh_token) {
|
|
3406
|
+
refreshToken = config.tokens.refresh_token;
|
|
3407
|
+
}
|
|
3408
|
+
if (!refreshToken) return null;
|
|
3409
|
+
const body = new URLSearchParams({
|
|
3410
|
+
grant_type: "refresh_token",
|
|
3411
|
+
refresh_token: refreshToken,
|
|
3412
|
+
client_id: "563584335869-fgrhgmd47bqnekij5i8b5pr03ho849e6.apps.googleusercontent.com",
|
|
3413
|
+
client_secret: "j9iVZfS8kkCEFUPaAeJV0sAi"
|
|
3414
|
+
});
|
|
3415
|
+
const res = await fetch("https://oauth2.googleapis.com/token", {
|
|
3416
|
+
method: "POST",
|
|
3417
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
3418
|
+
body: body.toString()
|
|
3419
|
+
});
|
|
3420
|
+
if (res.ok) {
|
|
3421
|
+
const data = await res.json();
|
|
3422
|
+
return data.access_token || null;
|
|
3423
|
+
}
|
|
3424
|
+
} catch {
|
|
3425
|
+
}
|
|
3426
|
+
return null;
|
|
3427
|
+
}
|
|
3428
|
+
/**
|
|
3429
|
+
* Enable Firestore API using Google Service Usage REST API.
|
|
3430
|
+
* Uses Firebase CLI's stored auth token — no gcloud CLI needed.
|
|
3431
|
+
* Falls back to gcloud CLI, then manual URL.
|
|
3432
|
+
*/
|
|
3433
|
+
async enableFirestoreApi() {
|
|
3434
|
+
const state = this.loadState();
|
|
3435
|
+
let projectId = state.projectId || "";
|
|
3436
|
+
if (!projectId) {
|
|
3437
|
+
const firebasercPath = resolve5(this.projectDir, ".firebaserc");
|
|
3438
|
+
if (existsSync6(firebasercPath)) {
|
|
3439
|
+
try {
|
|
3440
|
+
const rc = JSON.parse(readFileSync4(firebasercPath, "utf-8"));
|
|
3441
|
+
projectId = rc?.projects?.default || "";
|
|
3442
|
+
} catch {
|
|
3443
|
+
}
|
|
3444
|
+
}
|
|
3445
|
+
}
|
|
3446
|
+
if (!projectId) {
|
|
3447
|
+
return { success: false, message: "No project ID found. Select a project first." };
|
|
3448
|
+
}
|
|
3449
|
+
try {
|
|
3450
|
+
const accessToken = await this.getFirebaseAccessToken();
|
|
3451
|
+
if (accessToken) {
|
|
3452
|
+
const res = await fetch(
|
|
3453
|
+
`https://serviceusage.googleapis.com/v1/projects/${projectId}/services/firestore.googleapis.com:enable`,
|
|
3454
|
+
{
|
|
3455
|
+
method: "POST",
|
|
3456
|
+
headers: {
|
|
3457
|
+
Authorization: `Bearer ${accessToken}`,
|
|
3458
|
+
"Content-Type": "application/json"
|
|
3459
|
+
}
|
|
3460
|
+
}
|
|
3461
|
+
);
|
|
3462
|
+
if (res.ok) {
|
|
3463
|
+
return { success: true, message: "Firestore API enabled via REST API." };
|
|
3464
|
+
}
|
|
3465
|
+
if (res.status === 409) {
|
|
3466
|
+
return { success: true, message: "Firestore API already enabled." };
|
|
3467
|
+
}
|
|
3468
|
+
}
|
|
3469
|
+
} catch {
|
|
3470
|
+
}
|
|
3471
|
+
try {
|
|
3472
|
+
await this.execTimeout(
|
|
3473
|
+
"gcloud",
|
|
3474
|
+
["services", "enable", "firestore.googleapis.com", "--project", projectId],
|
|
3475
|
+
6e4
|
|
3476
|
+
);
|
|
3477
|
+
return { success: true, message: "Firestore API enabled via gcloud." };
|
|
3478
|
+
} catch (err) {
|
|
3479
|
+
const msg = err instanceof Error ? err.message : "Unknown error";
|
|
3480
|
+
if (!(msg.includes("ENOENT") || msg.includes("not found") || msg.includes("command not found"))) {
|
|
3481
|
+
return { success: false, message: `Failed to enable Firestore API: ${msg}` };
|
|
3482
|
+
}
|
|
3483
|
+
}
|
|
3484
|
+
return {
|
|
3485
|
+
success: false,
|
|
3486
|
+
message: `Failed to enable Firestore API automatically. Please enable it manually:
|
|
3487
|
+
https://console.developers.google.com/apis/api/firestore.googleapis.com/overview?project=${projectId}`
|
|
3488
|
+
};
|
|
3489
|
+
}
|
|
3380
3490
|
/**
|
|
3381
3491
|
* Create Firestore database via CLI.
|
|
3492
|
+
* Automatically enables Firestore API if needed.
|
|
3382
3493
|
* Handles "ALREADY_EXISTS" gracefully — returns success.
|
|
3383
3494
|
*/
|
|
3384
3495
|
async createFirestoreDatabase(location = "nam5") {
|
|
@@ -3394,6 +3505,27 @@ var FirebaseSetup = class {
|
|
|
3394
3505
|
if (msg.includes("ALREADY_EXISTS") || msg.includes("already exists")) {
|
|
3395
3506
|
return { success: true, message: "Firestore database already exists." };
|
|
3396
3507
|
}
|
|
3508
|
+
if (msg.includes("403") || msg.includes("has not been used") || msg.includes("is disabled")) {
|
|
3509
|
+
const enableResult = await this.enableFirestoreApi();
|
|
3510
|
+
if (!enableResult.success) {
|
|
3511
|
+
return enableResult;
|
|
3512
|
+
}
|
|
3513
|
+
await new Promise((r) => setTimeout(r, 5e3));
|
|
3514
|
+
try {
|
|
3515
|
+
await this.execTimeout(
|
|
3516
|
+
"firebase",
|
|
3517
|
+
["firestore:databases:create", "(default)", "--location", location, "--json"],
|
|
3518
|
+
6e4
|
|
3519
|
+
);
|
|
3520
|
+
return { success: true, message: `Firestore API enabled and database created (location: ${location}).` };
|
|
3521
|
+
} catch (retryErr) {
|
|
3522
|
+
const retryMsg = retryErr instanceof Error ? retryErr.message : "Unknown error";
|
|
3523
|
+
if (retryMsg.includes("ALREADY_EXISTS") || retryMsg.includes("already exists")) {
|
|
3524
|
+
return { success: true, message: "Firestore database already exists." };
|
|
3525
|
+
}
|
|
3526
|
+
return { success: false, message: `Failed to create Firestore database after enabling API: ${retryMsg}` };
|
|
3527
|
+
}
|
|
3528
|
+
}
|
|
3397
3529
|
return { success: false, message: `Failed to create Firestore database: ${msg}` };
|
|
3398
3530
|
}
|
|
3399
3531
|
}
|