backend-manager 5.0.192 → 5.0.194
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/CHANGELOG.md +9 -0
- package/CLAUDE.md +45 -4
- package/TODO-2.md +20 -0
- package/package.json +24 -29
- package/src/cli/commands/auth.js +4 -6
- package/src/cli/commands/base-command.js +5 -7
- package/src/cli/commands/emulator.js +1 -1
- package/src/cli/commands/firebase-init.js +1 -1
- package/src/cli/commands/firestore.js +4 -6
- package/src/cli/commands/indexes.js +1 -1
- package/src/cli/commands/install.js +1 -1
- package/src/cli/commands/logs.js +15 -4
- package/src/cli/commands/mcp.js +1 -1
- package/src/cli/commands/serve.js +1 -1
- package/src/cli/commands/setup-tests/backend-manager.js +1 -1
- package/src/cli/commands/setup-tests/bem-config.js +1 -1
- package/src/cli/commands/setup-tests/firebase-admin.js +1 -1
- package/src/cli/commands/setup-tests/firebase-cli.js +1 -1
- package/src/cli/commands/setup-tests/firebase-functions.js +1 -1
- package/src/cli/commands/setup-tests/firestore-indexes-file.js +1 -1
- package/src/cli/commands/setup-tests/firestore-indexes-required.js +1 -1
- package/src/cli/commands/setup-tests/firestore-indexes-synced.js +1 -1
- package/src/cli/commands/setup-tests/firestore-rules-file.js +1 -1
- package/src/cli/commands/setup-tests/index.js +2 -2
- package/src/cli/commands/setup-tests/is-firebase-project.js +1 -1
- package/src/cli/commands/setup-tests/legacy-tests-cleanup.js +1 -1
- package/src/cli/commands/setup-tests/marketing-campaigns-seeded.js +1 -1
- package/src/cli/commands/setup-tests/node-version.js +1 -1
- package/src/cli/commands/setup-tests/nvmrc-version.js +1 -1
- package/src/cli/commands/setup-tests/{hooks-directories.js → project-directories.js} +7 -5
- package/src/cli/commands/setup-tests/project-id-consistency.js +1 -1
- package/src/cli/commands/setup-tests/realtime-rules-file.js +1 -1
- package/src/cli/commands/setup-tests/remoteconfig-template-file.js +1 -1
- package/src/cli/commands/setup-tests/service-account.js +1 -1
- package/src/cli/commands/setup-tests/storage-lifecycle-policy.js +1 -1
- package/src/cli/commands/setup-tests/storage-rules-file.js +1 -1
- package/src/cli/commands/setup.js +2 -2
- package/src/cli/commands/test.js +2 -2
- package/src/cli/commands/watch.js +1 -1
- package/src/cli/index.js +2 -2
- package/src/manager/events/cron/daily/expire-paypal-cancellations.js +1 -1
- package/src/manager/events/cron/daily/ghostii-auto-publisher.js +1 -1
- package/src/manager/events/cron/daily/marketing-newsletter-generate.js +1 -1
- package/src/manager/events/cron/daily/marketing-prune.js +2 -2
- package/src/manager/events/cron/frequent/abandoned-carts.js +2 -2
- package/src/manager/events/cron/frequent/marketing-campaigns.js +1 -1
- package/src/manager/functions/_legacy/actions/create-post-handler.js +1 -1
- package/src/manager/functions/_legacy/actions/sign-up-handler.js +1 -1
- package/src/manager/functions/_legacy/admin/create-post.js +3 -3
- package/src/manager/functions/core/actions/api/test/lab.js +0 -1
- package/src/manager/index.js +24 -13
- package/src/manager/libraries/disposable-domains.json +1 -0
- package/src/manager/libraries/email/transactional/index.js +15 -11
- package/src/manager/libraries/payment/processors/stripe.js +1 -1
- package/src/manager/routes/payments/webhook/post.js +1 -1
- package/src/manager/server-manager.js +1 -1
- package/src/test/runner.js +1 -1
- package/test/helpers/storage.js +194 -0
package/CHANGELOG.md
CHANGED
|
@@ -14,6 +14,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
|
14
14
|
- `Fixed` for any bug fixes.
|
|
15
15
|
- `Security` in case of vulnerabilities.
|
|
16
16
|
|
|
17
|
+
# [5.0.194] - 2026-04-08
|
|
18
|
+
### Fixed
|
|
19
|
+
- Fix email template data merge: caller's `settings.data` is now deep-merged at root of template data tree, removing the broken `data.` prefix indirection that caused empty order confirmation emails since 5.0.185
|
|
20
|
+
### Added
|
|
21
|
+
- `preview` as a top-level setting on `email.send()` (alongside `subject`)
|
|
22
|
+
- `logs:read` CLI: `--search`, `--order`, `--filter` flags and increased default limit to 300
|
|
23
|
+
### Changed
|
|
24
|
+
- Email templates now access caller data at root (`{{order.id}}`, `{{body.message}}`) instead of under `data.*`
|
|
25
|
+
|
|
17
26
|
# [5.0.192] - 2026-04-02
|
|
18
27
|
### Added
|
|
19
28
|
- Setup test to create `hooks/auth/` and `hooks/cron/daily/` directories in consumer projects during `npx bm setup`
|
package/CLAUDE.md
CHANGED
|
@@ -736,6 +736,8 @@ The forwarding URL is: `http://localhost:{hostingPort}/backend-manager/payments/
|
|
|
736
736
|
|
|
737
737
|
Quick commands for reading/writing Firestore and managing Auth users directly from the terminal. Works in any BEM consumer project (requires `functions/service-account.json` for production, or `--emulator` for local).
|
|
738
738
|
|
|
739
|
+
**IMPORTANT: All CLI commands (`npx mgr ...` / `npx bm ...`) MUST be run from the consumer project's `functions/` subdirectory** (e.g., `cd /path/to/my-project/functions && npx mgr ...`). The `mgr` binary lives in `functions/node_modules/.bin/` — running from the project root or any other directory will fail.
|
|
740
|
+
|
|
739
741
|
### Firestore Commands
|
|
740
742
|
|
|
741
743
|
```bash
|
|
@@ -763,24 +765,63 @@ npx bm auth:set-claims <uid-or-email> '<json>' # Set custom claims
|
|
|
763
765
|
Fetch or stream Cloud Function logs from Google Cloud Logging. Requires `gcloud` CLI installed and authenticated. Auto-resolves the project ID from `service-account.json`, `.firebaserc`, or `GCLOUD_PROJECT`.
|
|
764
766
|
|
|
765
767
|
```bash
|
|
766
|
-
npx bm logs:read # Read last 1h of logs (default:
|
|
768
|
+
npx bm logs:read # Read last 1h of logs (default: 300 entries, newest first)
|
|
767
769
|
npx bm logs:read --fn bm_api # Filter by function name
|
|
768
770
|
npx bm logs:read --fn bm_api --severity ERROR # Filter by severity (DEBUG, INFO, WARNING, ERROR, CRITICAL)
|
|
769
771
|
npx bm logs:read --since 2d --limit 100 # Custom time range and limit
|
|
772
|
+
npx bm logs:read --search "72.134.242.25" # Search textPayload for a string (IP, email, error, etc.)
|
|
773
|
+
npx bm logs:read --fn bm_authBeforeCreate --search "ian@example.com" --since 7d # Combined filters
|
|
774
|
+
npx bm logs:read --order asc # Oldest first (default: desc/newest first)
|
|
775
|
+
npx bm logs:read --filter 'jsonPayload.level="error"' # Raw gcloud filter passthrough
|
|
770
776
|
npx bm logs:tail # Stream live logs
|
|
771
777
|
npx bm logs:tail --fn bm_paymentsWebhookOnWrite # Stream filtered live logs
|
|
772
778
|
```
|
|
773
779
|
|
|
774
780
|
Both commands save output to `functions/logs.log` (overwritten on each run). `logs:read` saves raw JSON; `logs:tail` streams text.
|
|
775
781
|
|
|
782
|
+
**Cloud Logs vs Local Logs:** These commands query **production** Google Cloud Logging. For **local/dev** logs, read `functions/serve.log` (from `npx bm serve`) or `functions/emulator.log` (from `npx bm test`) directly — they are plain text files, not gcloud.
|
|
783
|
+
|
|
776
784
|
| Flag | Description | Default | Commands |
|
|
777
785
|
|------|-------------|---------|----------|
|
|
778
|
-
| `--fn <name>` | Filter by Cloud Function name | all | both |
|
|
779
|
-
| `--severity <level>` | Minimum severity
|
|
786
|
+
| `--fn <name>` | Filter by Cloud Function name (see table below) | all | both |
|
|
787
|
+
| `--severity <level>` | Minimum severity: `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL` | all | both |
|
|
788
|
+
| `--search <text>` | Search textPayload for a substring (IP, email, uid, error message) | none | both |
|
|
789
|
+
| `--filter <expr>` | Raw gcloud logging filter expression (appended to built-in filters) | none | both |
|
|
780
790
|
| `--since <duration>` | Time range (`30m`, `1h`, `2d`, `1w`) | `1h` | read only |
|
|
781
|
-
| `--limit <n>` | Max entries | `
|
|
791
|
+
| `--limit <n>` | Max entries | `300` | read only |
|
|
792
|
+
| `--order <dir>` | Sort order: `asc` (oldest first) or `desc` (newest first) | `desc` | read only |
|
|
793
|
+
| `--interval <sec>` | Polling interval in seconds | `5` | tail only |
|
|
782
794
|
| `--raw` | Output raw JSON | false | both |
|
|
783
795
|
|
|
796
|
+
#### `--fn` Function Name Reference
|
|
797
|
+
|
|
798
|
+
The `--fn` flag uses the **deployed Cloud Function name**, not the route path.
|
|
799
|
+
|
|
800
|
+
**BEM built-in functions (always deployed):**
|
|
801
|
+
|
|
802
|
+
| Function name | Type | Description |
|
|
803
|
+
|---------------|------|-------------|
|
|
804
|
+
| `bm_api` | HTTPS | Main API router — all consumer routes (GET/POST/PUT/DELETE) go through this |
|
|
805
|
+
| `bm_authBeforeCreate` | Auth blocking | Before user creation: disposable email blocking, IP rate limiting, consumer hooks |
|
|
806
|
+
| `bm_authBeforeSignIn` | Auth blocking | Before sign-in: consumer hooks |
|
|
807
|
+
| `bm_authOnCreate` | Auth event | After user creation: user doc setup |
|
|
808
|
+
| `bm_authOnDelete` | Auth event | After user deletion |
|
|
809
|
+
| `bm_paymentsWebhookOnWrite` | Firestore trigger | Processes payment webhooks |
|
|
810
|
+
| `bm_paymentsDisputeOnWrite` | Firestore trigger | Processes payment disputes |
|
|
811
|
+
| `bm_notificationsOnWrite` | Firestore trigger | Sends push notifications |
|
|
812
|
+
| `bm_cronDaily` | Scheduled | Daily cron (midnight UTC) |
|
|
813
|
+
| `bm_cronFrequent` | Scheduled | Frequent cron (every 10 min) |
|
|
814
|
+
|
|
815
|
+
**Consumer-defined functions** use the export name from `functions/index.js` (e.g., `exports.items = ...` → `--fn items`).
|
|
816
|
+
|
|
817
|
+
**Quick lookup — which function to query:**
|
|
818
|
+
- API route errors → `--fn bm_api`
|
|
819
|
+
- Signup/auth blocked → `--fn bm_authBeforeCreate`
|
|
820
|
+
- Sign-in issues → `--fn bm_authBeforeSignIn`
|
|
821
|
+
- User doc not created → `--fn bm_authOnCreate`
|
|
822
|
+
- Payment not processing → `--fn bm_paymentsWebhookOnWrite`
|
|
823
|
+
- Cron job issues → `--fn bm_cronDaily` or `--fn bm_cronFrequent`
|
|
824
|
+
|
|
784
825
|
### Shared Flags
|
|
785
826
|
|
|
786
827
|
| Flag | Description |
|
package/TODO-2.md
CHANGED
|
@@ -23,6 +23,26 @@ waht about when they request a cancel
|
|
|
23
23
|
Read cancellation-requested.js
|
|
24
24
|
The category is order/cancellation-requested (line 13).
|
|
25
25
|
|
|
26
|
+
----
|
|
27
|
+
add a dedicated BEM JSON field for usage to reset
|
|
28
|
+
* this way we can have clear LIMITS with their definitions like
|
|
29
|
+
* [
|
|
30
|
+
{
|
|
31
|
+
name: 'credits'
|
|
32
|
+
reset: true,
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: 'agents',
|
|
36
|
+
reset: false,
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
* mirrors: [
|
|
40
|
+
{
|
|
41
|
+
collection: 'agents',
|
|
42
|
+
fields: ['usage.credits.daily', 'runs.replies.daily],
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
|
|
26
46
|
---
|
|
27
47
|
MIRROR settigns in BEM JSON so that usage reset can properly get MIRRED DOCS liek slapform forms or chatsy agents DOCS
|
|
28
48
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "backend-manager",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.194",
|
|
4
4
|
"description": "Quick tools for developing Firebase functions",
|
|
5
5
|
"main": "src/manager/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -43,60 +43,55 @@
|
|
|
43
43
|
"preparePackage": {
|
|
44
44
|
"input": "./src_",
|
|
45
45
|
"output": "./dist_",
|
|
46
|
-
"replace": {}
|
|
46
|
+
"replace": {},
|
|
47
|
+
"type": "copy"
|
|
47
48
|
},
|
|
48
49
|
"dependencies": {
|
|
49
50
|
"@firebase/rules-unit-testing": "^5.0.0",
|
|
50
51
|
"@google-cloud/pubsub": "^5.3.0",
|
|
51
52
|
"@google-cloud/storage": "^7.19.0",
|
|
53
|
+
"@inquirer/prompts": "^8.4.1",
|
|
52
54
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
53
|
-
"@octokit/rest": "^
|
|
55
|
+
"@octokit/rest": "^22.0.1",
|
|
54
56
|
"@sendgrid/mail": "^8.1.6",
|
|
55
|
-
"@sentry/node": "^
|
|
56
|
-
"body-parser": "^
|
|
57
|
+
"@sentry/node": "^10.47.0",
|
|
58
|
+
"body-parser": "^2.2.2",
|
|
57
59
|
"busboy": "^1.6.0",
|
|
58
|
-
"chalk": "^
|
|
60
|
+
"chalk": "^5.6.2",
|
|
59
61
|
"cors": "^2.8.6",
|
|
60
|
-
"dotenv": "^
|
|
61
|
-
"express": "^
|
|
62
|
+
"dotenv": "^17.4.1",
|
|
63
|
+
"express": "^5.2.1",
|
|
62
64
|
"fs-jetpack": "^5.1.0",
|
|
63
|
-
"glob": "^
|
|
65
|
+
"glob": "^13.0.6",
|
|
64
66
|
"hcaptcha": "^0.2.0",
|
|
65
|
-
"inquirer": "^8.2.7",
|
|
66
67
|
"itwcw-package-analytics": "^1.0.8",
|
|
67
68
|
"json5": "^2.2.3",
|
|
68
69
|
"jwt-decode": "^4.0.0",
|
|
69
|
-
"lodash": "^4.
|
|
70
|
-
"lowdb": "^
|
|
70
|
+
"lodash": "^4.18.1",
|
|
71
|
+
"lowdb": "^7.0.1",
|
|
71
72
|
"mailchimp-api-v3": "^1.15.0",
|
|
72
73
|
"markdown-it": "^14.1.1",
|
|
73
|
-
"mime-types": "^
|
|
74
|
-
"mocha": "^11.7.5",
|
|
74
|
+
"mime-types": "^3.0.2",
|
|
75
75
|
"moment": "^2.30.1",
|
|
76
|
-
"nanoid": "^
|
|
77
|
-
"node-
|
|
78
|
-
"node-powertools": "^2.3.2",
|
|
76
|
+
"nanoid": "^5.1.7",
|
|
77
|
+
"node-powertools": "^3.0.0",
|
|
79
78
|
"npm-api": "^1.0.1",
|
|
80
|
-
"paypal-server-api": "^2.0.14",
|
|
81
79
|
"pushid": "^1.0.0",
|
|
82
80
|
"sanitize-html": "^2.17.2",
|
|
83
|
-
"
|
|
84
|
-
"stripe": "^20.3.1",
|
|
81
|
+
"stripe": "^22.0.0",
|
|
85
82
|
"uid-generator": "^2.0.0",
|
|
86
|
-
"uuid": "^
|
|
87
|
-
"wonderful-fetch": "^
|
|
83
|
+
"uuid": "^13.0.0",
|
|
84
|
+
"wonderful-fetch": "^2.0.5",
|
|
88
85
|
"wonderful-log": "^1.0.7",
|
|
89
86
|
"wonderful-version": "^1.3.2",
|
|
90
|
-
"yaml": "^2.8.
|
|
91
|
-
"yargs": "^
|
|
87
|
+
"yaml": "^2.8.3",
|
|
88
|
+
"yargs": "^18.0.0"
|
|
92
89
|
},
|
|
93
90
|
"devDependencies": {
|
|
94
|
-
"
|
|
95
|
-
"prepare-package": "^1.2.6",
|
|
96
|
-
"sinon": "^21.0.1"
|
|
91
|
+
"prepare-package": "^2.0.8"
|
|
97
92
|
},
|
|
98
93
|
"peerDependencies": {
|
|
99
|
-
"firebase-admin": "^13.
|
|
100
|
-
"firebase-functions": "^7.
|
|
94
|
+
"firebase-admin": "^13.7.0",
|
|
95
|
+
"firebase-functions": "^7.2.3"
|
|
101
96
|
}
|
|
102
97
|
}
|
package/src/cli/commands/auth.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const BaseCommand = require('./base-command');
|
|
2
|
-
const chalk = require('chalk');
|
|
3
|
-
const
|
|
2
|
+
const chalk = require('chalk').default;
|
|
3
|
+
const { confirm } = require('@inquirer/prompts');
|
|
4
4
|
const { initFirebase } = require('./firebase-init');
|
|
5
5
|
|
|
6
6
|
class AuthCommand extends BaseCommand {
|
|
@@ -148,12 +148,10 @@ class AuthCommand extends BaseCommand {
|
|
|
148
148
|
|
|
149
149
|
// Require confirmation for production (skip for emulator or --force)
|
|
150
150
|
if (!isEmulator && !argv.force) {
|
|
151
|
-
const
|
|
152
|
-
type: 'confirm',
|
|
153
|
-
name: 'confirmed',
|
|
151
|
+
const confirmed = await confirm({
|
|
154
152
|
message: `Delete user "${user.uid}" (${user.email || 'no email'}) from PRODUCTION?`,
|
|
155
153
|
default: false,
|
|
156
|
-
}
|
|
154
|
+
});
|
|
157
155
|
|
|
158
156
|
if (!confirmed) {
|
|
159
157
|
this.log(chalk.gray(' Aborted.'));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const chalk = require('chalk');
|
|
2
|
-
const
|
|
1
|
+
const chalk = require('chalk').default;
|
|
2
|
+
const { confirm } = require('@inquirer/prompts');
|
|
3
3
|
const { execSync, spawn } = require('child_process');
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const jetpack = require('fs-jetpack');
|
|
@@ -63,12 +63,10 @@ class BaseCommand {
|
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
const
|
|
67
|
-
type: 'confirm',
|
|
68
|
-
name: 'shouldKill',
|
|
66
|
+
const shouldKill = await confirm({
|
|
69
67
|
message: 'Kill these processes to free the ports?',
|
|
70
68
|
default: true,
|
|
71
|
-
}
|
|
69
|
+
});
|
|
72
70
|
|
|
73
71
|
if (!shouldKill) {
|
|
74
72
|
this.log(chalk.gray('\n Aborting. Free the ports and try again.\n'));
|
|
@@ -174,7 +172,7 @@ class BaseCommand {
|
|
|
174
172
|
// Load .env so STRIPE_SECRET_KEY and BACKEND_MANAGER_KEY are available
|
|
175
173
|
const envPath = path.join(functionsDir, '.env');
|
|
176
174
|
if (jetpack.exists(envPath)) {
|
|
177
|
-
require('dotenv').config({ path: envPath });
|
|
175
|
+
require('dotenv').config({ path: envPath, quiet: true });
|
|
178
176
|
}
|
|
179
177
|
|
|
180
178
|
// Check for Stripe secret key
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const BaseCommand = require('./base-command');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const fs = require('fs');
|
|
4
|
-
const chalk = require('chalk');
|
|
4
|
+
const chalk = require('chalk').default;
|
|
5
5
|
const jetpack = require('fs-jetpack');
|
|
6
6
|
const JSON5 = require('json5');
|
|
7
7
|
const powertools = require('node-powertools');
|
|
@@ -17,7 +17,7 @@ function initFirebase({ firebaseProjectPath, emulator }) {
|
|
|
17
17
|
// Load .env so env vars like GCLOUD_PROJECT are available
|
|
18
18
|
const envPath = path.join(functionsDir, '.env');
|
|
19
19
|
if (jetpack.exists(envPath)) {
|
|
20
|
-
require('dotenv').config({ path: envPath });
|
|
20
|
+
require('dotenv').config({ path: envPath, quiet: true });
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
// Resolve firebase-admin from the consumer project's node_modules (peer dep)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const BaseCommand = require('./base-command');
|
|
2
|
-
const chalk = require('chalk');
|
|
3
|
-
const
|
|
2
|
+
const chalk = require('chalk').default;
|
|
3
|
+
const { confirm } = require('@inquirer/prompts');
|
|
4
4
|
const { initFirebase } = require('./firebase-init');
|
|
5
5
|
|
|
6
6
|
class FirestoreCommand extends BaseCommand {
|
|
@@ -175,12 +175,10 @@ class FirestoreCommand extends BaseCommand {
|
|
|
175
175
|
|
|
176
176
|
// Require confirmation for production (skip for emulator or --force)
|
|
177
177
|
if (!isEmulator && !argv.force) {
|
|
178
|
-
const
|
|
179
|
-
type: 'confirm',
|
|
180
|
-
name: 'confirmed',
|
|
178
|
+
const confirmed = await confirm({
|
|
181
179
|
message: `Delete document "${docPath}" from PRODUCTION?`,
|
|
182
180
|
default: false,
|
|
183
|
-
}
|
|
181
|
+
});
|
|
184
182
|
|
|
185
183
|
if (!confirmed) {
|
|
186
184
|
this.log(chalk.gray(' Aborted.'));
|
package/src/cli/commands/logs.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const BaseCommand = require('./base-command');
|
|
2
|
-
const chalk = require('chalk');
|
|
2
|
+
const chalk = require('chalk').default;
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const { execSync, spawn } = require('child_process');
|
|
5
5
|
const path = require('path');
|
|
@@ -56,11 +56,12 @@ class LogsCommand extends BaseCommand {
|
|
|
56
56
|
|
|
57
57
|
/**
|
|
58
58
|
* Fetch historical logs.
|
|
59
|
-
* Usage: npx bm logs:read [--fn bm_api] [--severity ERROR] [--since 1h] [--limit 300]
|
|
59
|
+
* Usage: npx bm logs:read [--fn bm_api] [--severity ERROR] [--since 1h] [--limit 300] [--search "text"] [--order desc] [--filter 'raw gcloud filter']
|
|
60
60
|
*/
|
|
61
61
|
async read(projectId, argv) {
|
|
62
62
|
const filter = this.buildFilter(argv);
|
|
63
63
|
const limit = parseInt(argv.limit, 10) || 300;
|
|
64
|
+
const order = argv.order || 'desc';
|
|
64
65
|
|
|
65
66
|
const cmd = [
|
|
66
67
|
'gcloud', 'logging', 'read',
|
|
@@ -68,7 +69,7 @@ class LogsCommand extends BaseCommand {
|
|
|
68
69
|
`--project=${projectId}`,
|
|
69
70
|
`--limit=${limit}`,
|
|
70
71
|
'--format=json',
|
|
71
|
-
|
|
72
|
+
`--order=${order}`,
|
|
72
73
|
].filter(Boolean).join(' ');
|
|
73
74
|
|
|
74
75
|
// Set up log file in the project directory
|
|
@@ -83,7 +84,7 @@ class LogsCommand extends BaseCommand {
|
|
|
83
84
|
const output = execSync(cmd, {
|
|
84
85
|
encoding: 'utf8',
|
|
85
86
|
maxBuffer: 10 * 1024 * 1024, // 10MB
|
|
86
|
-
timeout:
|
|
87
|
+
timeout: 60000,
|
|
87
88
|
});
|
|
88
89
|
|
|
89
90
|
const entries = JSON.parse(output || '[]');
|
|
@@ -233,6 +234,16 @@ class LogsCommand extends BaseCommand {
|
|
|
233
234
|
parts.push(`severity>=${argv.severity.toUpperCase()}`);
|
|
234
235
|
}
|
|
235
236
|
|
|
237
|
+
// Text search filter (searches textPayload)
|
|
238
|
+
if (argv.search) {
|
|
239
|
+
parts.push(`textPayload:"${argv.search}"`);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Raw filter passthrough (appended as-is)
|
|
243
|
+
if (argv.filter) {
|
|
244
|
+
parts.push(argv.filter);
|
|
245
|
+
}
|
|
246
|
+
|
|
236
247
|
// Timestamp filter (read only, not tail)
|
|
237
248
|
if (!options.excludeTimestamp) {
|
|
238
249
|
const since = argv.since || '1h';
|
package/src/cli/commands/mcp.js
CHANGED
|
@@ -10,7 +10,7 @@ class McpCommand extends BaseCommand {
|
|
|
10
10
|
const jetpack = require('fs-jetpack');
|
|
11
11
|
const envPath = path.join(functionsDir, '.env');
|
|
12
12
|
if (jetpack.exists(envPath)) {
|
|
13
|
-
require('dotenv').config({ path: envPath });
|
|
13
|
+
require('dotenv').config({ path: envPath, quiet: true });
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
// Resolve the BEM server URL
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const BaseCommand = require('./base-command');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const fs = require('fs');
|
|
4
|
-
const chalk = require('chalk');
|
|
4
|
+
const chalk = require('chalk').default;
|
|
5
5
|
const powertools = require('node-powertools');
|
|
6
6
|
const WatchCommand = require('./watch');
|
|
7
7
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const BaseTest = require('./base-test');
|
|
2
2
|
const jetpack = require('fs-jetpack');
|
|
3
|
-
const chalk = require('chalk');
|
|
3
|
+
const chalk = require('chalk').default;
|
|
4
4
|
const powertools = require('node-powertools');
|
|
5
5
|
const _ = require('lodash');
|
|
6
6
|
const helpers = require('./helpers');
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const BaseTest = require('./base-test');
|
|
2
2
|
const jetpack = require('fs-jetpack');
|
|
3
3
|
const _ = require('lodash');
|
|
4
|
-
const chalk = require('chalk');
|
|
4
|
+
const chalk = require('chalk').default;
|
|
5
5
|
const requiredIndexes = require('./helpers/required-indexes');
|
|
6
6
|
|
|
7
7
|
class FirestoreIndexesRequiredTest extends BaseTest {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const BaseTest = require('./base-test');
|
|
2
2
|
const jetpack = require('fs-jetpack');
|
|
3
|
-
const chalk = require('chalk');
|
|
3
|
+
const chalk = require('chalk').default;
|
|
4
4
|
|
|
5
5
|
const bem_allRulesRegex = /(\/\/\/---backend-manager---\/\/\/)(.*?)(\/\/\/---------end---------\/\/\/)/sgm;
|
|
6
6
|
const bem_allRulesBackupRegex = /({{\s*?backend-manager\s*?}})/sgm;
|
|
@@ -36,7 +36,7 @@ const RemoteconfigTemplateFileTest = require('./remoteconfig-template-file');
|
|
|
36
36
|
const HostingFolderTest = require('./hosting-folder');
|
|
37
37
|
const PublicHtmlFilesTest = require('./public-html-files');
|
|
38
38
|
const FirestoreIndexesRequiredTest = require('./firestore-indexes-required');
|
|
39
|
-
const
|
|
39
|
+
const ProjectDirectoriesTest = require('./project-directories');
|
|
40
40
|
const LegacyTestsCleanupTest = require('./legacy-tests-cleanup');
|
|
41
41
|
const MarketingCampaignsSeededTest = require('./marketing-campaigns-seeded');
|
|
42
42
|
|
|
@@ -79,7 +79,7 @@ function getTests(context) {
|
|
|
79
79
|
new RemoteconfigTemplateFileTest(context),
|
|
80
80
|
new HostingFolderTest(context),
|
|
81
81
|
new PublicHtmlFilesTest(context),
|
|
82
|
-
new
|
|
82
|
+
new ProjectDirectoriesTest(context),
|
|
83
83
|
new LegacyTestsCleanupTest(context),
|
|
84
84
|
new MarketingCampaignsSeededTest(context),
|
|
85
85
|
];
|
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
const BaseTest = require('./base-test');
|
|
2
2
|
const jetpack = require('fs-jetpack');
|
|
3
3
|
|
|
4
|
-
const
|
|
4
|
+
const DIRS = [
|
|
5
|
+
'routes',
|
|
6
|
+
'schemas',
|
|
5
7
|
'hooks/auth',
|
|
6
8
|
'hooks/cron/daily',
|
|
7
9
|
];
|
|
8
10
|
|
|
9
|
-
class
|
|
11
|
+
class ProjectDirectoriesTest extends BaseTest {
|
|
10
12
|
getName() {
|
|
11
|
-
return '
|
|
13
|
+
return 'project directories exist';
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
async run() {
|
|
15
17
|
const self = this.self;
|
|
16
18
|
const functionsDir = `${self.firebaseProjectPath}/functions`;
|
|
17
19
|
|
|
18
|
-
for (const dir of
|
|
20
|
+
for (const dir of DIRS) {
|
|
19
21
|
jetpack.dir(`${functionsDir}/${dir}`);
|
|
20
22
|
}
|
|
21
23
|
|
|
@@ -27,4 +29,4 @@ class HooksDirectoriesTest extends BaseTest {
|
|
|
27
29
|
}
|
|
28
30
|
}
|
|
29
31
|
|
|
30
|
-
module.exports =
|
|
32
|
+
module.exports = ProjectDirectoriesTest;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const BaseTest = require('./base-test');
|
|
2
2
|
const jetpack = require('fs-jetpack');
|
|
3
3
|
const JSON5 = require('json5');
|
|
4
|
-
const chalk = require('chalk');
|
|
4
|
+
const chalk = require('chalk').default;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Ensures projectId is consistent across all configuration files:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const BaseTest = require('./base-test');
|
|
2
2
|
const jetpack = require('fs-jetpack');
|
|
3
|
-
const chalk = require('chalk');
|
|
3
|
+
const chalk = require('chalk').default;
|
|
4
4
|
|
|
5
5
|
const bem_allRulesRegex = /(\/\/\/---backend-manager---\/\/\/)(.*?)(\/\/\/---------end---------\/\/\/)/sgm;
|
|
6
6
|
const bem_allRulesBackupRegex = /({{\s*?backend-manager\s*?}})/sgm;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const BaseTest = require('./base-test');
|
|
2
2
|
const powertools = require('node-powertools');
|
|
3
3
|
const path = require('path');
|
|
4
|
-
const chalk = require('chalk');
|
|
4
|
+
const chalk = require('chalk').default;
|
|
5
5
|
|
|
6
6
|
class StorageLifecyclePolicyTest extends BaseTest {
|
|
7
7
|
getName() {
|