smoonb 1.0.13 → 1.0.14

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/README.md CHANGED
@@ -1,695 +1,695 @@
1
- # Supa Moonbase (smoonb)
2
-
3
- **Complete Supabase backup and migration tool**
4
-
5
- Backup and restore: complete and simple, as it should be
6
-
7
- > **Commercial product.** You need an **active license** and a **valid subscription** (or be on a trial period) to use smoonb. [www.smoonb.com/#price](https://www.smoonb.com/#price). Use is governed by the [Terms of Service](https://www.smoonb.com/terms) and [Privacy Policy](https://www.smoonb.com/privacy). We do not assume any liability for damage caused by smoonb; the legal disclaimers below remain in effect.
8
-
9
- **Read this in other languages:** [Português (Brasil)](README.pt-BR.md)
10
-
11
- **Developed by:** Goalmoon Tecnologia LTDA
12
- **Website:** https://www.smoonb.com
13
- **GitHub:** https://github.com/almmello/smoonb
14
-
15
- ## 🎯 Objective
16
-
17
- **smoonb** solves the problem of existing tools that only backup the PostgreSQL database, ignoring critical Supabase components.
18
-
19
- ## 📦 Backup Components
20
-
21
- smoonb performs a complete backup of all components of your Supabase project:
22
-
23
- - ✅ **Database PostgreSQL** (backup completo via `pg_dumpall` + SQL separados, idêntico ao Dashboard)
24
- - ✅ **Database Extensions and Settings** (extensões PostgreSQL e configurações)
25
- - ✅ **Custom Roles** (roles personalizados do PostgreSQL)
26
- - ✅ **Edge Functions** (download automático do servidor)
27
- - ✅ **Auth Settings** (configurações de autenticação via Management API)
28
- - ✅ **Storage Buckets** (backup completo: metadados, configurações e todos os arquivos via Management API + Supabase Client, cria ZIP no padrão do Dashboard)
29
- - ✅ **Realtime Settings** (current settings captured through the Management API)
30
- - ✅ **Supabase .temp** (arquivos temporários do Supabase CLI)
31
- - ✅ **Migrations** (todas as migrations do projeto via `supabase migration fetch`)
32
-
33
- ## ⚠️ Universal Disclaimer / Legal Notice
34
-
35
- By continuing, you acknowledge and agree that Supa Moonbase (smoonb) is provided "AS IS" and "AS AVAILABLE", with no warranties of any kind—express, implied, or statutory—including but not limited to merchantability, fitness for a particular purpose, and non-infringement, to the maximum extent permitted by applicable law. Backup and restore operations inherently carry risk, environments vary widely, and we cannot foresee or validate all user setups. You are solely responsible for validating your own environment, keeping independent copies, and verifying results before relying on them in production. We build Supa Moonbase (smoonb) on public, auditable, open-source repositories to help people simplify their workflows, but this does not create any warranty, promise of support, or service-level commitment.
36
-
37
- **Limitation of liability** — To the maximum extent permitted by law, Goalmoon Tecnologia LTDA, its contributors, and licensors will not be liable for any indirect, incidental, special, consequential, exemplary, or punitive damages (including loss of data, interruption of business, or lost profits) arising from or related to the use of, inability to use, backup/restore operations performed by, or results produced by Supa Moonbase (smoonb).
38
-
39
- ## 🚀 Installation
40
-
41
- **⚠️ IMPORTANT: Install ONLY locally in the project!**
42
-
43
- **Install locally in the project:**
44
- ```bash
45
- npm install smoonb
46
- ```
47
-
48
- **Use with npx:**
49
- ```bash
50
- npx smoonb --help
51
- ```
52
-
53
- **Do not install globally** (blocked):
54
- ```bash
55
- npm install -g smoonb
56
- ```
57
-
58
- ### 🔄 Update to Latest Version
59
-
60
- To update smoonb to the latest available version, run in the current project:
61
-
62
- ```bash
63
- npm install smoonb@latest
64
- ```
65
-
66
- **⚠️ IMPORTANT:** smoonb must be installed locally in the project. Using without installing (e.g., `npx smoonb@latest`) is not allowed.
67
-
68
- **💡 Why local only?**
69
- - **🔒 Security**: Avoids version conflicts
70
- - **📦 Isolation**: Each project uses its own version
71
- - **🔄 Updates**: Granular control per project
72
- - **🛡️ Stability**: Prevents breaking other projects
73
-
74
- ## 📋 Prerequisites
75
-
76
- ### 1. Docker Desktop (REQUIRED)
77
-
78
- Install from [Docker Desktop](https://docs.docker.com/desktop/install/) (Windows/macOS) or [Docker Engine](https://docs.docker.com/engine/install/) (Linux). Then verify it is running:
79
-
80
- ```bash
81
- docker --version
82
- docker ps
83
- ```
84
-
85
- **⚠️ IMPORTANT:** Docker is required for:
86
- - Database backup via `pg_dumpall` (compatible with Supabase Dashboard)
87
- - Compression of `.backup.gz` files
88
- - Restoration of `.backup` and `.backup.gz` backups
89
-
90
- ### 2. Supabase CLI
91
- ```bash
92
- npm install -g supabase
93
- ```
94
-
95
- **Version policy:** smoonb accepts any Supabase CLI version that is **at most 1 minor behind the latest** (same major). We recommend always using the latest version. Versions that are too old are blocked with an error message.
96
-
97
- If your package manager (e.g. **Scoop** on Windows) lags behind on updates and you want to proceed anyway, use the `--skip-supabase-version-check` flag (see usage section below).
98
-
99
- To update the Supabase CLI: [Updating the Supabase CLI](https://supabase.com/docs/guides/cli/getting-started#updating-the-supabase-cli).
100
-
101
- ### 3. Supabase Personal Access Token
102
- You need to obtain a Supabase personal access token to use the Management API:
103
-
104
- 1. Visit: https://supabase.com/dashboard/account/tokens
105
- 2. Click "Generate new token"
106
- 3. Copy the token (format: `sbp_...`)
107
- 4. Add to `.env.local` as `SUPABASE_ACCESS_TOKEN`
108
-
109
- ### 4. License Key (REQUIRED for backup and restore)
110
- **smoonb** requires a valid license to run backup and restore:
111
-
112
- 1. Get your license from the desktop app at https://www.smoonb.com
113
- 2. Set in environment or `.env.local`: `SMOONB_LICENSE_KEY=[your-license-key]`
114
- 3. License is validated at the start of each run (step 00); no caching. If validation fails (network/server), the CLI aborts. The license is **not** shown in the interactive variable-mapping wizard (it is already validated before that).
115
-
116
- ## ⚙️ Configuration
117
-
118
- ### Modern Method: `.env.local` (RECOMMENDED)
119
-
120
- **smoonb** now uses `.env.local` for configuration, following industry standards. This makes the process simpler and more integrated with your workflow.
121
-
122
- #### 1. Create or edit `.env.local` in the project root
123
-
124
- ```bash
125
- touch .env.local
126
- ```
127
-
128
- #### 2. Add required environment variables
129
-
130
- ```env
131
- SMOONB_LICENSE_KEY=[your-license-key]
132
- NEXT_PUBLIC_SUPABASE_URL=[your-supabase-url]
133
- NEXT_PUBLIC_SUPABASE_ANON_KEY=[your-anon-key]
134
- SUPABASE_SERVICE_ROLE_KEY=[your-service-role]
135
- SUPABASE_DB_URL=postgresql://postgres:[your-database-password]@db.[your-project-id].supabase.co:5432/postgres
136
- SUPABASE_PROJECT_ID=[your-project-id]
137
- SUPABASE_ACCESS_TOKEN=[your-access-token]
138
- SUPABASE_POSTGRES_MAJOR=17
139
- SMOONB_TELEMETRY_ENABLED=true
140
- SMOONB_OUTPUT_DIR=./backups
141
- ```
142
-
143
- Required: `SMOONB_LICENSE_KEY` (from [www.smoonb.com](https://www.smoonb.com) desktop app), `SUPABASE_POSTGRES_MAJOR` (e.g. 17; see Dashboard → Project Settings → Infrastructure → Service Versions). Optional: `SMOONB_TELEMETRY_ENABLED`, `SMOONB_OUTPUT_DIR` (default `./backups`).
144
-
145
- #### 3. Interactive Mapping
146
-
147
- When running `backup` or `restore` for the first time, **smoonb** will:
148
-
149
- 1. **Read** your current `.env.local`
150
- 2. **Identify** the keys you already have
151
- 3. **Ask interactively** which keys correspond to the expected ones (if names are different)
152
- 4. **Add** missing keys if necessary
153
- 5. **Create automatic backup** of `.env.local` before any changes
154
- 6. **Save mapping** for future executions
155
-
156
- **Mapping example:**
157
- ```
158
- 🔧 Mapping variable: NEXT_PUBLIC_SUPABASE_URL
159
- Current value: https://abc123.supabase.co
160
- Is this the correct value for the target project? (Y/n): Y
161
- ```
162
-
163
- ## 🌐 Internationalization (i18n)
164
-
165
- **smoonb** supports multiple languages automatically. Currently supported languages are:
166
-
167
- - **English (en)** - Default language
168
- - **Portuguese (Brazil) (pt-BR)** - Full support
169
-
170
- ### Automatic Language Detection
171
-
172
- Language is detected automatically in the following order of precedence:
173
-
174
- 1. **Environment variable `SMOONB_LANG`** (in `.env.local` or in the environment)
175
- 2. **System locale** (LANG, LC_ALL, LC_MESSAGES). Example: `LANG=pt_BR.UTF-8` → pt-BR
176
- 3. **Fallback to English (en)** if none of the above are detected
177
-
178
- ### Supported Languages and Aliases
179
-
180
- - `en` or `en-US` → English
181
- - `pt-BR`, `pt_BR` or `pt` → Portuguese (Brazil)
182
-
183
- ### Important Notes
184
-
185
- - **Machine outputs** (e.g., `--json` if implemented) are **not** translated; fields and keys remain in English
186
- - If a translation key is missing in a language, the system automatically **falls back to English**
187
- - Language is detected once at the start of execution and applied to all CLI messages
188
-
189
- ## 🎯 Usage
190
-
191
- ### Full Backup
192
-
193
- ```bash
194
- npx smoonb backup
195
- ```
196
-
197
- **Available options:**
198
-
199
- | Flag | Description |
200
- |------|-------------|
201
- | `--skip-supabase-version-check` | Skips the Supabase CLI version check. Use when your package manager (e.g. Scoop) lags behind on updates. A warning is shown and the user assumes the risk. |
202
-
203
- **Example with flag:**
204
- ```bash
205
- npx smoonb backup --skip-supabase-version-check
206
- ```
207
-
208
- **Interactive backup flow:**
209
-
210
- 1. **Terms of use** - Displays and requests acceptance of terms
211
- 2. **License validation** - Validates `SMOONB_LICENSE_KEY` (env or prompt); no cache; aborts if validation fails
212
- 3. **Docker validation** - Verifies if Docker is running
213
- 4. **Consent** - Asks permission to read/write `.env.local`
214
- 5. **Variable mapping** - Maps your environment variables (first time; license is not in the wizard—already validated)
215
- 6. **.env.local backup** - Creates automatic backup before changes
216
- 7. **Component selection** - Asks which components to include:
217
- - ⚡ Edge Functions (explanation about link reset and download)
218
- - 📦 Storage (explanation about full backup: file download + ZIP in Dashboard format)
219
- - 🔐 Auth Settings (explanation about configurations)
220
- - 🔄 Realtime Settings (current configuration captured through the API)
221
- - 🗑️ Cleanup options (functions, .temp, migrations after backup)
222
- 8. **Configuration summary** - Shows everything that will be done
223
- 9. **Final confirmation** - Confirms before starting
224
- 10. **Step execution:**
225
- - 📊 1/10 - Database Backup via `pg_dumpall` (Docker)
226
- - 📊 2/10 - Separate Database SQL (schema, data, roles)
227
- - 🔧 3/10 - Database Extensions and Settings Backup
228
- - 🔐 4/10 - Auth Settings Backup (if selected)
229
- - 🔄 5/10 - Realtime Settings Backup (if selected) - fresh API snapshot
230
- - 📦 6/10 - Storage Backup (if selected) - Full file download + ZIP in Dashboard format
231
- - 👥 7/10 - Custom Roles Backup
232
- - ⚡ 8/10 - Edge Functions Backup (if selected)
233
- - 📁 9/10 - Supabase .temp Backup (if selected)
234
- - 📋 10/10 - Migrations Backup (if selected)
235
-
236
- **Result:** A folder `backups/backup-YYYY-MM-DD-HH-MM-SS/` containing for example:
237
-
238
- ```
239
- backups/backup-2025-10-31-09-37-54/
240
- ├── backup-manifest.json
241
- ├── db_cluster-31-10-2025@09-38-57.backup.gz
242
- ├── schema.sql
243
- ├── data.sql
244
- ├── roles.sql
245
- ├── database-settings-*.json
246
- ├── auth-settings.json
247
- ├── realtime-settings.json
248
- ├── storage/
249
- │ └── [bucket-name].json
250
- ├── [project-id].storage.zip
251
- ├── storage_temp/
252
- │ └── [project-id]/
253
- │ └── [bucket-name]/
254
- ├── edge-functions/
255
- │ └── [function-name]/
256
- ├── supabase-temp/
257
- ├── migrations/
258
- └── env/
259
- ├── .env.local
260
- └── env-map.json
261
- ```
262
-
263
- ### Interactive Restoration
264
-
265
- **Restore existing backup:**
266
- ```bash
267
- npx smoonb restore
268
- ```
269
-
270
- **Available options:**
271
-
272
- | Flag | Description |
273
- |------|-------------|
274
- | `--skip-supabase-version-check` | Skips the Supabase CLI version check. Use when your package manager (e.g. Scoop) lags behind on updates. A warning is shown and the user assumes the risk. |
275
-
276
- **Example with flag:**
277
- ```bash
278
- npx smoonb restore --skip-supabase-version-check
279
- ```
280
-
281
- **Interactive restore flow:**
282
-
283
- 1. **Terms of use** - Displays and requests acceptance of terms
284
- 2. **License validation** - Validates `SMOONB_LICENSE_KEY` (env or prompt); aborts if validation fails
285
- 3. **Docker validation** - Verifies if Docker is running
286
- 4. **Consent** - Asks permission to read/write `.env.local`
287
- 5. **Variable mapping** - Maps variables to target project (includes `SUPABASE_POSTGRES_MAJOR`)
288
- 6. **.env.local backup** - Creates automatic backup
289
- 7. **Backup selection** - Lists and allows choosing which backup to restore
290
- 8. **Component selection** - Asks which components to restore:
291
- - 📊 Database (always available)
292
- - ⚡ Edge Functions (if available in backup)
293
- - 🔐 Auth Settings (if available in backup)
294
- - 📦 Storage (if available in backup)
295
- - 🔧 Database Extensions and Settings (if available in backup)
296
- - 🔄 Realtime Settings (if available in backup)
297
- 9. **Detailed summary** - Shows selected backup, target project and components
298
- 10. **Final confirmation** - Confirms before starting
299
- 11. **Project URLs** - Confirms whether Supabase URLs in data and files should point to the new project
300
- 12. **Restore execution:**
301
- - 📊 Database - Restores via `psql` (supports `.backup.gz` and `.backup`)
302
- - ⚡ Edge Functions - Deploys from a temporary copy, preserving local sources
303
- - 🔐 Auth Settings - Applies via API and verifies the resulting values
304
- - 📦 Storage - Restores buckets and ZIP files, preserves metadata and verifies every download
305
- - 🔧 Database Settings - Restores extensions and settings via SQL
306
- - 🔄 Realtime Settings - Applies and verifies the snapshot recorded in the backup
307
-
308
- ### Verified restoration (1.0.8)
309
-
310
- Use a new, empty destination project and Node.js 20 or later. Existing complete 1.0.7 backups can be reused without another capture. Version 1.0.8 uses the complete dump as one snapshot for application structure, Auth data, migration history, buckets and object metadata. Platform schemas and internal migrations remain at the destination's version.
311
-
312
- Database loading uses one transaction, stops on errors, suspends triggers only on its connection, compares every restored column and checks foreign keys before commit. Extra destination default grants are cleared before replaying the backup's grants. Failed SQL is never reported as success. Compressed archives and local function sources remain untouched.
313
-
314
- Optional URL remapping changes only the project's Supabase hostname, including URLs inside JSON and text files. It does not rename files or replace isolated project IDs. Historical URLs may also change; choose preservation when needed. Signed URLs, custom domains, external integrations and application API keys need separate validation. Destination platform keys are not replaced.
315
-
316
- Readable Auth and Realtime settings are applied through the Management API and verified by reading them back. The **SMTP password cannot be exported**: Supabase returns a protected value that cannot be used as the password in another project. Starting with 1.0.9, smoonb requests the real provider password with hidden input **before restoring any components**, including when using legacy backups. It stays in memory only and is sent to the destination Supabase project. The report distinguishes API password acceptance from readback verification (`applied_with_unverified_secrets`). Test an authentication email on the destination; API acceptance does not validate the password with the email provider.
317
-
318
- If a 1.0.8 restore stopped at `Configuration verification failed: smtp_pass` and its `report.json` confirms Database and Edge Functions, reuse the same backup and project: run `npx smoonb@1.0.9 restore`, answer **no** for Database and Edge Functions, and **yes** for the pending Auth, Storage, Database Settings and Realtime components. Enter the provider SMTP password when prompted. This specific failure does not require another backup or a database reload.
319
-
320
- Legacy Realtime captures may be stale: restoration reproduces the recorded values and date, not the source project's current settings. New backups capture Realtime directly through the API. Legacy function backups without the JWT flag default to requiring JWT; new backups preserve that flag.
321
-
322
- Since 1.0.10, if Supabase does not apply numeric Realtime capacity limits, smoonb shows **backup value vs current destination value** and asks whether to retain the destination values. Starting with 1.0.11, the recommended default is **yes — `(Y/n)`**. After acceptance, it re-reads the configuration and records `completed_with_accepted_differences` with exact values, without claiming an identical restore. Security switches, service activation and connection pools still require a match. The tool does not change your plan or spend cap.
323
-
324
- If an earlier restore ended only with `Configuration verification failed: max_presence_events_per_second, max_payload_size_in_kb`, consult its report and run `npx smoonb@1.0.11 restore` selecting **only Realtime Settings**. Do not repeat completed components. If you agree with the displayed limits, answer **yes** to the new prompt. Refusal leaves the step pending and records the differences; changes already applied are not undone.
325
-
326
- Reports are saved after each stage, including failures. External services cannot share the database transaction: earlier stages remain completed if a later stage fails. Do not reload the database into a populated destination. Resolve the reported stage and select only pending components, or use another empty project.
327
-
328
- Unsupported internal data (such as encrypted Vault secrets without key migration) and destination plan/version incompatibilities stop the operation. Verified status covers the selected components; validate login, email delivery and business workflows before production use.
329
-
330
- **Supported file formats:**
331
- - ✅ `.backup.gz` (compressed) - Automatically decompresses before restoring
332
- - ✅ `.backup` (uncompressed) - Restores directly
333
-
334
- ### Import Backup from Supabase Dashboard
335
-
336
- If you downloaded a backup directly from the Supabase Dashboard (`.backup.gz` format), you can import it to the format expected by smoonb. The command also supports optionally importing storage files (`.storage.zip`).
337
-
338
- **Import database only:**
339
- ```bash
340
- npx smoonb import --file "full/path/to/db_cluster-04-03-2024@14-16-59.backup.gz"
341
- ```
342
-
343
- **Import database and storage together:**
344
- ```bash
345
- npx smoonb import --file "backup.backup.gz" --storage "my-project.storage.zip"
346
- ```
347
-
348
- **What the command does:**
349
- 1. Reads the `.backup.gz` file from Dashboard (required)
350
- 2. If provided, reads the `.storage.zip` file from Dashboard (optional)
351
- 3. Extracts information from backup file name (date and time)
352
- 4. Creates a backup folder in expected format (`backup-YYYY-MM-DD-HH-MM-SS`)
353
- 5. Copies backup file to created folder
354
- 6. If provided, copies storage file to same folder
355
- 7. Makes backup ready to be found by `restore` command
356
-
357
- **Complete example - Database only (using import + restore):**
358
-
359
- 1. Download backup from Supabase Dashboard (e.g. `db_cluster-04-03-2024@14-16-59.backup.gz`).
360
- 2. Import the file, then restore:
361
-
362
- ```bash
363
- npx smoonb import --file "C:\Downloads\db_cluster-04-03-2024@14-16-59.backup.gz"
364
- npx smoonb restore
365
- ```
366
-
367
- The imported backup will appear in the list of available backups.
368
-
369
- **Complete example - Database and Storage (using import + restore):**
370
-
371
- 1. Download backup and storage from Supabase Dashboard (e.g. `db_cluster-04-03-2024@14-16-59.backup.gz` and `my-project.storage.zip`).
372
- 2. Import both files, then restore:
373
-
374
- ```bash
375
- npx smoonb import --file "C:\Downloads\db_cluster-04-03-2024@14-16-59.backup.gz" --storage "C:\Downloads\my-project.storage.zip"
376
- npx smoonb restore
377
- ```
378
-
379
- The imported backup will appear in the list of available backups.
380
-
381
- **Important:**
382
- - Backup file is **required** and must be in Dashboard format: `db_cluster-DD-MM-YYYY@HH-MM-SS.backup.gz`
383
- - Storage file is **optional** and must be in format: `*.storage.zip`
384
- - Storage depends on a backup, but backup does not depend on storage
385
- - Both files will be copied to the same backup folder
386
- - Path can be absolute or relative
387
- - Command will automatically create necessary folder structure
388
-
389
- After running `import`, run `restore` to choose the imported backup from the list and restore it.
390
-
391
- ## 🔧 Available Commands
392
-
393
- | Command | Description |
394
- |---------|-------------|
395
- | `npx smoonb backup` | Full interactive backup using Docker |
396
- | `npx smoonb backup --skip-supabase-version-check` | Backup skipping the Supabase CLI version check |
397
- | `npx smoonb restore` | Interactive restoration using psql (Docker) |
398
- | `npx smoonb restore --skip-supabase-version-check` | Restore skipping the Supabase CLI version check |
399
- | `npx smoonb import --file <path> [--storage <path>]` | Import .backup.gz file and optionally .storage.zip from Supabase Dashboard |
400
-
401
- ## 🏗️ Technical Architecture
402
-
403
- ### Modular Structure
404
-
405
- The code has been refactored to a **modular architecture** with independent steps:
406
-
407
- #### Backup (`src/commands/backup/`)
408
- ```
409
- backup/
410
- ├── index.js
411
- ├── utils.js
412
- └── steps/
413
- ├── 00-license.js
414
- ├── 01-docker-validation.js
415
- ├── 02-database.js
416
- ├── 03-database-separated.js
417
- ├── 04-database-settings.js
418
- ├── 05-auth-settings.js
419
- ├── 06-realtime-settings.js
420
- ├── 07-storage.js
421
- ├── 08-custom-roles.js
422
- ├── 09-edge-functions.js
423
- ├── 10-supabase-temp.js
424
- └── 11-migrations.js
425
- ```
426
-
427
- #### Restore (`src/commands/restore/`)
428
- License validation (same as backup, `00-license.js` from backup steps) runs at start. Then:
429
- ```
430
- restore/
431
- ├── index.js
432
- ├── utils.js
433
- └── steps/
434
- ├── 00-backup-selection.js
435
- ├── 01-components-selection.js
436
- ├── 02-confirmation.js
437
- ├── 03-database.js
438
- ├── 04-edge-functions.js
439
- ├── 05-auth-settings.js
440
- ├── 06-storage.js
441
- ├── 07-database-settings.js
442
- └── 08-realtime-settings.js
443
- ```
444
-
445
- ### Backup Strategy
446
-
447
- #### Database
448
- - **Main Backup**: `pg_dumpall` via Docker (identical to Dashboard)
449
- - File: `db_cluster-XX-XX-XXXX@XX-XX-XX.backup.gz`
450
- - Compatible with restoration via Supabase Dashboard
451
- - **Separate Backup**: SQL in separate files via Supabase CLI
452
- - `schema.sql` - Table structure
453
- - `data.sql` - Data (COPY statements)
454
- - `roles.sql` - Roles and permissions
455
-
456
- #### Edge Functions
457
- - **Automatic Download**: Via Supabase CLI `supabase functions download`
458
- - **Link Reset**: Ensures clean link with project before download
459
- - **Complete Backup**: Full code of each function
460
-
461
- #### Migrations
462
- - **Automatic Download**: Via `supabase migration fetch`
463
- - **Link Reset**: Ensures clean link with project
464
- - **Complete Backup**: All server migrations
465
-
466
- #### Storage
467
- - **Complete Backup**: Download of all files from all buckets
468
- - **Temporary Structure**: Creates `storage_temp/project-id/bucket-name/files...` inside backupDir
469
- - **ZIP in Dashboard Format**: Creates `{project-id}.storage.zip` with structure `project-id/bucket-name/files...`
470
- - **Restore Compatible**: Created ZIP is compatible with restore process (same format as Dashboard)
471
- - **Interactive Question**: After creating ZIP, asks if you want to clean temporary structure
472
- - **Fallback**: If Supabase credentials are not available, backs up metadata only
473
- - **Management API**: Uses Personal Access Token to list buckets and objects
474
- - **Supabase Client**: Uses Service Role Key for file downloads
475
-
476
- #### Auth, Realtime
477
- - **Management API**: Uses Personal Access Token
478
- - **JSON Export**: Configurations exported as JSON
479
- - **Realtime Settings**: Fresh API capture, including:
480
- 1. Enable Realtime service
481
- 2. Allow public access
482
- 3. Database connection pool size
483
- 4. Max concurrent clients
484
- 5. Max events per second
485
- 6. Max presence events per second
486
- 7. Max payload size in KB
487
- - **SMTP password**: Not exportable; requested with hidden input during restore.
488
-
489
- ### Restore Strategy
490
-
491
- #### Database
492
- - **Format Support**:
493
- - `.backup.gz` - Reads compressed content without modifying the archive
494
- - `.backup` - Restores directly via `psql` (Docker)
495
- - **Empty Destination**: Requires an empty destination for the database; skip this component when retrying later stages that failed.
496
-
497
- #### Edge Functions
498
- - **Isolated Deploy**: Uses a temporary workspace, preserving local `supabase/functions` files
499
- - **Explicit Destination**: Passes the target project reference to the CLI
500
- - **Automatic Deploy**: Uses `supabase functions deploy`
501
-
502
- #### Other Components
503
- - **Database Settings**: Restores via SQL
504
- - **Storage**: Restores buckets and files from ZIP (if available) or displays information for manual configuration
505
- - **Auth/Realtime**: Applies and checks configurations through the API; reports SMTP verification limits and any explicitly accepted Realtime capacity differences.
506
-
507
- ### Cross-Platform
508
-
509
- - **Windows/macOS/Linux**: Automatic binary detection
510
- - **Cross-platform**: Uses `fs.promises.cp`, `path.join`, Docker
511
- - **Docker for Everything**: Backup, restore and compression via Docker (ensures consistency)
512
-
513
- ## 📊 Recommended Flow
514
-
515
- 1. **Configure `.env.local`** (first time) with your source project credentials.
516
- 2. **Backup source project:**
517
- ```bash
518
- npx smoonb backup
519
- ```
520
- (Maps variables interactively on first run, selects components, executes full backup.)
521
- 3. **Create new Supabase project** (via Dashboard or Supabase CLI).
522
- 4. **Edit `.env.local`** with new project credentials (point variables to target project).
523
- 5. **Restore backup** (interactive mode):
524
- ```bash
525
- npx smoonb restore
526
- ```
527
- (Select desired backup, select components, execute restoration.)
528
- 6. **Review the result**: inspect `backups/restore-*/report.json` and test login, email and application workflows on the destination.
529
-
530
- ## 🎨 User Experience
531
-
532
- ### Multi-Language Interface
533
-
534
- All interactions are **automatically translated** based on system locale or `SMOONB_LANG`:
535
- - Clear and direct questions
536
- - Explanations before each process
537
- - Detailed summaries before confirming
538
- - Confirmations with `(Y/n)` or `(y/N)` in English, `(S/n)` or `(s/N)` in Portuguese
539
-
540
- ### Intelligent Variable Mapping
541
-
542
- - **Automatic Detection**: If key already exists with expected name, skips selection
543
- - **Add Option**: Allows adding new keys if they don't exist
544
- - **Value Validation**: Confirms values before saving
545
- - **Automatic Backup**: Always creates backup of `.env.local` before changes
546
-
547
- ### Guided Process
548
-
549
- - **Prior Validation**: Verifies Docker before starting
550
- - **Contextual Explanations**: Explains each process before asking
551
- - **Final Summary**: Shows everything that will be done before executing
552
- - **Visual Feedback**: Colors and icons for better experience
553
-
554
- ## 🐛 Troubleshooting
555
-
556
- ### Circular foreign-key warnings during data export
557
-
558
- Tables can reference each other (or themselves). PostgreSQL warns that a **data-only** dump cannot always be restored with ordinary foreign-key checks. This warning alone is not an export failure: check the exit result and the backup manifest.
559
-
560
- smoonb consolidates these known warnings, lists the affected tables, and records the original diagnostics in `backup-manifest.json` under `components.database_separated.warnings`. Other warnings and errors remain visible. A failed schema, data, or roles export marks this component as incomplete.
561
-
562
- The Supabase CLI currently prepends `SET session_replication_role = replica;` to `data.sql`. smoonb checks the first line before reporting its presence. This is **not a restore validation**: the destination role must be allowed to change that setting. Restore schema before data and stop on SQL errors. For a controlled restore into an appropriate, separate target, follow the [Supabase backup/restore guide](https://supabase.com/docs/guides/platform/migrating-within-supabase/backup-restore):
563
-
564
- ```bash
565
- psql --dbname "$TARGET_DB_URL" --single-transaction --variable ON_ERROR_STOP=1 --file roles.sql --file schema.sql --command 'SET session_replication_role = replica' --file data.sql
566
- ```
567
-
568
- The setting affects that restore connection; it does not modify the source database. Verify row counts and references in the restored target before relying on the backup. Do not remove foreign keys from your application to silence these warnings. The main `.backup.gz` is a full cluster dump; the separate SQL files are additional artifacts.
569
-
570
- ### Development checks
571
-
572
- Use Node.js 22 for development checks: `npm test`, `npm run lint`, and `npm run build`. The explicit `npm run test:docker` integration test requires Docker, the `postgres:17` image and Supabase CLI. It creates only synthetic data in its own disposable PostgreSQL container, tests protected and unprotected restores, and removes that container afterward. It does not use a project's credentials or remote database.
573
-
574
-
575
- ### Docker not found or not running
576
-
577
- Verify Docker is installed and running:
578
-
579
- ```bash
580
- docker --version
581
- docker ps
582
- ```
583
-
584
- If not, start Docker Desktop (Windows/macOS) or run `sudo systemctl start docker` (Linux).
585
-
586
- ### Supabase CLI not found
587
- ```bash
588
- npm install -g supabase
589
- ```
590
-
591
- ### Supabase CLI outdated (below minimum accepted version)
592
-
593
- smoonb accepts versions up to **1 minor behind the latest**. If your installed version is below that threshold, you will see a message like:
594
-
595
- ```
596
- ❌ Supabase CLI X.Y.Z is below the minimum accepted version (X.W.0). Latest: X.V.Z. Update to at least version X.W.0.
597
- ```
598
-
599
- **Option 1 — Update the Supabase CLI:**
600
- ```bash
601
- npm install -g supabase@latest # global install
602
- npm install supabase@latest # local/project install
603
- ```
604
-
605
- **Option 2 — Skip the check (temporary, user assumes the risk):**
606
- ```bash
607
- npx smoonb backup --skip-supabase-version-check
608
- npx smoonb restore --skip-supabase-version-check
609
- ```
610
-
611
- > **Note for Scoop users (Windows):** the Scoop repository may take a few days to update after a release. Use `--skip-supabase-version-check` until Scoop ships the updated version.
612
-
613
- ### Invalid or missing Personal Access Token
614
-
615
- 1. Verify if `SUPABASE_ACCESS_TOKEN` is in `.env.local`
616
- 2. Generate new token: https://supabase.com/dashboard/account/tokens
617
- 3. Update `.env.local` with new token
618
-
619
- ### Incorrect Database URL
620
- - Verify password in connection URL
621
- - Use Connection string from Supabase Dashboard (Settings → Database)
622
- - Test connection: `psql "your-database-url" -c "SELECT 1"`
623
-
624
- ### .backup.gz file cannot be restored
625
-
626
- smoonb automatically supports:
627
- - ✅ `.backup.gz` - Reads compressed content without changing the original archive
628
- - ✅ `.backup` - Restores directly
629
-
630
- If there are problems:
631
- 1. Verify if Docker is running
632
- 2. Verify file permissions
633
- 3. Verify disk space
634
-
635
- ### Error downloading Edge Functions
636
-
637
- 1. Verify if `SUPABASE_ACCESS_TOKEN` is configured
638
- 2. Verify if project is linked: `supabase link`
639
- 3. Verify if functions exist on server
640
-
641
- ### Error downloading Migrations
642
-
643
- 1. Verify if `SUPABASE_ACCESS_TOKEN` is configured
644
- 2. Verify if project is linked: `supabase link`
645
- 3. Verify if there are migrations on server
646
-
647
- ## 🔒 Security
648
-
649
- - **Automatic Backup**: Always creates backup of `.env.local` before changes
650
- - **Local Mapping**: Variable mapping saved only locally
651
- - **No Sensitive Data**: No sensitive data is sent outside your environment
652
- - **Isolated Docker**: Database operations via Docker (isolation)
653
-
654
- ## 💼 Access and subscription
655
-
656
- Supa Moonbase code is provided under MIT license (see `LICENSE`). To use smoonb you must have an **active license** and a **valid subscription**, or be within a **trial period**. License validation runs at the start of backup and restore; without a valid license and subscription (or trial), the CLI will not run those operations.
657
-
658
- [www.smoonb.com/#price](https://www.smoonb.com/#price).
659
-
660
- ## 🔒 Privacy and LGPD (summary)
661
-
662
- Supa Moonbase adopts the data minimization principle. We process only the information strictly necessary for access control and billing (e.g., account identifier and contact). Purposes, legal bases and data subject rights are described in the [Privacy Policy](https://www.smoonb.com/privacy).
663
-
664
- ## 📋 Terms of Service and brand usage
665
-
666
- The code license (MIT) does not replace the [Terms of Service](https://www.smoonb.com/terms) that govern operational access and subscription validation.
667
-
668
- "Supa Moonbase" and visual identity elements are trademarks of Goalmoon Tecnologia Ltda.; use of brand and branding assets is restricted as per [Terms of Service](https://www.smoonb.com/terms).
669
-
670
- [FAQ](https://www.smoonb.com/#faq).
671
-
672
- ## 📝 License
673
-
674
- Supa Moonbase code is provided under MIT license. See [LICENSE](LICENSE) for the full license text. A Portuguese translation is available in [LICENSE.pt-BR.md](LICENSE.pt-BR.md) for convenience only.
675
-
676
- ## 🤝 Contributing
677
-
678
- Contributions are welcome. [www.smoonb.com/#price](https://www.smoonb.com/#price).
679
-
680
-
681
- ---
682
-
683
- **Developed by:** Goalmoon Tecnologia LTDA
684
- **Website:** https://www.smoonb.com
685
- **GitHub:** https://github.com/almmello/smoonb
686
-
687
- Additional restore-path test: `npm run test:restore:docker`. Uses disposable PostgreSQL, synthetic data and mocked Storage HTTP transport; covers Auth, grants, cycles, rollback, files and metadata.
688
-
689
- ## Reliability from 1.0.12
690
-
691
- Use Node.js LTS 22, 24 or 26 and a running Docker engine. Supabase CLI 2.122.1 is an exact package dependency, with npm-shrinkwrap.json locking distribution dependencies. The global CLI and npm latest do not determine backup compatibility. The v2 channel receives maintenance; no fixed LTS term is assumed. The first export may need to download the PostgreSQL image used by the CLI.
692
-
693
- SQL, roles, Functions and migrations run in temporary workspaces. Project files are preserved. Failed requested components yield exit code 1 and incomplete status; successful files remain available. Environment mappings apply to the current run without rewriting the project file. Upgrade legacy installations explicitly after publication: `npm install --save-exact smoonb@1.0.13`.
694
-
695
- In 1.0.13, databases without migration history complete that component with zero files. Connection/permission failures still produce an incomplete backup, with a summary of every component.
1
+ # Supa Moonbase (smoonb)
2
+
3
+ **Complete Supabase backup and migration tool**
4
+
5
+ Backup and restore: complete and simple, as it should be
6
+
7
+ > **Commercial product.** You need an **active license** and a **valid subscription** (or be on a trial period) to use smoonb. [www.smoonb.com/#price](https://www.smoonb.com/#price). Use is governed by the [Terms of Service](https://www.smoonb.com/terms) and [Privacy Policy](https://www.smoonb.com/privacy). We do not assume any liability for damage caused by smoonb; the legal disclaimers below remain in effect.
8
+
9
+ **Read this in other languages:** [Português (Brasil)](README.pt-BR.md)
10
+
11
+ **Developed by:** Goalmoon Tecnologia LTDA
12
+ **Website:** https://www.smoonb.com
13
+ **GitHub:** https://github.com/almmello/smoonb
14
+
15
+ ## 🎯 Objective
16
+
17
+ **smoonb** solves the problem of existing tools that only backup the PostgreSQL database, ignoring critical Supabase components.
18
+
19
+ ## 📦 Backup Components
20
+
21
+ smoonb performs a complete backup of all components of your Supabase project:
22
+
23
+ - ✅ **Database PostgreSQL** (backup completo via `pg_dumpall` + SQL separados, idêntico ao Dashboard)
24
+ - ✅ **Database Extensions and Settings** (extensões PostgreSQL e configurações)
25
+ - ✅ **Custom Roles** (roles personalizados do PostgreSQL)
26
+ - ✅ **Edge Functions** (download automático do servidor)
27
+ - ✅ **Auth Settings** (configurações de autenticação via Management API)
28
+ - ✅ **Storage Buckets** (backup completo: metadados, configurações e todos os arquivos via Management API + Supabase Client, cria ZIP no padrão do Dashboard)
29
+ - ✅ **Realtime Settings** (current settings captured through the Management API)
30
+ - ✅ **Supabase .temp** (arquivos temporários do Supabase CLI)
31
+ - ✅ **Migrations** (todas as migrations do projeto via `supabase migration fetch`)
32
+
33
+ ## ⚠️ Universal Disclaimer / Legal Notice
34
+
35
+ By continuing, you acknowledge and agree that Supa Moonbase (smoonb) is provided "AS IS" and "AS AVAILABLE", with no warranties of any kind—express, implied, or statutory—including but not limited to merchantability, fitness for a particular purpose, and non-infringement, to the maximum extent permitted by applicable law. Backup and restore operations inherently carry risk, environments vary widely, and we cannot foresee or validate all user setups. You are solely responsible for validating your own environment, keeping independent copies, and verifying results before relying on them in production. We build Supa Moonbase (smoonb) on public, auditable, open-source repositories to help people simplify their workflows, but this does not create any warranty, promise of support, or service-level commitment.
36
+
37
+ **Limitation of liability** — To the maximum extent permitted by law, Goalmoon Tecnologia LTDA, its contributors, and licensors will not be liable for any indirect, incidental, special, consequential, exemplary, or punitive damages (including loss of data, interruption of business, or lost profits) arising from or related to the use of, inability to use, backup/restore operations performed by, or results produced by Supa Moonbase (smoonb).
38
+
39
+ ## 🚀 Installation
40
+
41
+ **⚠️ IMPORTANT: Install ONLY locally in the project!**
42
+
43
+ **Install locally in the project:**
44
+ ```bash
45
+ npm install smoonb
46
+ ```
47
+
48
+ **Use with npx:**
49
+ ```bash
50
+ npx smoonb --help
51
+ ```
52
+
53
+ **Do not install globally** (blocked):
54
+ ```bash
55
+ npm install -g smoonb
56
+ ```
57
+
58
+ ### 🔄 Update to Latest Version
59
+
60
+ To update smoonb to the latest available version, run in the current project:
61
+
62
+ ```bash
63
+ npm install smoonb@latest
64
+ ```
65
+
66
+ **⚠️ IMPORTANT:** smoonb must be installed locally in the project. Using without installing (e.g., `npx smoonb@latest`) is not allowed.
67
+
68
+ **💡 Why local only?**
69
+ - **🔒 Security**: Avoids version conflicts
70
+ - **📦 Isolation**: Each project uses its own version
71
+ - **🔄 Updates**: Granular control per project
72
+ - **🛡️ Stability**: Prevents breaking other projects
73
+
74
+ ## 📋 Prerequisites
75
+
76
+ ### 1. Docker Desktop (REQUIRED)
77
+
78
+ Install from [Docker Desktop](https://docs.docker.com/desktop/install/) (Windows/macOS) or [Docker Engine](https://docs.docker.com/engine/install/) (Linux). Then verify it is running:
79
+
80
+ ```bash
81
+ docker --version
82
+ docker ps
83
+ ```
84
+
85
+ **⚠️ IMPORTANT:** Docker is required for:
86
+ - Database backup via `pg_dumpall` (compatible with Supabase Dashboard)
87
+ - Compression of `.backup.gz` files
88
+ - Restoration of `.backup` and `.backup.gz` backups
89
+
90
+ ### 2. Supabase CLI
91
+ ```bash
92
+ npm install -g supabase
93
+ ```
94
+
95
+ **Version policy:** smoonb accepts any Supabase CLI version that is **at most 1 minor behind the latest** (same major). We recommend always using the latest version. Versions that are too old are blocked with an error message.
96
+
97
+ If your package manager (e.g. **Scoop** on Windows) lags behind on updates and you want to proceed anyway, use the `--skip-supabase-version-check` flag (see usage section below).
98
+
99
+ To update the Supabase CLI: [Updating the Supabase CLI](https://supabase.com/docs/guides/cli/getting-started#updating-the-supabase-cli).
100
+
101
+ ### 3. Supabase Personal Access Token
102
+ You need to obtain a Supabase personal access token to use the Management API:
103
+
104
+ 1. Visit: https://supabase.com/dashboard/account/tokens
105
+ 2. Click "Generate new token"
106
+ 3. Copy the token (format: `sbp_...`)
107
+ 4. Add to `.env.local` as `SUPABASE_ACCESS_TOKEN`
108
+
109
+ ### 4. License Key (REQUIRED for backup and restore)
110
+ **smoonb** requires a valid license to run backup and restore:
111
+
112
+ 1. Get your license from the desktop app at https://www.smoonb.com
113
+ 2. Set in environment or `.env.local`: `SMOONB_LICENSE_KEY=[your-license-key]`
114
+ 3. License is validated at the start of each run (step 00); no caching. If validation fails (network/server), the CLI aborts. The license is **not** shown in the interactive variable-mapping wizard (it is already validated before that).
115
+
116
+ ## ⚙️ Configuration
117
+
118
+ ### Modern Method: `.env.local` (RECOMMENDED)
119
+
120
+ **smoonb** now uses `.env.local` for configuration, following industry standards. This makes the process simpler and more integrated with your workflow.
121
+
122
+ #### 1. Create or edit `.env.local` in the project root
123
+
124
+ ```bash
125
+ touch .env.local
126
+ ```
127
+
128
+ #### 2. Add required environment variables
129
+
130
+ ```env
131
+ SMOONB_LICENSE_KEY=[your-license-key]
132
+ NEXT_PUBLIC_SUPABASE_URL=[your-supabase-url]
133
+ NEXT_PUBLIC_SUPABASE_ANON_KEY=[your-anon-key]
134
+ SUPABASE_SERVICE_ROLE_KEY=[your-service-role]
135
+ SUPABASE_DB_URL=postgresql://postgres:[your-database-password]@db.[your-project-id].supabase.co:5432/postgres
136
+ SUPABASE_PROJECT_ID=[your-project-id]
137
+ SUPABASE_ACCESS_TOKEN=[your-access-token]
138
+ SUPABASE_POSTGRES_MAJOR=17
139
+ SMOONB_TELEMETRY_ENABLED=true
140
+ SMOONB_OUTPUT_DIR=./backups
141
+ ```
142
+
143
+ Required: `SMOONB_LICENSE_KEY` (from [www.smoonb.com](https://www.smoonb.com) desktop app), `SUPABASE_POSTGRES_MAJOR` (e.g. 17; see Dashboard → Project Settings → Infrastructure → Service Versions). Optional: `SMOONB_TELEMETRY_ENABLED`, `SMOONB_OUTPUT_DIR` (default `./backups`).
144
+
145
+ #### 3. Interactive Mapping
146
+
147
+ When running `backup` or `restore` for the first time, **smoonb** will:
148
+
149
+ 1. **Read** your current `.env.local`
150
+ 2. **Identify** the keys you already have
151
+ 3. **Ask interactively** which keys correspond to the expected ones (if names are different)
152
+ 4. **Add** missing keys if necessary
153
+ 5. **Create automatic backup** of `.env.local` before any changes
154
+ 6. **Save mapping** for future executions
155
+
156
+ **Mapping example:**
157
+ ```
158
+ 🔧 Mapping variable: NEXT_PUBLIC_SUPABASE_URL
159
+ Current value: https://abc123.supabase.co
160
+ Is this the correct value for the target project? (Y/n): Y
161
+ ```
162
+
163
+ ## 🌐 Internationalization (i18n)
164
+
165
+ **smoonb** supports multiple languages automatically. Currently supported languages are:
166
+
167
+ - **English (en)** - Default language
168
+ - **Portuguese (Brazil) (pt-BR)** - Full support
169
+
170
+ ### Automatic Language Detection
171
+
172
+ Language is detected automatically in the following order of precedence:
173
+
174
+ 1. **Environment variable `SMOONB_LANG`** (in `.env.local` or in the environment)
175
+ 2. **System locale** (LANG, LC_ALL, LC_MESSAGES). Example: `LANG=pt_BR.UTF-8` → pt-BR
176
+ 3. **Fallback to English (en)** if none of the above are detected
177
+
178
+ ### Supported Languages and Aliases
179
+
180
+ - `en` or `en-US` → English
181
+ - `pt-BR`, `pt_BR` or `pt` → Portuguese (Brazil)
182
+
183
+ ### Important Notes
184
+
185
+ - **Machine outputs** (e.g., `--json` if implemented) are **not** translated; fields and keys remain in English
186
+ - If a translation key is missing in a language, the system automatically **falls back to English**
187
+ - Language is detected once at the start of execution and applied to all CLI messages
188
+
189
+ ## 🎯 Usage
190
+
191
+ ### Full Backup
192
+
193
+ ```bash
194
+ npx smoonb backup
195
+ ```
196
+
197
+ **Available options:**
198
+
199
+ | Flag | Description |
200
+ |------|-------------|
201
+ | `--skip-supabase-version-check` | Skips the Supabase CLI version check. Use when your package manager (e.g. Scoop) lags behind on updates. A warning is shown and the user assumes the risk. |
202
+
203
+ **Example with flag:**
204
+ ```bash
205
+ npx smoonb backup --skip-supabase-version-check
206
+ ```
207
+
208
+ **Interactive backup flow:**
209
+
210
+ 1. **Terms of use** - Displays and requests acceptance of terms
211
+ 2. **License validation** - Validates `SMOONB_LICENSE_KEY` (env or prompt); no cache; aborts if validation fails
212
+ 3. **Docker validation** - Verifies if Docker is running
213
+ 4. **Consent** - Asks permission to read/write `.env.local`
214
+ 5. **Variable mapping** - Maps your environment variables (first time; license is not in the wizard—already validated)
215
+ 6. **.env.local backup** - Creates automatic backup before changes
216
+ 7. **Component selection** - Asks which components to include:
217
+ - ⚡ Edge Functions (explanation about link reset and download)
218
+ - 📦 Storage (explanation about full backup: file download + ZIP in Dashboard format)
219
+ - 🔐 Auth Settings (explanation about configurations)
220
+ - 🔄 Realtime Settings (current configuration captured through the API)
221
+ - 🗑️ Cleanup options (functions, .temp, migrations after backup)
222
+ 8. **Configuration summary** - Shows everything that will be done
223
+ 9. **Final confirmation** - Confirms before starting
224
+ 10. **Step execution:**
225
+ - 📊 1/10 - Database Backup via `pg_dumpall` (Docker)
226
+ - 📊 2/10 - Separate Database SQL (schema, data, roles)
227
+ - 🔧 3/10 - Database Extensions and Settings Backup
228
+ - 🔐 4/10 - Auth Settings Backup (if selected)
229
+ - 🔄 5/10 - Realtime Settings Backup (if selected) - fresh API snapshot
230
+ - 📦 6/10 - Storage Backup (if selected) - Full file download + ZIP in Dashboard format
231
+ - 👥 7/10 - Custom Roles Backup
232
+ - ⚡ 8/10 - Edge Functions Backup (if selected)
233
+ - 📁 9/10 - Supabase .temp Backup (if selected)
234
+ - 📋 10/10 - Migrations Backup (if selected)
235
+
236
+ **Result:** A folder `backups/backup-YYYY-MM-DD-HH-MM-SS/` containing for example:
237
+
238
+ ```
239
+ backups/backup-2025-10-31-09-37-54/
240
+ ├── backup-manifest.json
241
+ ├── db_cluster-31-10-2025@09-38-57.backup.gz
242
+ ├── schema.sql
243
+ ├── data.sql
244
+ ├── roles.sql
245
+ ├── database-settings-*.json
246
+ ├── auth-settings.json
247
+ ├── realtime-settings.json
248
+ ├── storage/
249
+ │ └── [bucket-name].json
250
+ ├── [project-id].storage.zip
251
+ ├── storage_temp/
252
+ │ └── [project-id]/
253
+ │ └── [bucket-name]/
254
+ ├── edge-functions/
255
+ │ └── [function-name]/
256
+ ├── supabase-temp/
257
+ ├── migrations/
258
+ └── env/
259
+ ├── .env.local
260
+ └── env-map.json
261
+ ```
262
+
263
+ ### Interactive Restoration
264
+
265
+ **Restore existing backup:**
266
+ ```bash
267
+ npx smoonb restore
268
+ ```
269
+
270
+ **Available options:**
271
+
272
+ | Flag | Description |
273
+ |------|-------------|
274
+ | `--skip-supabase-version-check` | Skips the Supabase CLI version check. Use when your package manager (e.g. Scoop) lags behind on updates. A warning is shown and the user assumes the risk. |
275
+
276
+ **Example with flag:**
277
+ ```bash
278
+ npx smoonb restore --skip-supabase-version-check
279
+ ```
280
+
281
+ **Interactive restore flow:**
282
+
283
+ 1. **Terms of use** - Displays and requests acceptance of terms
284
+ 2. **License validation** - Validates `SMOONB_LICENSE_KEY` (env or prompt); aborts if validation fails
285
+ 3. **Docker validation** - Verifies if Docker is running
286
+ 4. **Consent** - Asks permission to read/write `.env.local`
287
+ 5. **Variable mapping** - Maps variables to target project (includes `SUPABASE_POSTGRES_MAJOR`)
288
+ 6. **.env.local backup** - Creates automatic backup
289
+ 7. **Backup selection** - Lists and allows choosing which backup to restore
290
+ 8. **Component selection** - Asks which components to restore:
291
+ - 📊 Database (always available)
292
+ - ⚡ Edge Functions (if available in backup)
293
+ - 🔐 Auth Settings (if available in backup)
294
+ - 📦 Storage (if available in backup)
295
+ - 🔧 Database Extensions and Settings (if available in backup)
296
+ - 🔄 Realtime Settings (if available in backup)
297
+ 9. **Detailed summary** - Shows selected backup, target project and components
298
+ 10. **Final confirmation** - Confirms before starting
299
+ 11. **Project URLs** - Confirms whether Supabase URLs in data and files should point to the new project
300
+ 12. **Restore execution:**
301
+ - 📊 Database - Restores via `psql` (supports `.backup.gz` and `.backup`)
302
+ - ⚡ Edge Functions - Deploys from a temporary copy, preserving local sources
303
+ - 🔐 Auth Settings - Applies via API and verifies the resulting values
304
+ - 📦 Storage - Restores buckets and ZIP files, preserves metadata and verifies every download
305
+ - 🔧 Database Settings - Restores extensions and settings via SQL
306
+ - 🔄 Realtime Settings - Applies and verifies the snapshot recorded in the backup
307
+
308
+ ### Verified restoration (1.0.8)
309
+
310
+ Use a new, empty destination project and Node.js 20 or later. Existing complete 1.0.7 backups can be reused without another capture. Version 1.0.8 uses the complete dump as one snapshot for application structure, Auth data, migration history, buckets and object metadata. Platform schemas and internal migrations remain at the destination's version.
311
+
312
+ Database loading uses one transaction, stops on errors, suspends triggers only on its connection, compares every restored column and checks foreign keys before commit. Extra destination default grants are cleared before replaying the backup's grants. Failed SQL is never reported as success. Compressed archives and local function sources remain untouched.
313
+
314
+ Optional URL remapping changes only the project's Supabase hostname, including URLs inside JSON and text files. It does not rename files or replace isolated project IDs. Historical URLs may also change; choose preservation when needed. Signed URLs, custom domains, external integrations and application API keys need separate validation. Destination platform keys are not replaced.
315
+
316
+ Readable Auth and Realtime settings are applied through the Management API and verified by reading them back. The **SMTP password cannot be exported**: Supabase returns a protected value that cannot be used as the password in another project. Starting with 1.0.9, smoonb requests the real provider password with hidden input **before restoring any components**, including when using legacy backups. It stays in memory only and is sent to the destination Supabase project. The report distinguishes API password acceptance from readback verification (`applied_with_unverified_secrets`). Test an authentication email on the destination; API acceptance does not validate the password with the email provider.
317
+
318
+ If a 1.0.8 restore stopped at `Configuration verification failed: smtp_pass` and its `report.json` confirms Database and Edge Functions, reuse the same backup and project: run `npx smoonb@1.0.9 restore`, answer **no** for Database and Edge Functions, and **yes** for the pending Auth, Storage, Database Settings and Realtime components. Enter the provider SMTP password when prompted. This specific failure does not require another backup or a database reload.
319
+
320
+ Legacy Realtime captures may be stale: restoration reproduces the recorded values and date, not the source project's current settings. New backups capture Realtime directly through the API. Legacy function backups without the JWT flag default to requiring JWT; new backups preserve that flag.
321
+
322
+ Since 1.0.10, if Supabase does not apply numeric Realtime capacity limits, smoonb shows **backup value vs current destination value** and asks whether to retain the destination values. Starting with 1.0.11, the recommended default is **yes — `(Y/n)`**. After acceptance, it re-reads the configuration and records `completed_with_accepted_differences` with exact values, without claiming an identical restore. Security switches, service activation and connection pools still require a match. The tool does not change your plan or spend cap.
323
+
324
+ If an earlier restore ended only with `Configuration verification failed: max_presence_events_per_second, max_payload_size_in_kb`, consult its report and run `npx smoonb@1.0.11 restore` selecting **only Realtime Settings**. Do not repeat completed components. If you agree with the displayed limits, answer **yes** to the new prompt. Refusal leaves the step pending and records the differences; changes already applied are not undone.
325
+
326
+ Reports are saved after each stage, including failures. External services cannot share the database transaction: earlier stages remain completed if a later stage fails. Do not reload the database into a populated destination. Resolve the reported stage and select only pending components, or use another empty project.
327
+
328
+ Unsupported internal data (such as encrypted Vault secrets without key migration) and destination plan/version incompatibilities stop the operation. Verified status covers the selected components; validate login, email delivery and business workflows before production use.
329
+
330
+ **Supported file formats:**
331
+ - ✅ `.backup.gz` (compressed) - Automatically decompresses before restoring
332
+ - ✅ `.backup` (uncompressed) - Restores directly
333
+
334
+ ### Import Backup from Supabase Dashboard
335
+
336
+ If you downloaded a backup directly from the Supabase Dashboard (`.backup.gz` format), you can import it to the format expected by smoonb. The command also supports optionally importing storage files (`.storage.zip`).
337
+
338
+ **Import database only:**
339
+ ```bash
340
+ npx smoonb import --file "full/path/to/db_cluster-04-03-2024@14-16-59.backup.gz"
341
+ ```
342
+
343
+ **Import database and storage together:**
344
+ ```bash
345
+ npx smoonb import --file "backup.backup.gz" --storage "my-project.storage.zip"
346
+ ```
347
+
348
+ **What the command does:**
349
+ 1. Reads the `.backup.gz` file from Dashboard (required)
350
+ 2. If provided, reads the `.storage.zip` file from Dashboard (optional)
351
+ 3. Extracts information from backup file name (date and time)
352
+ 4. Creates a backup folder in expected format (`backup-YYYY-MM-DD-HH-MM-SS`)
353
+ 5. Copies backup file to created folder
354
+ 6. If provided, copies storage file to same folder
355
+ 7. Makes backup ready to be found by `restore` command
356
+
357
+ **Complete example - Database only (using import + restore):**
358
+
359
+ 1. Download backup from Supabase Dashboard (e.g. `db_cluster-04-03-2024@14-16-59.backup.gz`).
360
+ 2. Import the file, then restore:
361
+
362
+ ```bash
363
+ npx smoonb import --file "C:\Downloads\db_cluster-04-03-2024@14-16-59.backup.gz"
364
+ npx smoonb restore
365
+ ```
366
+
367
+ The imported backup will appear in the list of available backups.
368
+
369
+ **Complete example - Database and Storage (using import + restore):**
370
+
371
+ 1. Download backup and storage from Supabase Dashboard (e.g. `db_cluster-04-03-2024@14-16-59.backup.gz` and `my-project.storage.zip`).
372
+ 2. Import both files, then restore:
373
+
374
+ ```bash
375
+ npx smoonb import --file "C:\Downloads\db_cluster-04-03-2024@14-16-59.backup.gz" --storage "C:\Downloads\my-project.storage.zip"
376
+ npx smoonb restore
377
+ ```
378
+
379
+ The imported backup will appear in the list of available backups.
380
+
381
+ **Important:**
382
+ - Backup file is **required** and must be in Dashboard format: `db_cluster-DD-MM-YYYY@HH-MM-SS.backup.gz`
383
+ - Storage file is **optional** and must be in format: `*.storage.zip`
384
+ - Storage depends on a backup, but backup does not depend on storage
385
+ - Both files will be copied to the same backup folder
386
+ - Path can be absolute or relative
387
+ - Command will automatically create necessary folder structure
388
+
389
+ After running `import`, run `restore` to choose the imported backup from the list and restore it.
390
+
391
+ ## 🔧 Available Commands
392
+
393
+ | Command | Description |
394
+ |---------|-------------|
395
+ | `npx smoonb backup` | Full interactive backup using Docker |
396
+ | `npx smoonb backup --skip-supabase-version-check` | Backup skipping the Supabase CLI version check |
397
+ | `npx smoonb restore` | Interactive restoration using psql (Docker) |
398
+ | `npx smoonb restore --skip-supabase-version-check` | Restore skipping the Supabase CLI version check |
399
+ | `npx smoonb import --file <path> [--storage <path>]` | Import .backup.gz file and optionally .storage.zip from Supabase Dashboard |
400
+
401
+ ## 🏗️ Technical Architecture
402
+
403
+ ### Modular Structure
404
+
405
+ The code has been refactored to a **modular architecture** with independent steps:
406
+
407
+ #### Backup (`src/commands/backup/`)
408
+ ```
409
+ backup/
410
+ ├── index.js
411
+ ├── utils.js
412
+ └── steps/
413
+ ├── 00-license.js
414
+ ├── 01-docker-validation.js
415
+ ├── 02-database.js
416
+ ├── 03-database-separated.js
417
+ ├── 04-database-settings.js
418
+ ├── 05-auth-settings.js
419
+ ├── 06-realtime-settings.js
420
+ ├── 07-storage.js
421
+ ├── 08-custom-roles.js
422
+ ├── 09-edge-functions.js
423
+ ├── 10-supabase-temp.js
424
+ └── 11-migrations.js
425
+ ```
426
+
427
+ #### Restore (`src/commands/restore/`)
428
+ License validation (same as backup, `00-license.js` from backup steps) runs at start. Then:
429
+ ```
430
+ restore/
431
+ ├── index.js
432
+ ├── utils.js
433
+ └── steps/
434
+ ├── 00-backup-selection.js
435
+ ├── 01-components-selection.js
436
+ ├── 02-confirmation.js
437
+ ├── 03-database.js
438
+ ├── 04-edge-functions.js
439
+ ├── 05-auth-settings.js
440
+ ├── 06-storage.js
441
+ ├── 07-database-settings.js
442
+ └── 08-realtime-settings.js
443
+ ```
444
+
445
+ ### Backup Strategy
446
+
447
+ #### Database
448
+ - **Main Backup**: `pg_dumpall` via Docker (identical to Dashboard)
449
+ - File: `db_cluster-XX-XX-XXXX@XX-XX-XX.backup.gz`
450
+ - Compatible with restoration via Supabase Dashboard
451
+ - **Separate Backup**: SQL in separate files via Supabase CLI
452
+ - `schema.sql` - Table structure
453
+ - `data.sql` - Data (COPY statements)
454
+ - `roles.sql` - Roles and permissions
455
+
456
+ #### Edge Functions
457
+ - **Automatic Download**: Via Supabase CLI `supabase functions download`
458
+ - **Link Reset**: Ensures clean link with project before download
459
+ - **Complete Backup**: Full code of each function
460
+
461
+ #### Migrations
462
+ - **Automatic Download**: Via `supabase migration fetch`
463
+ - **Link Reset**: Ensures clean link with project
464
+ - **Complete Backup**: All server migrations
465
+
466
+ #### Storage
467
+ - **Complete Backup**: Download of all files from all buckets
468
+ - **Temporary Structure**: Creates `storage_temp/project-id/bucket-name/files...` inside backupDir
469
+ - **ZIP in Dashboard Format**: Creates `{project-id}.storage.zip` with structure `project-id/bucket-name/files...`
470
+ - **Restore Compatible**: Created ZIP is compatible with restore process (same format as Dashboard)
471
+ - **Interactive Question**: After creating ZIP, asks if you want to clean temporary structure
472
+ - **Fallback**: If Supabase credentials are not available, backs up metadata only
473
+ - **Management API**: Uses Personal Access Token to list buckets and objects
474
+ - **Supabase Client**: Uses Service Role Key for file downloads
475
+
476
+ #### Auth, Realtime
477
+ - **Management API**: Uses Personal Access Token
478
+ - **JSON Export**: Configurations exported as JSON
479
+ - **Realtime Settings**: Fresh API capture, including:
480
+ 1. Enable Realtime service
481
+ 2. Allow public access
482
+ 3. Database connection pool size
483
+ 4. Max concurrent clients
484
+ 5. Max events per second
485
+ 6. Max presence events per second
486
+ 7. Max payload size in KB
487
+ - **SMTP password**: Not exportable; requested with hidden input during restore.
488
+
489
+ ### Restore Strategy
490
+
491
+ #### Database
492
+ - **Format Support**:
493
+ - `.backup.gz` - Reads compressed content without modifying the archive
494
+ - `.backup` - Restores directly via `psql` (Docker)
495
+ - **Empty Destination**: Requires an empty destination for the database; skip this component when retrying later stages that failed.
496
+
497
+ #### Edge Functions
498
+ - **Isolated Deploy**: Uses a temporary workspace, preserving local `supabase/functions` files
499
+ - **Explicit Destination**: Passes the target project reference to the CLI
500
+ - **Automatic Deploy**: Uses `supabase functions deploy`
501
+
502
+ #### Other Components
503
+ - **Database Settings**: Restores via SQL
504
+ - **Storage**: Restores buckets and files from ZIP (if available) or displays information for manual configuration
505
+ - **Auth/Realtime**: Applies and checks configurations through the API; reports SMTP verification limits and any explicitly accepted Realtime capacity differences.
506
+
507
+ ### Cross-Platform
508
+
509
+ - **Windows/macOS/Linux**: Automatic binary detection
510
+ - **Cross-platform**: Uses `fs.promises.cp`, `path.join`, Docker
511
+ - **Docker for Everything**: Backup, restore and compression via Docker (ensures consistency)
512
+
513
+ ## 📊 Recommended Flow
514
+
515
+ 1. **Configure `.env.local`** (first time) with your source project credentials.
516
+ 2. **Backup source project:**
517
+ ```bash
518
+ npx smoonb backup
519
+ ```
520
+ (Maps variables interactively on first run, selects components, executes full backup.)
521
+ 3. **Create new Supabase project** (via Dashboard or Supabase CLI).
522
+ 4. **Edit `.env.local`** with new project credentials (point variables to target project).
523
+ 5. **Restore backup** (interactive mode):
524
+ ```bash
525
+ npx smoonb restore
526
+ ```
527
+ (Select desired backup, select components, execute restoration.)
528
+ 6. **Review the result**: inspect `backups/restore-*/report.json` and test login, email and application workflows on the destination.
529
+
530
+ ## 🎨 User Experience
531
+
532
+ ### Multi-Language Interface
533
+
534
+ All interactions are **automatically translated** based on system locale or `SMOONB_LANG`:
535
+ - Clear and direct questions
536
+ - Explanations before each process
537
+ - Detailed summaries before confirming
538
+ - Confirmations with `(Y/n)` or `(y/N)` in English, `(S/n)` or `(s/N)` in Portuguese
539
+
540
+ ### Intelligent Variable Mapping
541
+
542
+ - **Automatic Detection**: If key already exists with expected name, skips selection
543
+ - **Add Option**: Allows adding new keys if they don't exist
544
+ - **Value Validation**: Confirms values before saving
545
+ - **Automatic Backup**: Always creates backup of `.env.local` before changes
546
+
547
+ ### Guided Process
548
+
549
+ - **Prior Validation**: Verifies Docker before starting
550
+ - **Contextual Explanations**: Explains each process before asking
551
+ - **Final Summary**: Shows everything that will be done before executing
552
+ - **Visual Feedback**: Colors and icons for better experience
553
+
554
+ ## 🐛 Troubleshooting
555
+
556
+ ### Circular foreign-key warnings during data export
557
+
558
+ Tables can reference each other (or themselves). PostgreSQL warns that a **data-only** dump cannot always be restored with ordinary foreign-key checks. This warning alone is not an export failure: check the exit result and the backup manifest.
559
+
560
+ smoonb consolidates these known warnings, lists the affected tables, and records the original diagnostics in `backup-manifest.json` under `components.database_separated.warnings`. Other warnings and errors remain visible. A failed schema, data, or roles export marks this component as incomplete.
561
+
562
+ The Supabase CLI currently prepends `SET session_replication_role = replica;` to `data.sql`. smoonb checks the first line before reporting its presence. This is **not a restore validation**: the destination role must be allowed to change that setting. Restore schema before data and stop on SQL errors. For a controlled restore into an appropriate, separate target, follow the [Supabase backup/restore guide](https://supabase.com/docs/guides/platform/migrating-within-supabase/backup-restore):
563
+
564
+ ```bash
565
+ psql --dbname "$TARGET_DB_URL" --single-transaction --variable ON_ERROR_STOP=1 --file roles.sql --file schema.sql --command 'SET session_replication_role = replica' --file data.sql
566
+ ```
567
+
568
+ The setting affects that restore connection; it does not modify the source database. Verify row counts and references in the restored target before relying on the backup. Do not remove foreign keys from your application to silence these warnings. The main `.backup.gz` is a full cluster dump; the separate SQL files are additional artifacts.
569
+
570
+ ### Development checks
571
+
572
+ Use Node.js 22 for development checks: `npm test`, `npm run lint`, and `npm run build`. The explicit `npm run test:docker` integration test requires Docker, the `postgres:17` image and Supabase CLI. It creates only synthetic data in its own disposable PostgreSQL container, tests protected and unprotected restores, and removes that container afterward. It does not use a project's credentials or remote database.
573
+
574
+
575
+ ### Docker not found or not running
576
+
577
+ Verify Docker is installed and running:
578
+
579
+ ```bash
580
+ docker --version
581
+ docker ps
582
+ ```
583
+
584
+ If not, start Docker Desktop (Windows/macOS) or run `sudo systemctl start docker` (Linux).
585
+
586
+ ### Supabase CLI not found
587
+ ```bash
588
+ npm install -g supabase
589
+ ```
590
+
591
+ ### Supabase CLI outdated (below minimum accepted version)
592
+
593
+ smoonb accepts versions up to **1 minor behind the latest**. If your installed version is below that threshold, you will see a message like:
594
+
595
+ ```
596
+ ❌ Supabase CLI X.Y.Z is below the minimum accepted version (X.W.0). Latest: X.V.Z. Update to at least version X.W.0.
597
+ ```
598
+
599
+ **Option 1 — Update the Supabase CLI:**
600
+ ```bash
601
+ npm install -g supabase@latest # global install
602
+ npm install supabase@latest # local/project install
603
+ ```
604
+
605
+ **Option 2 — Skip the check (temporary, user assumes the risk):**
606
+ ```bash
607
+ npx smoonb backup --skip-supabase-version-check
608
+ npx smoonb restore --skip-supabase-version-check
609
+ ```
610
+
611
+ > **Note for Scoop users (Windows):** the Scoop repository may take a few days to update after a release. Use `--skip-supabase-version-check` until Scoop ships the updated version.
612
+
613
+ ### Invalid or missing Personal Access Token
614
+
615
+ 1. Verify if `SUPABASE_ACCESS_TOKEN` is in `.env.local`
616
+ 2. Generate new token: https://supabase.com/dashboard/account/tokens
617
+ 3. Update `.env.local` with new token
618
+
619
+ ### Incorrect Database URL
620
+ - Verify password in connection URL
621
+ - Use Connection string from Supabase Dashboard (Settings → Database)
622
+ - Test connection: `psql "your-database-url" -c "SELECT 1"`
623
+
624
+ ### .backup.gz file cannot be restored
625
+
626
+ smoonb automatically supports:
627
+ - ✅ `.backup.gz` - Reads compressed content without changing the original archive
628
+ - ✅ `.backup` - Restores directly
629
+
630
+ If there are problems:
631
+ 1. Verify if Docker is running
632
+ 2. Verify file permissions
633
+ 3. Verify disk space
634
+
635
+ ### Error downloading Edge Functions
636
+
637
+ 1. Verify if `SUPABASE_ACCESS_TOKEN` is configured
638
+ 2. Verify if project is linked: `supabase link`
639
+ 3. Verify if functions exist on server
640
+
641
+ ### Error downloading Migrations
642
+
643
+ 1. Verify if `SUPABASE_ACCESS_TOKEN` is configured
644
+ 2. Verify if project is linked: `supabase link`
645
+ 3. Verify if there are migrations on server
646
+
647
+ ## 🔒 Security
648
+
649
+ - **Automatic Backup**: Always creates backup of `.env.local` before changes
650
+ - **Local Mapping**: Variable mapping saved only locally
651
+ - **No Sensitive Data**: No sensitive data is sent outside your environment
652
+ - **Isolated Docker**: Database operations via Docker (isolation)
653
+
654
+ ## 💼 Access and subscription
655
+
656
+ Supa Moonbase code is provided under MIT license (see `LICENSE`). To use smoonb you must have an **active license** and a **valid subscription**, or be within a **trial period**. License validation runs at the start of backup and restore; without a valid license and subscription (or trial), the CLI will not run those operations.
657
+
658
+ [www.smoonb.com/#price](https://www.smoonb.com/#price).
659
+
660
+ ## 🔒 Privacy and LGPD (summary)
661
+
662
+ Supa Moonbase adopts the data minimization principle. We process only the information strictly necessary for access control and billing (e.g., account identifier and contact). Purposes, legal bases and data subject rights are described in the [Privacy Policy](https://www.smoonb.com/privacy).
663
+
664
+ ## 📋 Terms of Service and brand usage
665
+
666
+ The code license (MIT) does not replace the [Terms of Service](https://www.smoonb.com/terms) that govern operational access and subscription validation.
667
+
668
+ "Supa Moonbase" and visual identity elements are trademarks of Goalmoon Tecnologia Ltda.; use of brand and branding assets is restricted as per [Terms of Service](https://www.smoonb.com/terms).
669
+
670
+ [FAQ](https://www.smoonb.com/#faq).
671
+
672
+ ## 📝 License
673
+
674
+ Supa Moonbase code is provided under MIT license. See [LICENSE](LICENSE) for the full license text. A Portuguese translation is available in [LICENSE.pt-BR.md](LICENSE.pt-BR.md) for convenience only.
675
+
676
+ ## 🤝 Contributing
677
+
678
+ Contributions are welcome. [www.smoonb.com/#price](https://www.smoonb.com/#price).
679
+
680
+
681
+ ---
682
+
683
+ **Developed by:** Goalmoon Tecnologia LTDA
684
+ **Website:** https://www.smoonb.com
685
+ **GitHub:** https://github.com/almmello/smoonb
686
+
687
+ Additional restore-path test: `npm run test:restore:docker`. Uses disposable PostgreSQL, synthetic data and mocked Storage HTTP transport; covers Auth, grants, cycles, rollback, files and metadata.
688
+
689
+ ## Reliability from 1.0.12
690
+
691
+ Use Node.js LTS 22, 24 or 26 and a running Docker engine. Supabase CLI 2.122.1 is an exact package dependency, with npm-shrinkwrap.json locking distribution dependencies. The global CLI and npm latest do not determine backup compatibility. The v2 channel receives maintenance; no fixed LTS term is assumed. The first export may need to download the PostgreSQL image used by the CLI.
692
+
693
+ SQL, roles, Functions and migrations run in temporary workspaces. Project files are preserved. Failed requested components yield exit code 1 and incomplete status; successful files remain available. Since 1.0.14, each confirmed environment value is saved immediately to `.env.local`, before export, so failures or cancellation do not discard it. Unrelated settings are preserved. The backup stores the pre-mapping file at `env/.env.local.before` and the effective configuration at `env/.env.local`. Prompted license keys are also saved before validation. Upgrade legacy installations explicitly after publication: `npm install --save-exact smoonb@1.0.14`.
694
+
695
+ In 1.0.13, databases without migration history complete that component with zero files. Connection/permission failures still produce an incomplete backup, with a summary of every component.