clawfire 0.6.5 → 0.6.6

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 CHANGED
@@ -269,7 +269,7 @@ async function runDevServer() {
269
269
  const port = portArg ? parseInt(portArg.split("=")[1], 10) : 3e3;
270
270
  const apiPort = apiPortArg ? parseInt(apiPortArg.split("=")[1], 10) : 3456;
271
271
  const noHotReload = args.includes("--no-hot-reload");
272
- const { startDevServer } = await import("./dev-server-LCKIGM6U.js");
272
+ const { startDevServer } = await import("./dev-server-PQP33VSE.js");
273
273
  await startDevServer({
274
274
  projectDir,
275
275
  port,
@@ -1856,8 +1856,9 @@ function generateDashboardHtml(options) {
1856
1856
  }
1857
1857
 
1858
1858
  btn.disabled = true;
1859
- btn.textContent = 'Setting...';
1860
- status.style.display = 'none';
1859
+ btn.textContent = 'Setting up...';
1860
+ status.textContent = 'Selecting project, detecting web app, auto-filling config...';
1861
+ status.style.cssText = 'display:block;margin-top:8px;font-size:13px;padding:8px 12px;border-radius:6px;background:#0a0a1c;border:1px solid #3b82f6;color:#93c5fd;';
1861
1862
 
1862
1863
  fetch(API + '/__dev/setup/select-project', {
1863
1864
  method: 'POST',
@@ -1867,8 +1868,11 @@ function generateDashboardHtml(options) {
1867
1868
  .then(function(r) { return r.json(); })
1868
1869
  .then(function(data) {
1869
1870
  if (data.success) {
1870
- status.textContent = data.message;
1871
- status.style.cssText = 'display:block;margin-top:8px;font-size:13px;padding:8px 12px;border-radius:6px;background:#0a1a0a;border:1px solid #22c55e;color:#22c55e;';
1871
+ var msg = data.steps ? data.steps.join('\\n') : data.message;
1872
+ status.textContent = msg;
1873
+ status.style.whiteSpace = 'pre-line';
1874
+ status.style.cssText = 'display:block;margin-top:8px;font-size:13px;padding:8px 12px;border-radius:6px;background:#0a1a0a;border:1px solid #22c55e;color:#22c55e;white-space:pre-line;';
1875
+ btn.textContent = 'Done';
1872
1876
  setTimeout(refreshSetupStatus, 1000);
1873
1877
  } else {
1874
1878
  status.textContent = data.message;
@@ -3119,41 +3123,48 @@ https://console.developers.google.com/apis/api/firestore.googleapis.com/overview
3119
3123
  * Handles "ALREADY_EXISTS" gracefully — returns success.
3120
3124
  */
3121
3125
  async createFirestoreDatabase(location = "nam5") {
3122
- try {
3123
- await this.execTimeout(
3124
- "firebase",
3125
- ["firestore:databases:create", "(default)", "--location", location, "--json"],
3126
- 6e4
3127
- );
3128
- return { success: true, message: `Firestore database created (location: ${location}).` };
3129
- } catch (err) {
3130
- const msg = err instanceof Error ? err.message : "Unknown error";
3131
- if (msg.includes("ALREADY_EXISTS") || msg.includes("already exists")) {
3132
- return { success: true, message: "Firestore database already exists." };
3133
- }
3134
- if (msg.includes("403") || msg.includes("has not been used") || msg.includes("is disabled")) {
3135
- const enableResult = await this.enableFirestoreApi();
3136
- if (!enableResult.success) {
3137
- return enableResult;
3126
+ const dbArgs = ["firestore:databases:create", "(default)", "--location", location, "--json"];
3127
+ const tryCreate = async () => {
3128
+ try {
3129
+ await this.execTimeout("firebase", dbArgs, 6e4);
3130
+ return { ok: true, alreadyExists: false, needsApi: false, msg: "" };
3131
+ } catch (err) {
3132
+ const msg = err instanceof Error ? err.message : "Unknown error";
3133
+ if (msg.includes("ALREADY_EXISTS") || msg.includes("already exists")) {
3134
+ return { ok: true, alreadyExists: true, needsApi: false, msg };
3138
3135
  }
3139
- await new Promise((r) => setTimeout(r, 5e3));
3140
- try {
3141
- await this.execTimeout(
3142
- "firebase",
3143
- ["firestore:databases:create", "(default)", "--location", location, "--json"],
3144
- 6e4
3145
- );
3146
- return { success: true, message: `Firestore API enabled and database created (location: ${location}).` };
3147
- } catch (retryErr) {
3148
- const retryMsg = retryErr instanceof Error ? retryErr.message : "Unknown error";
3149
- if (retryMsg.includes("ALREADY_EXISTS") || retryMsg.includes("already exists")) {
3150
- return { success: true, message: "Firestore database already exists." };
3151
- }
3152
- return { success: false, message: `Failed to create Firestore database after enabling API: ${retryMsg}` };
3136
+ if (msg.includes("403") || msg.includes("has not been used") || msg.includes("is disabled")) {
3137
+ return { ok: false, alreadyExists: false, needsApi: true, msg };
3153
3138
  }
3139
+ return { ok: false, alreadyExists: false, needsApi: false, msg };
3140
+ }
3141
+ };
3142
+ const first = await tryCreate();
3143
+ if (first.ok) {
3144
+ return { success: true, message: first.alreadyExists ? "Firestore database already exists." : `Firestore database created (location: ${location}).` };
3145
+ }
3146
+ if (!first.needsApi) {
3147
+ return { success: false, message: `Failed to create Firestore database: ${first.msg}` };
3148
+ }
3149
+ const enableResult = await this.enableFirestoreApi();
3150
+ if (!enableResult.success) {
3151
+ return enableResult;
3152
+ }
3153
+ const waits = [5e3, 5e3, 1e4, 1e4, 15e3];
3154
+ for (let i = 0; i < waits.length; i++) {
3155
+ await new Promise((r) => setTimeout(r, waits[i]));
3156
+ const retry = await tryCreate();
3157
+ if (retry.ok) {
3158
+ return { success: true, message: `Firestore API enabled and database created (location: ${location}).` };
3159
+ }
3160
+ if (!retry.needsApi) {
3161
+ return { success: false, message: `Failed to create Firestore database: ${retry.msg}` };
3154
3162
  }
3155
- return { success: false, message: `Failed to create Firestore database: ${msg}` };
3156
3163
  }
3164
+ return {
3165
+ success: false,
3166
+ message: "Firestore API was enabled but database creation timed out waiting for propagation. Please wait a minute and try again."
3167
+ };
3157
3168
  }
3158
3169
  /**
3159
3170
  * Deploy open Firestore security rules for dev testing.
@@ -4173,10 +4184,57 @@ ${liveReloadScript}
4173
4184
  sendJson({ success: false, message: "projectId is required" }, 400);
4174
4185
  return;
4175
4186
  }
4176
- this.firebaseSetup.selectProject(data.projectId).then((result) => {
4187
+ (async () => {
4188
+ const selectResult = await this.firebaseSetup.selectProject(data.projectId);
4189
+ if (!selectResult.success) {
4190
+ sendJson(selectResult);
4191
+ return;
4192
+ }
4193
+ const steps = [selectResult.message];
4194
+ try {
4195
+ const { apps } = await this.firebaseSetup.listWebApps();
4196
+ let webAppId = "";
4197
+ if (apps.length > 0) {
4198
+ webAppId = apps[0].appId;
4199
+ this.firebaseSetup.selectWebApp(apps[0].appId, apps[0].displayName);
4200
+ steps.push(`Web app "${apps[0].displayName}" selected.`);
4201
+ } else {
4202
+ const createResult = await this.firebaseSetup.createWebApp(data.projectId);
4203
+ if (createResult.success && createResult.appId) {
4204
+ webAppId = createResult.appId;
4205
+ steps.push(`Web app "${data.projectId}" created.`);
4206
+ } else {
4207
+ steps.push(`Web app creation skipped: ${createResult.message}`);
4208
+ }
4209
+ }
4210
+ if (webAppId) {
4211
+ try {
4212
+ const sdkConfig = await fetchFirebaseSdkConfig(this.options.projectDir, webAppId);
4213
+ const fields = {};
4214
+ for (const [key, value] of Object.entries(sdkConfig)) {
4215
+ if (value && typeof value === "string") {
4216
+ fields[key] = value;
4217
+ }
4218
+ }
4219
+ if (Object.keys(fields).length > 0) {
4220
+ for (const [key, value] of Object.entries(fields)) {
4221
+ try {
4222
+ this.updateProjectConfig(key, value);
4223
+ } catch {
4224
+ }
4225
+ }
4226
+ steps.push("Config auto-filled in clawfire.config.ts.");
4227
+ }
4228
+ } catch (configErr) {
4229
+ steps.push(`Config auto-fill skipped: ${configErr instanceof Error ? configErr.message : "unknown error"}`);
4230
+ }
4231
+ }
4232
+ } catch (autoFillErr) {
4233
+ steps.push(`Auto-setup partial: ${autoFillErr instanceof Error ? autoFillErr.message : "unknown error"}`);
4234
+ }
4177
4235
  clearFirebaseStatusCache();
4178
- sendJson(result);
4179
- }).catch((err) => sendJson({ success: false, message: err instanceof Error ? err.message : "Failed" }, 500));
4236
+ sendJson({ success: true, message: steps.join(" "), steps });
4237
+ })().catch((err) => sendJson({ success: false, message: err instanceof Error ? err.message : "Failed" }, 500));
4180
4238
  } catch {
4181
4239
  sendJson({ success: false, message: "Invalid JSON body" }, 400);
4182
4240
  }
package/dist/dev.cjs CHANGED
@@ -2268,8 +2268,9 @@ function generateDashboardHtml(options) {
2268
2268
  }
2269
2269
 
2270
2270
  btn.disabled = true;
2271
- btn.textContent = 'Setting...';
2272
- status.style.display = 'none';
2271
+ btn.textContent = 'Setting up...';
2272
+ status.textContent = 'Selecting project, detecting web app, auto-filling config...';
2273
+ status.style.cssText = 'display:block;margin-top:8px;font-size:13px;padding:8px 12px;border-radius:6px;background:#0a0a1c;border:1px solid #3b82f6;color:#93c5fd;';
2273
2274
 
2274
2275
  fetch(API + '/__dev/setup/select-project', {
2275
2276
  method: 'POST',
@@ -2279,8 +2280,11 @@ function generateDashboardHtml(options) {
2279
2280
  .then(function(r) { return r.json(); })
2280
2281
  .then(function(data) {
2281
2282
  if (data.success) {
2282
- status.textContent = data.message;
2283
- status.style.cssText = 'display:block;margin-top:8px;font-size:13px;padding:8px 12px;border-radius:6px;background:#0a1a0a;border:1px solid #22c55e;color:#22c55e;';
2283
+ var msg = data.steps ? data.steps.join('\\n') : data.message;
2284
+ status.textContent = msg;
2285
+ status.style.whiteSpace = 'pre-line';
2286
+ status.style.cssText = 'display:block;margin-top:8px;font-size:13px;padding:8px 12px;border-radius:6px;background:#0a1a0a;border:1px solid #22c55e;color:#22c55e;white-space:pre-line;';
2287
+ btn.textContent = 'Done';
2284
2288
  setTimeout(refreshSetupStatus, 1000);
2285
2289
  } else {
2286
2290
  status.textContent = data.message;
@@ -3531,41 +3535,48 @@ https://console.developers.google.com/apis/api/firestore.googleapis.com/overview
3531
3535
  * Handles "ALREADY_EXISTS" gracefully — returns success.
3532
3536
  */
3533
3537
  async createFirestoreDatabase(location = "nam5") {
3534
- try {
3535
- await this.execTimeout(
3536
- "firebase",
3537
- ["firestore:databases:create", "(default)", "--location", location, "--json"],
3538
- 6e4
3539
- );
3540
- return { success: true, message: `Firestore database created (location: ${location}).` };
3541
- } catch (err) {
3542
- const msg = err instanceof Error ? err.message : "Unknown error";
3543
- if (msg.includes("ALREADY_EXISTS") || msg.includes("already exists")) {
3544
- return { success: true, message: "Firestore database already exists." };
3545
- }
3546
- if (msg.includes("403") || msg.includes("has not been used") || msg.includes("is disabled")) {
3547
- const enableResult = await this.enableFirestoreApi();
3548
- if (!enableResult.success) {
3549
- return enableResult;
3538
+ const dbArgs = ["firestore:databases:create", "(default)", "--location", location, "--json"];
3539
+ const tryCreate = async () => {
3540
+ try {
3541
+ await this.execTimeout("firebase", dbArgs, 6e4);
3542
+ return { ok: true, alreadyExists: false, needsApi: false, msg: "" };
3543
+ } catch (err) {
3544
+ const msg = err instanceof Error ? err.message : "Unknown error";
3545
+ if (msg.includes("ALREADY_EXISTS") || msg.includes("already exists")) {
3546
+ return { ok: true, alreadyExists: true, needsApi: false, msg };
3550
3547
  }
3551
- await new Promise((r) => setTimeout(r, 5e3));
3552
- try {
3553
- await this.execTimeout(
3554
- "firebase",
3555
- ["firestore:databases:create", "(default)", "--location", location, "--json"],
3556
- 6e4
3557
- );
3558
- return { success: true, message: `Firestore API enabled and database created (location: ${location}).` };
3559
- } catch (retryErr) {
3560
- const retryMsg = retryErr instanceof Error ? retryErr.message : "Unknown error";
3561
- if (retryMsg.includes("ALREADY_EXISTS") || retryMsg.includes("already exists")) {
3562
- return { success: true, message: "Firestore database already exists." };
3563
- }
3564
- return { success: false, message: `Failed to create Firestore database after enabling API: ${retryMsg}` };
3548
+ if (msg.includes("403") || msg.includes("has not been used") || msg.includes("is disabled")) {
3549
+ return { ok: false, alreadyExists: false, needsApi: true, msg };
3565
3550
  }
3551
+ return { ok: false, alreadyExists: false, needsApi: false, msg };
3552
+ }
3553
+ };
3554
+ const first = await tryCreate();
3555
+ if (first.ok) {
3556
+ return { success: true, message: first.alreadyExists ? "Firestore database already exists." : `Firestore database created (location: ${location}).` };
3557
+ }
3558
+ if (!first.needsApi) {
3559
+ return { success: false, message: `Failed to create Firestore database: ${first.msg}` };
3560
+ }
3561
+ const enableResult = await this.enableFirestoreApi();
3562
+ if (!enableResult.success) {
3563
+ return enableResult;
3564
+ }
3565
+ const waits = [5e3, 5e3, 1e4, 1e4, 15e3];
3566
+ for (let i = 0; i < waits.length; i++) {
3567
+ await new Promise((r) => setTimeout(r, waits[i]));
3568
+ const retry = await tryCreate();
3569
+ if (retry.ok) {
3570
+ return { success: true, message: `Firestore API enabled and database created (location: ${location}).` };
3571
+ }
3572
+ if (!retry.needsApi) {
3573
+ return { success: false, message: `Failed to create Firestore database: ${retry.msg}` };
3566
3574
  }
3567
- return { success: false, message: `Failed to create Firestore database: ${msg}` };
3568
3575
  }
3576
+ return {
3577
+ success: false,
3578
+ message: "Firestore API was enabled but database creation timed out waiting for propagation. Please wait a minute and try again."
3579
+ };
3569
3580
  }
3570
3581
  /**
3571
3582
  * Deploy open Firestore security rules for dev testing.
@@ -4585,10 +4596,57 @@ ${liveReloadScript}
4585
4596
  sendJson({ success: false, message: "projectId is required" }, 400);
4586
4597
  return;
4587
4598
  }
4588
- this.firebaseSetup.selectProject(data.projectId).then((result) => {
4599
+ (async () => {
4600
+ const selectResult = await this.firebaseSetup.selectProject(data.projectId);
4601
+ if (!selectResult.success) {
4602
+ sendJson(selectResult);
4603
+ return;
4604
+ }
4605
+ const steps = [selectResult.message];
4606
+ try {
4607
+ const { apps } = await this.firebaseSetup.listWebApps();
4608
+ let webAppId = "";
4609
+ if (apps.length > 0) {
4610
+ webAppId = apps[0].appId;
4611
+ this.firebaseSetup.selectWebApp(apps[0].appId, apps[0].displayName);
4612
+ steps.push(`Web app "${apps[0].displayName}" selected.`);
4613
+ } else {
4614
+ const createResult = await this.firebaseSetup.createWebApp(data.projectId);
4615
+ if (createResult.success && createResult.appId) {
4616
+ webAppId = createResult.appId;
4617
+ steps.push(`Web app "${data.projectId}" created.`);
4618
+ } else {
4619
+ steps.push(`Web app creation skipped: ${createResult.message}`);
4620
+ }
4621
+ }
4622
+ if (webAppId) {
4623
+ try {
4624
+ const sdkConfig = await fetchFirebaseSdkConfig(this.options.projectDir, webAppId);
4625
+ const fields = {};
4626
+ for (const [key, value] of Object.entries(sdkConfig)) {
4627
+ if (value && typeof value === "string") {
4628
+ fields[key] = value;
4629
+ }
4630
+ }
4631
+ if (Object.keys(fields).length > 0) {
4632
+ for (const [key, value] of Object.entries(fields)) {
4633
+ try {
4634
+ this.updateProjectConfig(key, value);
4635
+ } catch {
4636
+ }
4637
+ }
4638
+ steps.push("Config auto-filled in clawfire.config.ts.");
4639
+ }
4640
+ } catch (configErr) {
4641
+ steps.push(`Config auto-fill skipped: ${configErr instanceof Error ? configErr.message : "unknown error"}`);
4642
+ }
4643
+ }
4644
+ } catch (autoFillErr) {
4645
+ steps.push(`Auto-setup partial: ${autoFillErr instanceof Error ? autoFillErr.message : "unknown error"}`);
4646
+ }
4589
4647
  clearFirebaseStatusCache();
4590
- sendJson(result);
4591
- }).catch((err) => sendJson({ success: false, message: err instanceof Error ? err.message : "Failed" }, 500));
4648
+ sendJson({ success: true, message: steps.join(" "), steps });
4649
+ })().catch((err) => sendJson({ success: false, message: err instanceof Error ? err.message : "Failed" }, 500));
4592
4650
  } catch {
4593
4651
  sendJson({ success: false, message: "Invalid JSON body" }, 400);
4594
4652
  }