clawfire 0.6.14 → 0.6.16

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/dev.js CHANGED
@@ -1143,6 +1143,7 @@ var PageCompiler = class {
1143
1143
  try {
1144
1144
  const compiled = this.compile(fullPath);
1145
1145
  let html = compiled.html;
1146
+ html = this.sanitizeForProduction(html);
1146
1147
  if (scriptToInject) {
1147
1148
  if (html.includes("</body>")) {
1148
1149
  html = html.replace("</body>", scriptToInject + "\n</body>");
@@ -1171,6 +1172,18 @@ var PageCompiler = class {
1171
1172
  walk(this.pagesDir);
1172
1173
  return { pages, errors };
1173
1174
  }
1175
+ // ─── Production Sanitization ─────────────────────────────────────
1176
+ /**
1177
+ * Remove dev-only content from production builds:
1178
+ * - Sections wrapped in <!-- dev-only:start --> / <!-- dev-only:end -->
1179
+ * - Links to http://localhost (API Playground, dev dashboard, etc.)
1180
+ */
1181
+ sanitizeForProduction(html) {
1182
+ html = html.replace(/<!--\s*dev-only:start\s*-->[\s\S]*?<!--\s*dev-only:end\s*-->/g, "");
1183
+ html = html.replace(/<a\s[^>]*href="http:\/\/localhost[^"]*"[^>]*>[\s\S]*?<\/a>/g, "");
1184
+ html = html.replace(/\n{3,}/g, "\n\n");
1185
+ return html;
1186
+ }
1174
1187
  // ─── Internal Methods ────────────────────────────────────────────
1175
1188
  /**
1176
1189
  * Extract <!-- @key: value --> metadata from HTML.
@@ -1839,9 +1852,9 @@ function generateDashboardHtml(options) {
1839
1852
  <div style="margin-bottom:6px;"><strong style="color:#fbbf24;">Current Plan:</strong> <span style="color:#ef4444;">Spark (Free)</span></div>
1840
1853
  <div style="margin-bottom:6px;"><strong style="color:#fbbf24;">Required Plan:</strong> <span style="color:#22c55e;">Blaze (Pay-as-you-go)</span></div>
1841
1854
  <div style="margin-bottom:10px;color:#a3a3a3;font-size:12px;">
1842
- Static pages (HTML/CSS/JS) are deployed and working.<br>
1855
+ Static pages (HTML/CSS/JS) are deployed and live.<br>
1843
1856
  API routes (<code style="background:#2a2a2a;padding:2px 6px;border-radius:3px;color:#f97316;">/api/*</code>) require Cloud Functions, which need the Blaze plan.<br>
1844
- Blaze plan has a generous free tier \u2014 you only pay for actual usage beyond free limits.
1857
+ Blaze plan has a generous free tier \u2014 you only pay for usage beyond free limits.
1845
1858
  </div>
1846
1859
  <a id="deploy-upgrade-link" href="#" target="_blank" style="display:inline-block;padding:8px 16px;background:#f59e0b;color:#000;border-radius:6px;font-size:13px;font-weight:700;text-decoration:none;">
1847
1860
  Upgrade to Blaze Plan &#8594;
@@ -2728,13 +2741,12 @@ function generateDashboardHtml(options) {
2728
2741
  var btn = document.getElementById('deploy-hosting-btn');
2729
2742
  var status = document.getElementById('deploy-hosting-status');
2730
2743
  var urlBox = document.getElementById('deploy-hosting-url');
2744
+ var billingNote = document.getElementById('deploy-billing-note');
2731
2745
  btn.disabled = true;
2732
2746
  btn.textContent = 'Deploying...';
2733
- status.textContent = 'Deploying to Firebase Hosting... This may take up to 2 minutes.';
2747
+ status.textContent = 'Deploying to Firebase Hosting... This may take up to 3 minutes.';
2734
2748
  status.style.cssText = 'display:block;margin-top:10px;font-size:13px;padding:10px 14px;border-radius:6px;background:#0a0a1a;border:1px solid #3b82f6;color:#3b82f6;';
2735
2749
  urlBox.style.display = 'none';
2736
-
2737
- var billingNote = document.getElementById('deploy-billing-note');
2738
2750
  billingNote.style.display = 'none';
2739
2751
 
2740
2752
  fetch(API + '/__dev/deploy/hosting', { method: 'POST' })
@@ -2749,18 +2761,17 @@ function generateDashboardHtml(options) {
2749
2761
  link.textContent = data.url;
2750
2762
  urlBox.style.display = 'block';
2751
2763
  }
2752
- // Show Blaze plan notice if needed
2764
+ // Show Blaze plan notice when functions deploy failed
2753
2765
  if (data.blazeRequired) {
2754
2766
  billingNote.style.display = 'block';
2755
2767
  if (data.upgradeUrl) {
2756
- var upgradeLink = document.getElementById('deploy-upgrade-link');
2757
- upgradeLink.href = data.upgradeUrl;
2768
+ document.getElementById('deploy-upgrade-link').href = data.upgradeUrl;
2758
2769
  }
2759
2770
  }
2760
2771
  } else {
2761
2772
  status.textContent = data.message;
2762
2773
  status.style.cssText = 'display:block;margin-top:10px;font-size:13px;padding:10px 14px;border-radius:6px;background:#1c0808;border:1px solid #ef4444;color:#ef4444;';
2763
- // Check if error is about billing \u2014 show upgrade notice
2774
+ // Also check if error is billing-related
2764
2775
  var errMsg = (data.message || '').toLowerCase();
2765
2776
  if (errMsg.indexOf('blaze') >= 0 || errMsg.indexOf('pay-as-you-go') >= 0 || errMsg.indexOf('upgrade') >= 0 || errMsg.indexOf('artifactregistry') >= 0) {
2766
2777
  billingNote.style.display = 'block';
@@ -3795,7 +3806,8 @@ https://console.developers.google.com/apis/api/firestore.googleapis.com/overview
3795
3806
  return new Promise((resolve7, reject) => {
3796
3807
  const proc = execFile2(command, args, { cwd: cwd || this.projectDir, timeout: timeoutMs }, (err, stdout, stderr) => {
3797
3808
  if (err) {
3798
- const detail = stderr?.trim() || stdout?.trim() || "";
3809
+ const parts = [stderr?.trim(), stdout?.trim()].filter(Boolean);
3810
+ const detail = parts.join("\n");
3799
3811
  const enriched = new Error(`${err.message}${detail ? "\n" + detail : ""}`);
3800
3812
  reject(enriched);
3801
3813
  } else {
@@ -5024,45 +5036,38 @@ ${liveReloadScript}
5024
5036
  }
5025
5037
  steps.push("Hosting deployed");
5026
5038
  let blazeRequired = false;
5027
- let projectId = "";
5028
5039
  if (deployFunctions) {
5029
5040
  console.log(" Deploying functions...");
5030
5041
  const funcResult = await this.firebaseSetup.deployHosting("functions");
5031
5042
  if (funcResult.success) {
5032
- console.log(` \x1B[32m\u2713\x1B[0m Functions deployed`);
5043
+ console.log(" \x1B[32m\u2713\x1B[0m Functions deployed");
5033
5044
  steps.push("Functions deployed");
5034
5045
  } else {
5035
- const msg = funcResult.message.toLowerCase();
5036
- if (msg.includes("blaze") || msg.includes("pay-as-you-go") || msg.includes("upgrade") || msg.includes("billing") || msg.includes("artifactregistry")) {
5046
+ const errMsg = (funcResult.message || "").toLowerCase();
5047
+ const isBillingError = ["billing", "blaze", "pay-as-you-go", "upgrade your project", "budget"].some((kw) => errMsg.includes(kw));
5048
+ if (isBillingError) {
5037
5049
  blazeRequired = true;
5038
- const state = this.firebaseSetup.loadState();
5039
- projectId = state.projectId || firebaseConfig.projectId || "";
5040
- console.log(" \x1B[33m\u26A0\x1B[0m Functions require Blaze (pay-as-you-go) plan");
5050
+ console.log(" \x1B[33m\u26A0\x1B[0m Functions deploy failed (Blaze plan required)");
5041
5051
  steps.push("Functions skipped (Blaze plan required)");
5042
5052
  } else {
5043
5053
  console.log(` \x1B[31m\u2717\x1B[0m Functions deploy failed: ${funcResult.message}`);
5044
- steps.push("Functions deploy failed");
5054
+ steps.push(`Functions deploy failed: ${funcResult.message}`);
5045
5055
  }
5046
5056
  }
5047
5057
  }
5048
5058
  clearFirebaseStatusCache();
5059
+ const state = this.firebaseSetup.loadState();
5060
+ const projectId = state.projectId || firebaseConfig.projectId || "";
5061
+ const upgradeUrl = projectId ? `https://console.firebase.google.com/project/${projectId}/usage/details` : "https://console.firebase.google.com";
5049
5062
  const stepsStr = steps.length > 0 ? ` (${steps.join(", ")})` : "";
5050
- if (blazeRequired) {
5051
- const upgradeUrl = projectId ? `https://console.firebase.google.com/project/${projectId}/usage/details` : "https://console.firebase.google.com";
5052
- sendJson({
5053
- success: true,
5054
- url: hostingResult.url,
5055
- blazeRequired: true,
5056
- upgradeUrl,
5057
- message: `Hosting deployed successfully!${stepsStr}`,
5058
- billingNote: `Static pages are live, but API routes (/api/*) require Cloud Functions which need the Blaze (pay-as-you-go) plan. Upgrade at: ${upgradeUrl}`
5059
- });
5060
- } else {
5061
- sendJson({
5062
- ...hostingResult,
5063
- message: hostingResult.message + stepsStr
5064
- });
5065
- }
5063
+ sendJson({
5064
+ success: true,
5065
+ url: hostingResult.url,
5066
+ blazeRequired,
5067
+ upgradeUrl: blazeRequired ? upgradeUrl : void 0,
5068
+ message: `Hosting deployed successfully!${stepsStr}`,
5069
+ billingNote: blazeRequired ? `Static pages are live! But API routes (/api/*) need Cloud Functions, which require the Blaze (pay-as-you-go) plan. Upgrade: ${upgradeUrl}` : void 0
5070
+ });
5066
5071
  } catch (err) {
5067
5072
  sendJson({ success: false, message: err instanceof Error ? err.message : "Failed" }, 500);
5068
5073
  }