@fazetitans/fscopy 1.0.0
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/LICENSE +21 -0
- package/README.md +409 -0
- package/package.json +74 -0
- package/src/cli.ts +1936 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 [fullname]
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="assets/banner.png" alt="fscopy banner" width="600">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">
|
|
6
|
+
<img src="assets/logo.png" alt="fscopy logo" width="40" height="40" style="vertical-align: middle;">
|
|
7
|
+
fscopy
|
|
8
|
+
</h1>
|
|
9
|
+
|
|
10
|
+
<p align="center">
|
|
11
|
+
<a href="https://www.npmjs.com/package/@fazetitans/fscopy"><img src="https://img.shields.io/npm/v/@fazetitans/fscopy.svg" alt="npm version"></a>
|
|
12
|
+
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
|
|
13
|
+
</p>
|
|
14
|
+
|
|
15
|
+
<p align="center">
|
|
16
|
+
<strong>Fast CLI tool to copy Firestore collections between Firebase projects</strong>
|
|
17
|
+
</p>
|
|
18
|
+
|
|
19
|
+
Transfer documents between Firebase projects with support for subcollections, filtering, parallel transfers, and merge mode. Built with [Bun](https://bun.sh) for maximum performance.
|
|
20
|
+
|
|
21
|
+
## Features
|
|
22
|
+
|
|
23
|
+
- **Subcollection support** - Recursively copy nested collections
|
|
24
|
+
- **Document filtering** - Filter documents with `--where` clauses
|
|
25
|
+
- **Exclude patterns** - Skip subcollections by name or glob pattern
|
|
26
|
+
- **Merge mode** - Update existing documents instead of overwriting
|
|
27
|
+
- **Parallel transfers** - Copy multiple collections simultaneously
|
|
28
|
+
- **Clear destination** - Optionally delete destination data before transfer
|
|
29
|
+
- **Sync mode** - Delete destination docs not present in source
|
|
30
|
+
- **Document transform** - Transform data during transfer with custom JS/TS functions
|
|
31
|
+
- **Collection renaming** - Rename collections in destination for backups or migrations
|
|
32
|
+
- **ID modification** - Add prefix or suffix to document IDs to avoid conflicts
|
|
33
|
+
- **Webhook notifications** - Send Slack, Discord, or custom webhooks on completion
|
|
34
|
+
- **Resume transfers** - Continue interrupted transfers from saved state
|
|
35
|
+
- **Interactive mode** - Guided setup with prompts for project and collection selection
|
|
36
|
+
- **Progress bar** - Real-time progress with ETA
|
|
37
|
+
- **Automatic retry** - Exponential backoff on network errors
|
|
38
|
+
- **Dry run mode** - Preview changes before applying (enabled by default)
|
|
39
|
+
- **Flexible config** - INI, JSON, or CLI arguments
|
|
40
|
+
|
|
41
|
+
## Installation
|
|
42
|
+
|
|
43
|
+
### With Bun (recommended)
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# Global install
|
|
47
|
+
bun add -g @fazetitans/fscopy
|
|
48
|
+
|
|
49
|
+
# Or run directly
|
|
50
|
+
bunx @fazetitans/fscopy --help
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### With npm
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
npm install -g @fazetitans/fscopy
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Prerequisites
|
|
60
|
+
|
|
61
|
+
1. [Bun](https://bun.sh) or Node.js 18+
|
|
62
|
+
1. Google Cloud authentication: `gcloud auth application-default login`
|
|
63
|
+
1. Firestore read access on source project, write access on destination
|
|
64
|
+
|
|
65
|
+
## Quick Start
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# 1. Generate config file
|
|
69
|
+
fscopy --init config.ini
|
|
70
|
+
|
|
71
|
+
# 2. Edit config.ini with your project IDs and collections
|
|
72
|
+
|
|
73
|
+
# 3. Preview transfer (dry run)
|
|
74
|
+
fscopy -f config.ini
|
|
75
|
+
|
|
76
|
+
# 4. Execute transfer
|
|
77
|
+
fscopy -f config.ini -d false -y
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Usage
|
|
81
|
+
|
|
82
|
+
### Basic Transfer
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
# Using config file
|
|
86
|
+
fscopy -f config.ini
|
|
87
|
+
|
|
88
|
+
# Using CLI arguments
|
|
89
|
+
fscopy \
|
|
90
|
+
--source-project my-source \
|
|
91
|
+
--dest-project my-dest \
|
|
92
|
+
-c users orders products
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### With Subcollections
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# Include all subcollections
|
|
99
|
+
fscopy -f config.ini -s
|
|
100
|
+
|
|
101
|
+
# Exclude specific subcollections
|
|
102
|
+
fscopy -f config.ini -s --exclude logs --exclude "temp/*"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Filtering Documents
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
# Single filter
|
|
109
|
+
fscopy -f config.ini --where "status == active"
|
|
110
|
+
|
|
111
|
+
# Multiple filters (AND)
|
|
112
|
+
fscopy -f config.ini -w "active == true" -w "createdAt > 2024-01-01"
|
|
113
|
+
|
|
114
|
+
# Supported operators: ==, !=, <, >, <=, >=
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Advanced Options
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
# Merge mode (update instead of overwrite)
|
|
121
|
+
fscopy -f config.ini --merge
|
|
122
|
+
|
|
123
|
+
# Parallel transfers (3 collections at once)
|
|
124
|
+
fscopy -f config.ini --parallel 3
|
|
125
|
+
|
|
126
|
+
# With logging
|
|
127
|
+
fscopy -f config.ini --log transfer.log
|
|
128
|
+
|
|
129
|
+
# Limit documents per collection
|
|
130
|
+
fscopy -f config.ini --limit 100
|
|
131
|
+
|
|
132
|
+
# Quiet mode (no progress bar)
|
|
133
|
+
fscopy -f config.ini -q
|
|
134
|
+
|
|
135
|
+
# Clear destination before transfer (DESTRUCTIVE)
|
|
136
|
+
fscopy -f config.ini --clear
|
|
137
|
+
|
|
138
|
+
# Sync mode: delete orphan docs in destination
|
|
139
|
+
fscopy -f config.ini --delete-missing
|
|
140
|
+
|
|
141
|
+
# Interactive mode with prompts
|
|
142
|
+
fscopy -i
|
|
143
|
+
|
|
144
|
+
# Transform documents during transfer
|
|
145
|
+
fscopy -f config.ini --transform ./transforms/anonymize.ts
|
|
146
|
+
|
|
147
|
+
# Rename collections in destination
|
|
148
|
+
fscopy -f config.ini -r users:users_backup -r orders:orders_2024
|
|
149
|
+
|
|
150
|
+
# Add prefix to document IDs
|
|
151
|
+
fscopy -f config.ini --id-prefix backup_
|
|
152
|
+
|
|
153
|
+
# Add suffix to document IDs
|
|
154
|
+
fscopy -f config.ini --id-suffix _archived
|
|
155
|
+
|
|
156
|
+
# Send notification to Slack/Discord
|
|
157
|
+
fscopy -f config.ini --webhook https://hooks.slack.com/services/...
|
|
158
|
+
|
|
159
|
+
# Resume an interrupted transfer
|
|
160
|
+
fscopy -f config.ini --resume
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Collection Renaming
|
|
164
|
+
|
|
165
|
+
Rename collections during transfer for backups or migrations:
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
# Backup with dated collection names
|
|
169
|
+
fscopy -f config.ini -r users:users_2024_12_29 -r orders:orders_2024_12_29
|
|
170
|
+
|
|
171
|
+
# Multiple renames in one command
|
|
172
|
+
fscopy -f config.ini --rename-collection users:users_v2 --rename-collection products:catalog
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Subcollections are automatically renamed along with their parent collection.
|
|
176
|
+
|
|
177
|
+
### ID Modification
|
|
178
|
+
|
|
179
|
+
Add prefix or suffix to document IDs to avoid conflicts when merging:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
# Add prefix: user123 → backup_user123
|
|
183
|
+
fscopy -f config.ini --id-prefix backup_
|
|
184
|
+
|
|
185
|
+
# Add suffix: user123 → user123_v2
|
|
186
|
+
fscopy -f config.ini --id-suffix _v2
|
|
187
|
+
|
|
188
|
+
# Combine both: user123 → old_user123_archived
|
|
189
|
+
fscopy -f config.ini --id-prefix old_ --id-suffix _archived
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Document Transform
|
|
193
|
+
|
|
194
|
+
Transform documents during transfer using a custom function:
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
# Create a transform file
|
|
198
|
+
cat > anonymize.ts << 'EOF'
|
|
199
|
+
export function transform(doc, meta) {
|
|
200
|
+
// Anonymize email addresses
|
|
201
|
+
if (doc.email) {
|
|
202
|
+
doc.email = `user_${meta.id}@example.com`;
|
|
203
|
+
}
|
|
204
|
+
// Remove sensitive fields
|
|
205
|
+
delete doc.password;
|
|
206
|
+
delete doc.ssn;
|
|
207
|
+
// Return null to skip the document
|
|
208
|
+
if (doc.deleted) return null;
|
|
209
|
+
return doc;
|
|
210
|
+
}
|
|
211
|
+
EOF
|
|
212
|
+
|
|
213
|
+
# Use the transform
|
|
214
|
+
fscopy -f config.ini -t ./anonymize.ts
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
The transform function receives:
|
|
218
|
+
|
|
219
|
+
- `doc` - The document data as an object
|
|
220
|
+
- `meta` - Metadata with `id` (document ID) and `path` (full document path)
|
|
221
|
+
|
|
222
|
+
Return the transformed document, or `null` to skip it.
|
|
223
|
+
|
|
224
|
+
### Webhook Notifications
|
|
225
|
+
|
|
226
|
+
Get notified when transfers complete (success or failure):
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
# Slack webhook
|
|
230
|
+
fscopy -f config.ini --webhook https://hooks.slack.com/services/XXX/YYY/ZZZ
|
|
231
|
+
|
|
232
|
+
# Discord webhook
|
|
233
|
+
fscopy -f config.ini --webhook https://discord.com/api/webhooks/123/abc
|
|
234
|
+
|
|
235
|
+
# Custom webhook (receives raw JSON payload)
|
|
236
|
+
fscopy -f config.ini --webhook https://api.example.com/webhook
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
The webhook receives a POST request with:
|
|
240
|
+
|
|
241
|
+
- `source` / `destination` - Project IDs
|
|
242
|
+
- `collections` - List of transferred collections
|
|
243
|
+
- `stats` - Documents transferred, deleted, errors
|
|
244
|
+
- `duration` - Transfer time in seconds
|
|
245
|
+
- `dryRun` - Whether it was a dry run
|
|
246
|
+
- `success` - Boolean status
|
|
247
|
+
- `error` - Error message (if failed)
|
|
248
|
+
|
|
249
|
+
Slack and Discord webhooks are automatically formatted with rich messages.
|
|
250
|
+
|
|
251
|
+
### Resume Interrupted Transfers
|
|
252
|
+
|
|
253
|
+
Large migrations can be resumed if interrupted:
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
# Start a transfer (state is saved automatically to .fscopy-state.json)
|
|
257
|
+
fscopy -f config.ini -d false
|
|
258
|
+
|
|
259
|
+
# If interrupted (Ctrl+C, network error, etc.), resume from where it left off
|
|
260
|
+
fscopy -f config.ini --resume
|
|
261
|
+
|
|
262
|
+
# Use a custom state file
|
|
263
|
+
fscopy -f config.ini --state-file ./my-transfer.state.json
|
|
264
|
+
fscopy -f config.ini --resume --state-file ./my-transfer.state.json
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
The state file tracks:
|
|
268
|
+
|
|
269
|
+
- Completed document IDs per collection
|
|
270
|
+
- Transfer statistics
|
|
271
|
+
- Source/destination project validation
|
|
272
|
+
|
|
273
|
+
State files are automatically deleted on successful completion.
|
|
274
|
+
|
|
275
|
+
## Configuration
|
|
276
|
+
|
|
277
|
+
### INI Format (recommended)
|
|
278
|
+
|
|
279
|
+
```bash
|
|
280
|
+
fscopy --init config.ini
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
```ini
|
|
284
|
+
[projects]
|
|
285
|
+
source = my-source-project
|
|
286
|
+
dest = my-dest-project
|
|
287
|
+
|
|
288
|
+
[transfer]
|
|
289
|
+
collections = users, orders, products
|
|
290
|
+
includeSubcollections = true
|
|
291
|
+
dryRun = true
|
|
292
|
+
batchSize = 500
|
|
293
|
+
limit = 0
|
|
294
|
+
|
|
295
|
+
[options]
|
|
296
|
+
; where = status == active
|
|
297
|
+
; exclude = logs, cache, temp/*
|
|
298
|
+
merge = false
|
|
299
|
+
parallel = 1
|
|
300
|
+
clear = false
|
|
301
|
+
deleteMissing = false
|
|
302
|
+
; transform = ./transforms/anonymize.ts
|
|
303
|
+
; renameCollection = users:users_backup, orders:orders_2024
|
|
304
|
+
; idPrefix = backup_
|
|
305
|
+
; idSuffix = _v2
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### JSON Format
|
|
309
|
+
|
|
310
|
+
```bash
|
|
311
|
+
fscopy --init config.json
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
```json
|
|
315
|
+
{
|
|
316
|
+
"sourceProject": "my-source-project",
|
|
317
|
+
"destProject": "my-dest-project",
|
|
318
|
+
"collections": ["users", "orders"],
|
|
319
|
+
"includeSubcollections": true,
|
|
320
|
+
"dryRun": true,
|
|
321
|
+
"batchSize": 500,
|
|
322
|
+
"limit": 0,
|
|
323
|
+
"where": ["status == active"],
|
|
324
|
+
"exclude": ["logs", "cache"],
|
|
325
|
+
"merge": false,
|
|
326
|
+
"parallel": 1,
|
|
327
|
+
"clear": false,
|
|
328
|
+
"deleteMissing": false,
|
|
329
|
+
"transform": null,
|
|
330
|
+
"renameCollection": {},
|
|
331
|
+
"idPrefix": null,
|
|
332
|
+
"idSuffix": null
|
|
333
|
+
}
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
## CLI Reference
|
|
337
|
+
|
|
338
|
+
| Option | Alias | Type | Default | Description |
|
|
339
|
+
| -------------------------- | ----- | ------- | ------- | --------------------------------- |
|
|
340
|
+
| `--init` | | string | | Generate config template |
|
|
341
|
+
| `--config` | `-f` | string | | Path to config file |
|
|
342
|
+
| `--source-project` | | string | | Source Firebase project |
|
|
343
|
+
| `--dest-project` | | string | | Destination project |
|
|
344
|
+
| `--collections` | `-c` | array | | Collections to transfer |
|
|
345
|
+
| `--include-subcollections` | `-s` | boolean | `false` | Include subcollections |
|
|
346
|
+
| `--where` | `-w` | array | | Filter documents |
|
|
347
|
+
| `--exclude` | `-x` | array | | Exclude subcollections |
|
|
348
|
+
| `--merge` | `-m` | boolean | `false` | Merge instead of overwrite |
|
|
349
|
+
| `--parallel` | `-p` | number | `1` | Parallel transfers |
|
|
350
|
+
| `--dry-run` | `-d` | boolean | `true` | Preview without writing |
|
|
351
|
+
| `--batch-size` | `-b` | number | `500` | Documents per batch |
|
|
352
|
+
| `--limit` | `-l` | number | `0` | Limit docs (0 = no limit) |
|
|
353
|
+
| `--retries` | | number | `3` | Retries on error |
|
|
354
|
+
| `--log` | | string | | Log file path |
|
|
355
|
+
| `--quiet` | `-q` | boolean | `false` | No progress bar |
|
|
356
|
+
| `--yes` | `-y` | boolean | `false` | Skip confirmation |
|
|
357
|
+
| `--clear` | | boolean | `false` | Clear destination before transfer |
|
|
358
|
+
| `--delete-missing` | | boolean | `false` | Delete dest docs not in source |
|
|
359
|
+
| `--interactive` | `-i` | boolean | `false` | Interactive mode with prompts |
|
|
360
|
+
| `--transform` | `-t` | string | | Path to JS/TS transform file |
|
|
361
|
+
| `--rename-collection` | `-r` | array | | Rename collection (source:dest) |
|
|
362
|
+
| `--id-prefix` | | string | | Add prefix to document IDs |
|
|
363
|
+
| `--id-suffix` | | string | | Add suffix to document IDs |
|
|
364
|
+
| `--webhook` | | string | | Webhook URL for notifications |
|
|
365
|
+
| `--resume` | | boolean | `false` | Resume from saved state |
|
|
366
|
+
| `--state-file` | | string | `.fscopy-state.json` | State file path |
|
|
367
|
+
|
|
368
|
+
## How It Works
|
|
369
|
+
|
|
370
|
+
1. **Authentication** - Uses Google Application Default Credentials (ADC)
|
|
371
|
+
2. **Document counting** - Counts total documents for progress bar
|
|
372
|
+
3. **Batch processing** - Transfers documents in configurable batches
|
|
373
|
+
4. **Retry logic** - Automatic retry with exponential backoff on failures
|
|
374
|
+
5. **Subcollection discovery** - Uses `listCollections()` to find nested data
|
|
375
|
+
|
|
376
|
+
## Notes
|
|
377
|
+
|
|
378
|
+
- **Dry run is ON by default** - Use `-d false` for actual transfer
|
|
379
|
+
- **Documents are overwritten** - Use `--merge` to update instead
|
|
380
|
+
- **Where filters apply to root only** - Subcollections are copied in full
|
|
381
|
+
- **Exclude patterns support globs** - e.g., `temp/*`, `*/logs`
|
|
382
|
+
- **Progress bar shows ETA** - Based on documents processed
|
|
383
|
+
- **Clear is destructive** - `--clear` deletes all destination docs before transfer
|
|
384
|
+
- **Delete-missing syncs** - `--delete-missing` removes orphan docs after transfer
|
|
385
|
+
- **Transform applies to all** - Transform function is applied to both root and subcollection docs
|
|
386
|
+
- **Same project allowed** - Source and destination can be the same project when using `--rename-collection` or `--id-prefix`/`--id-suffix`
|
|
387
|
+
|
|
388
|
+
## Development
|
|
389
|
+
|
|
390
|
+
```bash
|
|
391
|
+
# Clone and install
|
|
392
|
+
git clone https://github.com/fazetitans/fscopy.git
|
|
393
|
+
cd fscopy
|
|
394
|
+
bun install
|
|
395
|
+
|
|
396
|
+
# Run locally
|
|
397
|
+
bun start -- -f config.ini
|
|
398
|
+
|
|
399
|
+
# Run tests
|
|
400
|
+
bun test
|
|
401
|
+
|
|
402
|
+
# Type check & lint
|
|
403
|
+
bun run type-check
|
|
404
|
+
bun run lint
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
## License
|
|
408
|
+
|
|
409
|
+
[MIT](LICENSE)
|
package/package.json
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@fazetitans/fscopy",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Fast CLI tool to copy Firestore collections between Firebase projects with filtering, parallel transfers, and subcollection support",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"fscopy": "./src/cli.ts"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"start": "bun src/cli.ts",
|
|
11
|
+
"dev": "bun --watch src/cli.ts",
|
|
12
|
+
"test": "bun test",
|
|
13
|
+
"test:watch": "bun test --watch",
|
|
14
|
+
"type-check": "tsc --noEmit",
|
|
15
|
+
"lint": "eslint src/**/*.ts",
|
|
16
|
+
"lint:fix": "eslint src/**/*.ts --fix",
|
|
17
|
+
"format": "prettier --write src/**/*.ts",
|
|
18
|
+
"format:check": "prettier --check src/**/*.ts",
|
|
19
|
+
"prepublishOnly": "bun run type-check && bun run lint && bun test"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"firestore",
|
|
23
|
+
"firebase",
|
|
24
|
+
"transfer",
|
|
25
|
+
"migration",
|
|
26
|
+
"cli",
|
|
27
|
+
"copy",
|
|
28
|
+
"backup",
|
|
29
|
+
"sync",
|
|
30
|
+
"google-cloud",
|
|
31
|
+
"database",
|
|
32
|
+
"nosql",
|
|
33
|
+
"bun"
|
|
34
|
+
],
|
|
35
|
+
"author": "fazetitans",
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "git+https://github.com/fazetitans/fscopy.git"
|
|
40
|
+
},
|
|
41
|
+
"homepage": "https://github.com/fazetitans/fscopy#readme",
|
|
42
|
+
"bugs": {
|
|
43
|
+
"url": "https://github.com/fazetitans/fscopy/issues"
|
|
44
|
+
},
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=18.0.0"
|
|
47
|
+
},
|
|
48
|
+
"files": [
|
|
49
|
+
"src/cli.ts",
|
|
50
|
+
"README.md",
|
|
51
|
+
"LICENSE"
|
|
52
|
+
],
|
|
53
|
+
"dependencies": {
|
|
54
|
+
"@inquirer/prompts": "^8.1.0",
|
|
55
|
+
"cli-progress": "^3.12.0",
|
|
56
|
+
"firebase-admin": "^13.6.0",
|
|
57
|
+
"ini": "^6.0.0",
|
|
58
|
+
"yargs": "^17.7.2"
|
|
59
|
+
},
|
|
60
|
+
"devDependencies": {
|
|
61
|
+
"@eslint/js": "^9.39.2",
|
|
62
|
+
"@types/cli-progress": "^3.11.6",
|
|
63
|
+
"@types/ini": "^4.1.1",
|
|
64
|
+
"@types/node": "^25.0.3",
|
|
65
|
+
"@types/yargs": "^17.0.35",
|
|
66
|
+
"@typescript-eslint/eslint-plugin": "^8.51.0",
|
|
67
|
+
"@typescript-eslint/parser": "^8.51.0",
|
|
68
|
+
"bun-types": "^1.3.5",
|
|
69
|
+
"eslint": "^9.39.2",
|
|
70
|
+
"prettier": "^3.7.4",
|
|
71
|
+
"typescript": "^5.9.3",
|
|
72
|
+
"typescript-eslint": "^8.51.0"
|
|
73
|
+
}
|
|
74
|
+
}
|