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/cli.js +1 -1
- package/dist/{dev-server-IKWE6UJT.js → dev-server-FYHT3WN5.js} +39 -34
- package/dist/dev.cjs +39 -34
- package/dist/dev.cjs.map +1 -1
- package/dist/dev.js +39 -34
- package/dist/dev.js.map +1 -1
- package/package.json +1 -1
- package/templates/starter/app/components/nav.html +1 -1
- package/templates/starter/app/pages/index.html +5 -4
- package/templates/starter/app/pages/todos/index.html +20 -2
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-
|
|
272
|
+
const { startDevServer } = await import("./dev-server-FYHT3WN5.js");
|
|
273
273
|
await startDevServer({
|
|
274
274
|
projectDir,
|
|
275
275
|
port,
|
|
@@ -769,6 +769,7 @@ var PageCompiler = class {
|
|
|
769
769
|
try {
|
|
770
770
|
const compiled = this.compile(fullPath);
|
|
771
771
|
let html = compiled.html;
|
|
772
|
+
html = this.sanitizeForProduction(html);
|
|
772
773
|
if (scriptToInject) {
|
|
773
774
|
if (html.includes("</body>")) {
|
|
774
775
|
html = html.replace("</body>", scriptToInject + "\n</body>");
|
|
@@ -797,6 +798,18 @@ var PageCompiler = class {
|
|
|
797
798
|
walk(this.pagesDir);
|
|
798
799
|
return { pages, errors };
|
|
799
800
|
}
|
|
801
|
+
// ─── Production Sanitization ─────────────────────────────────────
|
|
802
|
+
/**
|
|
803
|
+
* Remove dev-only content from production builds:
|
|
804
|
+
* - Sections wrapped in <!-- dev-only:start --> / <!-- dev-only:end -->
|
|
805
|
+
* - Links to http://localhost (API Playground, dev dashboard, etc.)
|
|
806
|
+
*/
|
|
807
|
+
sanitizeForProduction(html) {
|
|
808
|
+
html = html.replace(/<!--\s*dev-only:start\s*-->[\s\S]*?<!--\s*dev-only:end\s*-->/g, "");
|
|
809
|
+
html = html.replace(/<a\s[^>]*href="http:\/\/localhost[^"]*"[^>]*>[\s\S]*?<\/a>/g, "");
|
|
810
|
+
html = html.replace(/\n{3,}/g, "\n\n");
|
|
811
|
+
return html;
|
|
812
|
+
}
|
|
800
813
|
// ─── Internal Methods ────────────────────────────────────────────
|
|
801
814
|
/**
|
|
802
815
|
* Extract <!-- @key: value --> metadata from HTML.
|
|
@@ -1465,9 +1478,9 @@ function generateDashboardHtml(options) {
|
|
|
1465
1478
|
<div style="margin-bottom:6px;"><strong style="color:#fbbf24;">Current Plan:</strong> <span style="color:#ef4444;">Spark (Free)</span></div>
|
|
1466
1479
|
<div style="margin-bottom:6px;"><strong style="color:#fbbf24;">Required Plan:</strong> <span style="color:#22c55e;">Blaze (Pay-as-you-go)</span></div>
|
|
1467
1480
|
<div style="margin-bottom:10px;color:#a3a3a3;font-size:12px;">
|
|
1468
|
-
Static pages (HTML/CSS/JS) are deployed and
|
|
1481
|
+
Static pages (HTML/CSS/JS) are deployed and live.<br>
|
|
1469
1482
|
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>
|
|
1470
|
-
Blaze plan has a generous free tier \u2014 you only pay for
|
|
1483
|
+
Blaze plan has a generous free tier \u2014 you only pay for usage beyond free limits.
|
|
1471
1484
|
</div>
|
|
1472
1485
|
<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;">
|
|
1473
1486
|
Upgrade to Blaze Plan →
|
|
@@ -2354,13 +2367,12 @@ function generateDashboardHtml(options) {
|
|
|
2354
2367
|
var btn = document.getElementById('deploy-hosting-btn');
|
|
2355
2368
|
var status = document.getElementById('deploy-hosting-status');
|
|
2356
2369
|
var urlBox = document.getElementById('deploy-hosting-url');
|
|
2370
|
+
var billingNote = document.getElementById('deploy-billing-note');
|
|
2357
2371
|
btn.disabled = true;
|
|
2358
2372
|
btn.textContent = 'Deploying...';
|
|
2359
|
-
status.textContent = 'Deploying to Firebase Hosting... This may take up to
|
|
2373
|
+
status.textContent = 'Deploying to Firebase Hosting... This may take up to 3 minutes.';
|
|
2360
2374
|
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;';
|
|
2361
2375
|
urlBox.style.display = 'none';
|
|
2362
|
-
|
|
2363
|
-
var billingNote = document.getElementById('deploy-billing-note');
|
|
2364
2376
|
billingNote.style.display = 'none';
|
|
2365
2377
|
|
|
2366
2378
|
fetch(API + '/__dev/deploy/hosting', { method: 'POST' })
|
|
@@ -2375,18 +2387,17 @@ function generateDashboardHtml(options) {
|
|
|
2375
2387
|
link.textContent = data.url;
|
|
2376
2388
|
urlBox.style.display = 'block';
|
|
2377
2389
|
}
|
|
2378
|
-
// Show Blaze plan notice
|
|
2390
|
+
// Show Blaze plan notice when functions deploy failed
|
|
2379
2391
|
if (data.blazeRequired) {
|
|
2380
2392
|
billingNote.style.display = 'block';
|
|
2381
2393
|
if (data.upgradeUrl) {
|
|
2382
|
-
|
|
2383
|
-
upgradeLink.href = data.upgradeUrl;
|
|
2394
|
+
document.getElementById('deploy-upgrade-link').href = data.upgradeUrl;
|
|
2384
2395
|
}
|
|
2385
2396
|
}
|
|
2386
2397
|
} else {
|
|
2387
2398
|
status.textContent = data.message;
|
|
2388
2399
|
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;';
|
|
2389
|
-
//
|
|
2400
|
+
// Also check if error is billing-related
|
|
2390
2401
|
var errMsg = (data.message || '').toLowerCase();
|
|
2391
2402
|
if (errMsg.indexOf('blaze') >= 0 || errMsg.indexOf('pay-as-you-go') >= 0 || errMsg.indexOf('upgrade') >= 0 || errMsg.indexOf('artifactregistry') >= 0) {
|
|
2392
2403
|
billingNote.style.display = 'block';
|
|
@@ -3421,7 +3432,8 @@ https://console.developers.google.com/apis/api/firestore.googleapis.com/overview
|
|
|
3421
3432
|
return new Promise((resolve6, reject) => {
|
|
3422
3433
|
const proc = execFile2(command, args, { cwd: cwd || this.projectDir, timeout: timeoutMs }, (err, stdout, stderr) => {
|
|
3423
3434
|
if (err) {
|
|
3424
|
-
const
|
|
3435
|
+
const parts = [stderr?.trim(), stdout?.trim()].filter(Boolean);
|
|
3436
|
+
const detail = parts.join("\n");
|
|
3425
3437
|
const enriched = new Error(`${err.message}${detail ? "\n" + detail : ""}`);
|
|
3426
3438
|
reject(enriched);
|
|
3427
3439
|
} else {
|
|
@@ -4650,45 +4662,38 @@ ${liveReloadScript}
|
|
|
4650
4662
|
}
|
|
4651
4663
|
steps.push("Hosting deployed");
|
|
4652
4664
|
let blazeRequired = false;
|
|
4653
|
-
let projectId = "";
|
|
4654
4665
|
if (deployFunctions) {
|
|
4655
4666
|
console.log(" Deploying functions...");
|
|
4656
4667
|
const funcResult = await this.firebaseSetup.deployHosting("functions");
|
|
4657
4668
|
if (funcResult.success) {
|
|
4658
|
-
console.log(
|
|
4669
|
+
console.log(" \x1B[32m\u2713\x1B[0m Functions deployed");
|
|
4659
4670
|
steps.push("Functions deployed");
|
|
4660
4671
|
} else {
|
|
4661
|
-
const
|
|
4662
|
-
|
|
4672
|
+
const errMsg = (funcResult.message || "").toLowerCase();
|
|
4673
|
+
const isBillingError = ["billing", "blaze", "pay-as-you-go", "upgrade your project", "budget"].some((kw) => errMsg.includes(kw));
|
|
4674
|
+
if (isBillingError) {
|
|
4663
4675
|
blazeRequired = true;
|
|
4664
|
-
|
|
4665
|
-
projectId = state.projectId || firebaseConfig.projectId || "";
|
|
4666
|
-
console.log(" \x1B[33m\u26A0\x1B[0m Functions require Blaze (pay-as-you-go) plan");
|
|
4676
|
+
console.log(" \x1B[33m\u26A0\x1B[0m Functions deploy failed (Blaze plan required)");
|
|
4667
4677
|
steps.push("Functions skipped (Blaze plan required)");
|
|
4668
4678
|
} else {
|
|
4669
4679
|
console.log(` \x1B[31m\u2717\x1B[0m Functions deploy failed: ${funcResult.message}`);
|
|
4670
|
-
steps.push(
|
|
4680
|
+
steps.push(`Functions deploy failed: ${funcResult.message}`);
|
|
4671
4681
|
}
|
|
4672
4682
|
}
|
|
4673
4683
|
}
|
|
4674
4684
|
clearFirebaseStatusCache();
|
|
4685
|
+
const state = this.firebaseSetup.loadState();
|
|
4686
|
+
const projectId = state.projectId || firebaseConfig.projectId || "";
|
|
4687
|
+
const upgradeUrl = projectId ? `https://console.firebase.google.com/project/${projectId}/usage/details` : "https://console.firebase.google.com";
|
|
4675
4688
|
const stepsStr = steps.length > 0 ? ` (${steps.join(", ")})` : "";
|
|
4676
|
-
|
|
4677
|
-
|
|
4678
|
-
|
|
4679
|
-
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
|
|
4683
|
-
|
|
4684
|
-
billingNote: `Static pages are live, but API routes (/api/*) require Cloud Functions which need the Blaze (pay-as-you-go) plan. Upgrade at: ${upgradeUrl}`
|
|
4685
|
-
});
|
|
4686
|
-
} else {
|
|
4687
|
-
sendJson({
|
|
4688
|
-
...hostingResult,
|
|
4689
|
-
message: hostingResult.message + stepsStr
|
|
4690
|
-
});
|
|
4691
|
-
}
|
|
4689
|
+
sendJson({
|
|
4690
|
+
success: true,
|
|
4691
|
+
url: hostingResult.url,
|
|
4692
|
+
blazeRequired,
|
|
4693
|
+
upgradeUrl: blazeRequired ? upgradeUrl : void 0,
|
|
4694
|
+
message: `Hosting deployed successfully!${stepsStr}`,
|
|
4695
|
+
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
|
|
4696
|
+
});
|
|
4692
4697
|
} catch (err) {
|
|
4693
4698
|
sendJson({ success: false, message: err instanceof Error ? err.message : "Failed" }, 500);
|
|
4694
4699
|
}
|
package/dist/dev.cjs
CHANGED
|
@@ -1181,6 +1181,7 @@ var PageCompiler = class {
|
|
|
1181
1181
|
try {
|
|
1182
1182
|
const compiled = this.compile(fullPath);
|
|
1183
1183
|
let html = compiled.html;
|
|
1184
|
+
html = this.sanitizeForProduction(html);
|
|
1184
1185
|
if (scriptToInject) {
|
|
1185
1186
|
if (html.includes("</body>")) {
|
|
1186
1187
|
html = html.replace("</body>", scriptToInject + "\n</body>");
|
|
@@ -1209,6 +1210,18 @@ var PageCompiler = class {
|
|
|
1209
1210
|
walk(this.pagesDir);
|
|
1210
1211
|
return { pages, errors };
|
|
1211
1212
|
}
|
|
1213
|
+
// ─── Production Sanitization ─────────────────────────────────────
|
|
1214
|
+
/**
|
|
1215
|
+
* Remove dev-only content from production builds:
|
|
1216
|
+
* - Sections wrapped in <!-- dev-only:start --> / <!-- dev-only:end -->
|
|
1217
|
+
* - Links to http://localhost (API Playground, dev dashboard, etc.)
|
|
1218
|
+
*/
|
|
1219
|
+
sanitizeForProduction(html) {
|
|
1220
|
+
html = html.replace(/<!--\s*dev-only:start\s*-->[\s\S]*?<!--\s*dev-only:end\s*-->/g, "");
|
|
1221
|
+
html = html.replace(/<a\s[^>]*href="http:\/\/localhost[^"]*"[^>]*>[\s\S]*?<\/a>/g, "");
|
|
1222
|
+
html = html.replace(/\n{3,}/g, "\n\n");
|
|
1223
|
+
return html;
|
|
1224
|
+
}
|
|
1212
1225
|
// ─── Internal Methods ────────────────────────────────────────────
|
|
1213
1226
|
/**
|
|
1214
1227
|
* Extract <!-- @key: value --> metadata from HTML.
|
|
@@ -1877,9 +1890,9 @@ function generateDashboardHtml(options) {
|
|
|
1877
1890
|
<div style="margin-bottom:6px;"><strong style="color:#fbbf24;">Current Plan:</strong> <span style="color:#ef4444;">Spark (Free)</span></div>
|
|
1878
1891
|
<div style="margin-bottom:6px;"><strong style="color:#fbbf24;">Required Plan:</strong> <span style="color:#22c55e;">Blaze (Pay-as-you-go)</span></div>
|
|
1879
1892
|
<div style="margin-bottom:10px;color:#a3a3a3;font-size:12px;">
|
|
1880
|
-
Static pages (HTML/CSS/JS) are deployed and
|
|
1893
|
+
Static pages (HTML/CSS/JS) are deployed and live.<br>
|
|
1881
1894
|
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>
|
|
1882
|
-
Blaze plan has a generous free tier \u2014 you only pay for
|
|
1895
|
+
Blaze plan has a generous free tier \u2014 you only pay for usage beyond free limits.
|
|
1883
1896
|
</div>
|
|
1884
1897
|
<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;">
|
|
1885
1898
|
Upgrade to Blaze Plan →
|
|
@@ -2766,13 +2779,12 @@ function generateDashboardHtml(options) {
|
|
|
2766
2779
|
var btn = document.getElementById('deploy-hosting-btn');
|
|
2767
2780
|
var status = document.getElementById('deploy-hosting-status');
|
|
2768
2781
|
var urlBox = document.getElementById('deploy-hosting-url');
|
|
2782
|
+
var billingNote = document.getElementById('deploy-billing-note');
|
|
2769
2783
|
btn.disabled = true;
|
|
2770
2784
|
btn.textContent = 'Deploying...';
|
|
2771
|
-
status.textContent = 'Deploying to Firebase Hosting... This may take up to
|
|
2785
|
+
status.textContent = 'Deploying to Firebase Hosting... This may take up to 3 minutes.';
|
|
2772
2786
|
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;';
|
|
2773
2787
|
urlBox.style.display = 'none';
|
|
2774
|
-
|
|
2775
|
-
var billingNote = document.getElementById('deploy-billing-note');
|
|
2776
2788
|
billingNote.style.display = 'none';
|
|
2777
2789
|
|
|
2778
2790
|
fetch(API + '/__dev/deploy/hosting', { method: 'POST' })
|
|
@@ -2787,18 +2799,17 @@ function generateDashboardHtml(options) {
|
|
|
2787
2799
|
link.textContent = data.url;
|
|
2788
2800
|
urlBox.style.display = 'block';
|
|
2789
2801
|
}
|
|
2790
|
-
// Show Blaze plan notice
|
|
2802
|
+
// Show Blaze plan notice when functions deploy failed
|
|
2791
2803
|
if (data.blazeRequired) {
|
|
2792
2804
|
billingNote.style.display = 'block';
|
|
2793
2805
|
if (data.upgradeUrl) {
|
|
2794
|
-
|
|
2795
|
-
upgradeLink.href = data.upgradeUrl;
|
|
2806
|
+
document.getElementById('deploy-upgrade-link').href = data.upgradeUrl;
|
|
2796
2807
|
}
|
|
2797
2808
|
}
|
|
2798
2809
|
} else {
|
|
2799
2810
|
status.textContent = data.message;
|
|
2800
2811
|
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;';
|
|
2801
|
-
//
|
|
2812
|
+
// Also check if error is billing-related
|
|
2802
2813
|
var errMsg = (data.message || '').toLowerCase();
|
|
2803
2814
|
if (errMsg.indexOf('blaze') >= 0 || errMsg.indexOf('pay-as-you-go') >= 0 || errMsg.indexOf('upgrade') >= 0 || errMsg.indexOf('artifactregistry') >= 0) {
|
|
2804
2815
|
billingNote.style.display = 'block';
|
|
@@ -3833,7 +3844,8 @@ https://console.developers.google.com/apis/api/firestore.googleapis.com/overview
|
|
|
3833
3844
|
return new Promise((resolve7, reject) => {
|
|
3834
3845
|
const proc = (0, import_node_child_process2.execFile)(command, args, { cwd: cwd || this.projectDir, timeout: timeoutMs }, (err, stdout, stderr) => {
|
|
3835
3846
|
if (err) {
|
|
3836
|
-
const
|
|
3847
|
+
const parts = [stderr?.trim(), stdout?.trim()].filter(Boolean);
|
|
3848
|
+
const detail = parts.join("\n");
|
|
3837
3849
|
const enriched = new Error(`${err.message}${detail ? "\n" + detail : ""}`);
|
|
3838
3850
|
reject(enriched);
|
|
3839
3851
|
} else {
|
|
@@ -5062,45 +5074,38 @@ ${liveReloadScript}
|
|
|
5062
5074
|
}
|
|
5063
5075
|
steps.push("Hosting deployed");
|
|
5064
5076
|
let blazeRequired = false;
|
|
5065
|
-
let projectId = "";
|
|
5066
5077
|
if (deployFunctions) {
|
|
5067
5078
|
console.log(" Deploying functions...");
|
|
5068
5079
|
const funcResult = await this.firebaseSetup.deployHosting("functions");
|
|
5069
5080
|
if (funcResult.success) {
|
|
5070
|
-
console.log(
|
|
5081
|
+
console.log(" \x1B[32m\u2713\x1B[0m Functions deployed");
|
|
5071
5082
|
steps.push("Functions deployed");
|
|
5072
5083
|
} else {
|
|
5073
|
-
const
|
|
5074
|
-
|
|
5084
|
+
const errMsg = (funcResult.message || "").toLowerCase();
|
|
5085
|
+
const isBillingError = ["billing", "blaze", "pay-as-you-go", "upgrade your project", "budget"].some((kw) => errMsg.includes(kw));
|
|
5086
|
+
if (isBillingError) {
|
|
5075
5087
|
blazeRequired = true;
|
|
5076
|
-
|
|
5077
|
-
projectId = state.projectId || firebaseConfig.projectId || "";
|
|
5078
|
-
console.log(" \x1B[33m\u26A0\x1B[0m Functions require Blaze (pay-as-you-go) plan");
|
|
5088
|
+
console.log(" \x1B[33m\u26A0\x1B[0m Functions deploy failed (Blaze plan required)");
|
|
5079
5089
|
steps.push("Functions skipped (Blaze plan required)");
|
|
5080
5090
|
} else {
|
|
5081
5091
|
console.log(` \x1B[31m\u2717\x1B[0m Functions deploy failed: ${funcResult.message}`);
|
|
5082
|
-
steps.push(
|
|
5092
|
+
steps.push(`Functions deploy failed: ${funcResult.message}`);
|
|
5083
5093
|
}
|
|
5084
5094
|
}
|
|
5085
5095
|
}
|
|
5086
5096
|
clearFirebaseStatusCache();
|
|
5097
|
+
const state = this.firebaseSetup.loadState();
|
|
5098
|
+
const projectId = state.projectId || firebaseConfig.projectId || "";
|
|
5099
|
+
const upgradeUrl = projectId ? `https://console.firebase.google.com/project/${projectId}/usage/details` : "https://console.firebase.google.com";
|
|
5087
5100
|
const stepsStr = steps.length > 0 ? ` (${steps.join(", ")})` : "";
|
|
5088
|
-
|
|
5089
|
-
|
|
5090
|
-
|
|
5091
|
-
|
|
5092
|
-
|
|
5093
|
-
|
|
5094
|
-
|
|
5095
|
-
|
|
5096
|
-
billingNote: `Static pages are live, but API routes (/api/*) require Cloud Functions which need the Blaze (pay-as-you-go) plan. Upgrade at: ${upgradeUrl}`
|
|
5097
|
-
});
|
|
5098
|
-
} else {
|
|
5099
|
-
sendJson({
|
|
5100
|
-
...hostingResult,
|
|
5101
|
-
message: hostingResult.message + stepsStr
|
|
5102
|
-
});
|
|
5103
|
-
}
|
|
5101
|
+
sendJson({
|
|
5102
|
+
success: true,
|
|
5103
|
+
url: hostingResult.url,
|
|
5104
|
+
blazeRequired,
|
|
5105
|
+
upgradeUrl: blazeRequired ? upgradeUrl : void 0,
|
|
5106
|
+
message: `Hosting deployed successfully!${stepsStr}`,
|
|
5107
|
+
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
|
|
5108
|
+
});
|
|
5104
5109
|
} catch (err) {
|
|
5105
5110
|
sendJson({ success: false, message: err instanceof Error ? err.message : "Failed" }, 500);
|
|
5106
5111
|
}
|