firestore-dart-generator 1.0.0-beta.1
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/CONFIG_FILE_GUIDE.md +445 -0
- package/IMPLEMENTATION_SUMMARY.md +305 -0
- package/LICENSE +22 -0
- package/QUICK_START.md +241 -0
- package/README.md +590 -0
- package/dist/config-file-loader.d.ts +35 -0
- package/dist/config-file-loader.d.ts.map +1 -0
- package/dist/config-file-loader.js +130 -0
- package/dist/config-file-loader.js.map +1 -0
- package/dist/config-loader.d.ts +21 -0
- package/dist/config-loader.d.ts.map +1 -0
- package/dist/config-loader.js +125 -0
- package/dist/config-loader.js.map +1 -0
- package/dist/dart-generator.d.ts +35 -0
- package/dist/dart-generator.d.ts.map +1 -0
- package/dist/dart-generator.js +167 -0
- package/dist/dart-generator.js.map +1 -0
- package/dist/firestore-client.d.ts +49 -0
- package/dist/firestore-client.d.ts.map +1 -0
- package/dist/firestore-client.js +227 -0
- package/dist/firestore-client.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +65 -0
- package/dist/index.js.map +1 -0
- package/dist/interactive-cli.d.ts +5 -0
- package/dist/interactive-cli.d.ts.map +1 -0
- package/dist/interactive-cli.js +310 -0
- package/dist/interactive-cli.js.map +1 -0
- package/dist/schema-analyzer.d.ts +38 -0
- package/dist/schema-analyzer.d.ts.map +1 -0
- package/dist/schema-analyzer.js +350 -0
- package/dist/schema-analyzer.js.map +1 -0
- package/dist/templates/model.hbs +39 -0
- package/dist/types.d.ts +58 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/firestore-dart-gen.example.yaml +28 -0
- package/package.json +61 -0
package/README.md
ADDED
|
@@ -0,0 +1,590 @@
|
|
|
1
|
+
# Firestore Dart Generator
|
|
2
|
+
|
|
3
|
+
A TypeScript CLI tool that automatically generates Dart models from Firestore collections by analyzing document schemas in your Firebase project.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🎮 **Interactive Mode**: Guided CLI experience with collection selection
|
|
8
|
+
- 🔥 Connects directly to Firebase Firestore
|
|
9
|
+
- 📊 Analyzes real documents to infer field types
|
|
10
|
+
- 🎯 Generates clean Dart models with `fromJson`/`toJson`
|
|
11
|
+
- 🔍 Detects optional and nullable fields automatically
|
|
12
|
+
- ✅ **Multiple selection**: Choose multiple collections at once with checkboxes
|
|
13
|
+
- 🌳 **Auto-discovery**: Automatically detects and offers subcollections
|
|
14
|
+
- 🎨 **Auto-formats generated code with `dart format`**
|
|
15
|
+
- ⚡ Fast and easy to use
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
### Global Installation (Recommended)
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install -g firestore-dart-generator
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Using npx (No Installation Required)
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npx firestore-dart-generator --help
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Local Installation
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm install --save-dev firestore-dart-generator
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Quick Start
|
|
38
|
+
|
|
39
|
+
1. **Install the tool**:
|
|
40
|
+
```bash
|
|
41
|
+
npm install -g firestore-dart-generator
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
2. **Run interactively**:
|
|
45
|
+
```bash
|
|
46
|
+
firestore-dart-gen --service-account firebase_service_account.json
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
3. **Follow the prompts**:
|
|
50
|
+
- ✨ View your Firebase project name
|
|
51
|
+
- ✅ Select collections with checkboxes (Space to select, Enter to confirm)
|
|
52
|
+
- 🌳 Choose whether to include subcollections (auto-detected)
|
|
53
|
+
- 📁 Configure output directory and sample size
|
|
54
|
+
- 🎯 Review summary and confirm
|
|
55
|
+
|
|
56
|
+
Done! Your Dart models are generated.
|
|
57
|
+
|
|
58
|
+
## Prerequisites
|
|
59
|
+
|
|
60
|
+
- Node.js 18+ with npm
|
|
61
|
+
- Firebase project with Firestore
|
|
62
|
+
- Firebase service account JSON file (for authentication)
|
|
63
|
+
- (Optional) Dart SDK for auto-formatting
|
|
64
|
+
|
|
65
|
+
## Firebase Authentication Setup
|
|
66
|
+
|
|
67
|
+
### 1. Create a Firebase Service Account
|
|
68
|
+
|
|
69
|
+
1. Go to [Firebase Console](https://console.firebase.google.com/)
|
|
70
|
+
2. Select your project
|
|
71
|
+
3. Go to **Project Settings** > **Service Accounts**
|
|
72
|
+
4. Click **Generate New Private Key**
|
|
73
|
+
5. Save the JSON file securely (e.g., `firebase_service_account.json`)
|
|
74
|
+
|
|
75
|
+
⚠️ **Important**: Never commit this file to git!
|
|
76
|
+
|
|
77
|
+
### 2. Configure Environment Variables (Optional)
|
|
78
|
+
|
|
79
|
+
Create a `.env` file in your project directory:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
GOOGLE_APPLICATION_CREDENTIALS=./firebase_service_account.json
|
|
83
|
+
FIREBASE_PROJECT_ID=your-project-id
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Or use the `--service-account` and `--project-id` flags when running the command.
|
|
87
|
+
|
|
88
|
+
## Configuration File (Optional)
|
|
89
|
+
|
|
90
|
+
You can create a `firestore-dart-gen.yaml` file to:
|
|
91
|
+
- ✅ Specify Firebase credentials (no need to type them every time)
|
|
92
|
+
- ✅ Pre-select collections you use frequently
|
|
93
|
+
- ✅ Set default output directory and sample size
|
|
94
|
+
- ✅ Share configuration with your team (without credentials)
|
|
95
|
+
|
|
96
|
+
### Example Configuration
|
|
97
|
+
|
|
98
|
+
Create `firestore-dart-gen.yaml` in your project root:
|
|
99
|
+
|
|
100
|
+
```yaml
|
|
101
|
+
# Firebase Configuration
|
|
102
|
+
firebase:
|
|
103
|
+
serviceAccount: ./firebase_service_account.json
|
|
104
|
+
projectId: my-project-id # optional
|
|
105
|
+
|
|
106
|
+
# Pre-select these collections in the CLI
|
|
107
|
+
collections:
|
|
108
|
+
- users
|
|
109
|
+
- products
|
|
110
|
+
- orders
|
|
111
|
+
|
|
112
|
+
# Default output settings
|
|
113
|
+
output:
|
|
114
|
+
directory: ./lib/src/models
|
|
115
|
+
sampleSize: 20
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Copy from the example file:
|
|
119
|
+
```bash
|
|
120
|
+
cp firestore-dart-gen.example.yaml firestore-dart-gen.yaml
|
|
121
|
+
# Edit with your settings
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Usage with Config File
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
# CLI will automatically find firestore-dart-gen.yaml
|
|
128
|
+
firestore-dart-gen
|
|
129
|
+
|
|
130
|
+
# Or specify a custom config file
|
|
131
|
+
firestore-dart-gen --config my-config.yaml
|
|
132
|
+
|
|
133
|
+
# Override config with CLI arguments
|
|
134
|
+
firestore-dart-gen --service-account other.json
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Priority Order
|
|
138
|
+
|
|
139
|
+
Configuration is resolved in this order (highest to lowest priority):
|
|
140
|
+
|
|
141
|
+
1. **CLI arguments** (e.g., `--service-account other.json`)
|
|
142
|
+
2. **Config file** (`firestore-dart-gen.yaml`)
|
|
143
|
+
3. **Environment variables** (`.env` file)
|
|
144
|
+
|
|
145
|
+
**Example:** If you have `serviceAccount` in the YAML but also pass `--service-account`, the CLI argument wins.
|
|
146
|
+
|
|
147
|
+
### Benefits
|
|
148
|
+
|
|
149
|
+
- ✅ Save time - no need to type credentials every run
|
|
150
|
+
- ✅ Pre-select collections you work with frequently
|
|
151
|
+
- ✅ Team consistency - share same defaults
|
|
152
|
+
- ✅ Flexible - can override with CLI args anytime
|
|
153
|
+
|
|
154
|
+
⚠️ **Important:** Add `firestore-dart-gen.yaml` to `.gitignore` if it contains sensitive paths!
|
|
155
|
+
|
|
156
|
+
## Usage
|
|
157
|
+
|
|
158
|
+
### Interactive Mode (Default) 🎮
|
|
159
|
+
|
|
160
|
+
The tool runs in interactive mode by default, providing a guided experience:
|
|
161
|
+
|
|
162
|
+
**Features:**
|
|
163
|
+
- 🔍 **Auto-discovery**: Automatically lists all collections in your project
|
|
164
|
+
- ✅ **Multiple selection**: Use checkboxes to select multiple collections at once
|
|
165
|
+
- 🌳 **Subcollection detection**: Automatically finds and offers to include subcollections
|
|
166
|
+
- ⚙️ **Easy configuration**: Configure output directory and sample size with prompts
|
|
167
|
+
- 📊 **Summary review**: See exactly what will be generated before confirming
|
|
168
|
+
|
|
169
|
+
**Run the interactive mode:**
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
firestore-dart-gen --service-account firebase_service_account.json
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
**Example Session:**
|
|
176
|
+
|
|
177
|
+
```
|
|
178
|
+
🔥 Firestore Dart Generator - Interactive Mode
|
|
179
|
+
|
|
180
|
+
✓ Connected to Firebase Project: my-awesome-app
|
|
181
|
+
|
|
182
|
+
🔍 Discovering collections...
|
|
183
|
+
|
|
184
|
+
Found 5 collection(s)
|
|
185
|
+
|
|
186
|
+
? Select collections to generate models for: (Use arrow keys, Space to select, Enter to confirm)
|
|
187
|
+
❯◯ users
|
|
188
|
+
◯ products
|
|
189
|
+
◯ orders
|
|
190
|
+
◯ reviews
|
|
191
|
+
◯ settings
|
|
192
|
+
|
|
193
|
+
🌳 Checking for subcollections...
|
|
194
|
+
|
|
195
|
+
Analyzing users...
|
|
196
|
+
Found 2 subcollection(s): profiles, settings
|
|
197
|
+
Include subcollections for users? (Y/n) Yes
|
|
198
|
+
|
|
199
|
+
? Output directory for generated Dart files: ./lib/src/models
|
|
200
|
+
? Number of documents to sample per collection: 20
|
|
201
|
+
|
|
202
|
+
📋 Generation Summary:
|
|
203
|
+
────────────────────────────────────────────────────────────
|
|
204
|
+
Firebase Project: my-awesome-app
|
|
205
|
+
Collections: users, products
|
|
206
|
+
Subcollections:
|
|
207
|
+
└─ users: profiles, settings
|
|
208
|
+
Output: ./lib/src/models
|
|
209
|
+
Sample Size: 20 documents per collection
|
|
210
|
+
────────────────────────────────────────────────────────────
|
|
211
|
+
|
|
212
|
+
? Generate Dart models with these settings? (Y/n) Yes
|
|
213
|
+
|
|
214
|
+
🚀 Starting generation...
|
|
215
|
+
|
|
216
|
+
📦 Processing collection: users
|
|
217
|
+
...
|
|
218
|
+
|
|
219
|
+
✨ Success! Generated 4 model(s)
|
|
220
|
+
|
|
221
|
+
Generated files:
|
|
222
|
+
✓ lib/src/models/user_dto.dart
|
|
223
|
+
✓ lib/src/models/profile_dto.dart
|
|
224
|
+
✓ lib/src/models/setting_dto.dart
|
|
225
|
+
✓ lib/src/models/product_dto.dart
|
|
226
|
+
|
|
227
|
+
📚 Next steps:
|
|
228
|
+
1. Review the generated files
|
|
229
|
+
2. Import the models in your Dart code
|
|
230
|
+
3. Add 'equatable' to your pubspec.yaml if not already present
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Legacy Usage (Advanced)
|
|
234
|
+
|
|
235
|
+
### Batch Mode (Legacy)
|
|
236
|
+
|
|
237
|
+
*Note: Interactive mode is now recommended for most use cases.*
|
|
238
|
+
|
|
239
|
+
Extract multiple collections using a YAML configuration file:
|
|
240
|
+
|
|
241
|
+
1. **Create `collections.yaml`** (or copy from `collections.example.yaml`):
|
|
242
|
+
|
|
243
|
+
```yaml
|
|
244
|
+
collections:
|
|
245
|
+
- name: users
|
|
246
|
+
output: ./lib/src/models
|
|
247
|
+
sampleSize: 20
|
|
248
|
+
subcollections:
|
|
249
|
+
- profiles
|
|
250
|
+
- settings
|
|
251
|
+
|
|
252
|
+
- name: products
|
|
253
|
+
output: ./lib/src/models
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
2. **Run the extractor**:
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
firestore-dart-gen batch --service-account firebase_service_account.json
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
That's it! All collections in the YAML file will be processed.
|
|
263
|
+
|
|
264
|
+
### Single Collection Mode (Legacy)
|
|
265
|
+
|
|
266
|
+
*Note: Interactive mode is now recommended for most use cases.*
|
|
267
|
+
|
|
268
|
+
For programmatic use or CI/CD, you can still extract collections using the old commands (requires custom wrapper):
|
|
269
|
+
|
|
270
|
+
```bash
|
|
271
|
+
firestore-dart-gen single \
|
|
272
|
+
--collection users \
|
|
273
|
+
--output ./lib/src/models \
|
|
274
|
+
--service-account firebase_service_account.json
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### With Subcollections
|
|
278
|
+
|
|
279
|
+
```bash
|
|
280
|
+
firestore-dart-gen single \
|
|
281
|
+
--collection orders \
|
|
282
|
+
--subcollections items,shipping_info \
|
|
283
|
+
--output ./lib/src/models \
|
|
284
|
+
--service-account firebase_service_account.json
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
## Command Line Options
|
|
288
|
+
|
|
289
|
+
### Interactive Mode (Default)
|
|
290
|
+
|
|
291
|
+
| Option | Required | Description | Default |
|
|
292
|
+
|--------|----------|-------------|---------|
|
|
293
|
+
| `--service-account <path>` | No | Path to service account JSON | From env |
|
|
294
|
+
| `--project-id <id>` | No | Firebase project ID | From env |
|
|
295
|
+
|
|
296
|
+
### Batch Mode (Legacy)
|
|
297
|
+
|
|
298
|
+
| Option | Alias | Required | Description | Default |
|
|
299
|
+
|--------|-------|----------|-------------|---------|
|
|
300
|
+
| `--config <path>` | `-f` | No | Path to collections.yaml | `collections.yaml` |
|
|
301
|
+
| `--service-account <path>` | - | No | Path to service account JSON | From env |
|
|
302
|
+
| `--project-id <id>` | - | No | Firebase project ID | From env |
|
|
303
|
+
|
|
304
|
+
### Single Mode
|
|
305
|
+
|
|
306
|
+
| Option | Alias | Required | Description | Default |
|
|
307
|
+
|--------|-------|----------|-------------|---------|
|
|
308
|
+
| `--collection <name>` | `-c` | Yes | Firestore collection name | - |
|
|
309
|
+
| `--output <path>` | `-o` | Yes | Output directory for Dart files | - |
|
|
310
|
+
| `--subcollections <names>` | `-s` | No | Comma-separated subcollections | - |
|
|
311
|
+
| `--service-account <path>` | - | No | Path to service account JSON | From env |
|
|
312
|
+
| `--project-id <id>` | - | No | Firebase project ID | From env |
|
|
313
|
+
| `--sample-size <number>` | - | No | Number of docs to sample | 20 |
|
|
314
|
+
|
|
315
|
+
## Configuration File
|
|
316
|
+
|
|
317
|
+
The `collections.yaml` file defines which collections to extract:
|
|
318
|
+
|
|
319
|
+
```yaml
|
|
320
|
+
collections:
|
|
321
|
+
# Simple collection
|
|
322
|
+
- name: users
|
|
323
|
+
output: ./lib/src/models
|
|
324
|
+
sampleSize: 20 # Optional: number of documents to sample (default: 20)
|
|
325
|
+
|
|
326
|
+
# Collection with subcollections
|
|
327
|
+
- name: orders
|
|
328
|
+
output: ./lib/src/models
|
|
329
|
+
subcollections:
|
|
330
|
+
- items # Will extract from orders/{orderId}/items
|
|
331
|
+
- shipping_info # Will extract from orders/{orderId}/shipping_info
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
## Generated Output
|
|
335
|
+
|
|
336
|
+
### Example Input (Firestore Document)
|
|
337
|
+
|
|
338
|
+
```json
|
|
339
|
+
{
|
|
340
|
+
"id": "user123",
|
|
341
|
+
"email": "user@example.com",
|
|
342
|
+
"name": "John Doe",
|
|
343
|
+
"age": 30,
|
|
344
|
+
"isActive": true,
|
|
345
|
+
"createdAt": Timestamp(2024-01-01),
|
|
346
|
+
"metadata": {
|
|
347
|
+
"source": "mobile"
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
### Generated Dart Model
|
|
353
|
+
|
|
354
|
+
```dart
|
|
355
|
+
import 'package:equatable/equatable.dart';
|
|
356
|
+
|
|
357
|
+
/// {@template user}
|
|
358
|
+
/// A model representing a users document from Firestore.
|
|
359
|
+
/// {@endtemplate}
|
|
360
|
+
class User extends Equatable {
|
|
361
|
+
/// {@macro user}
|
|
362
|
+
const User({
|
|
363
|
+
required this.id,
|
|
364
|
+
required this.email,
|
|
365
|
+
required this.isActive,
|
|
366
|
+
this.age,
|
|
367
|
+
this.name,
|
|
368
|
+
this.createdAt,
|
|
369
|
+
this.metadata,
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
/// Creates a [User] from a JSON map.
|
|
373
|
+
factory User.fromJson(Map<String, dynamic> json) {
|
|
374
|
+
return User(
|
|
375
|
+
id: json['id'] as String,
|
|
376
|
+
email: json['email'] as String,
|
|
377
|
+
isActive: json['isActive'] as bool,
|
|
378
|
+
age: json['age'] as int?,
|
|
379
|
+
name: json['name'] as String?,
|
|
380
|
+
createdAt: json['createdAt'] != null
|
|
381
|
+
? DateTime.parse(json['createdAt'] as String)
|
|
382
|
+
: null,
|
|
383
|
+
metadata: json['metadata'] as Map<String, dynamic>?,
|
|
384
|
+
);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/// The id field.
|
|
388
|
+
final String id;
|
|
389
|
+
|
|
390
|
+
/// The email field.
|
|
391
|
+
final String email;
|
|
392
|
+
|
|
393
|
+
/// The isActive field.
|
|
394
|
+
final bool isActive;
|
|
395
|
+
|
|
396
|
+
/// The age field.
|
|
397
|
+
final int? age;
|
|
398
|
+
|
|
399
|
+
/// The name field.
|
|
400
|
+
final String? name;
|
|
401
|
+
|
|
402
|
+
/// The createdAt field.
|
|
403
|
+
final DateTime? createdAt;
|
|
404
|
+
|
|
405
|
+
/// The metadata field.
|
|
406
|
+
final Map<String, dynamic>? metadata;
|
|
407
|
+
|
|
408
|
+
@override
|
|
409
|
+
List<Object?> get props => [
|
|
410
|
+
id,
|
|
411
|
+
email,
|
|
412
|
+
isActive,
|
|
413
|
+
age,
|
|
414
|
+
name,
|
|
415
|
+
createdAt,
|
|
416
|
+
metadata,
|
|
417
|
+
];
|
|
418
|
+
|
|
419
|
+
/// Converts this [User] to a JSON map.
|
|
420
|
+
Map<String, dynamic> toJson() {
|
|
421
|
+
return {
|
|
422
|
+
'id': id,
|
|
423
|
+
'email': email,
|
|
424
|
+
'isActive': isActive,
|
|
425
|
+
if (age != null) 'age': age,
|
|
426
|
+
if (name != null) 'name': name,
|
|
427
|
+
if (createdAt != null) 'createdAt': createdAt?.toIso8601String(),
|
|
428
|
+
if (metadata != null) 'metadata': metadata,
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
## Type Detection
|
|
435
|
+
|
|
436
|
+
The tool automatically detects and maps Firestore types to Dart types:
|
|
437
|
+
|
|
438
|
+
| Firestore Type | Dart Type |
|
|
439
|
+
|----------------|-----------|
|
|
440
|
+
| String | `String` |
|
|
441
|
+
| Number (integer) | `int` |
|
|
442
|
+
| Number (float) | `double` |
|
|
443
|
+
| Boolean | `bool` |
|
|
444
|
+
| Timestamp | `DateTime` |
|
|
445
|
+
| Array | `List<dynamic>` |
|
|
446
|
+
| Map | `Map<String, dynamic>` |
|
|
447
|
+
| Null/Mixed | `dynamic` |
|
|
448
|
+
|
|
449
|
+
### Optional Fields
|
|
450
|
+
|
|
451
|
+
- A field is marked **optional** (`field?`) if it doesn't appear in all sampled documents
|
|
452
|
+
- Optional fields use `if (field != null)` in `toJson()`
|
|
453
|
+
|
|
454
|
+
### Nullable Fields
|
|
455
|
+
|
|
456
|
+
- A field is marked **nullable** (`Type?`) if it has inconsistent types across documents
|
|
457
|
+
- Required fields present in all documents are non-nullable
|
|
458
|
+
|
|
459
|
+
## Workflow
|
|
460
|
+
|
|
461
|
+
### 1. Extract Schema
|
|
462
|
+
|
|
463
|
+
```bash
|
|
464
|
+
firestore-dart-gen single \
|
|
465
|
+
--collection users \
|
|
466
|
+
--output ./lib/src/models \
|
|
467
|
+
--service-account firebase_service_account.json
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
### 2. Review and Customize
|
|
471
|
+
|
|
472
|
+
**Note:** The tool automatically runs `dart format` on generated files, so formatting is already done!
|
|
473
|
+
|
|
474
|
+
The generated models are basic. You may want to:
|
|
475
|
+
|
|
476
|
+
- Add more detailed documentation
|
|
477
|
+
- Customize field names (if Firestore uses different naming)
|
|
478
|
+
- Add validation logic
|
|
479
|
+
- Use `json_serializable` for more complex scenarios
|
|
480
|
+
|
|
481
|
+
### 3. Import in Your Code
|
|
482
|
+
|
|
483
|
+
```dart
|
|
484
|
+
import 'package:your_package/models/user.dart';
|
|
485
|
+
|
|
486
|
+
final user = User.fromJson(firestoreDoc.data()!);
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
## Troubleshooting
|
|
490
|
+
|
|
491
|
+
### "Service account file not found"
|
|
492
|
+
|
|
493
|
+
Make sure the path to your service account JSON is correct. Use absolute paths or paths relative to your current directory.
|
|
494
|
+
|
|
495
|
+
### "No documents found in collection"
|
|
496
|
+
|
|
497
|
+
- Verify the collection name is correct
|
|
498
|
+
- Ensure the collection has at least one document
|
|
499
|
+
- Check Firebase rules allow read access for the service account
|
|
500
|
+
|
|
501
|
+
### "Multiple types detected" warning
|
|
502
|
+
|
|
503
|
+
This happens when a field has different types across documents. The tool will use `dynamic` type. Consider:
|
|
504
|
+
|
|
505
|
+
- Cleaning up inconsistent data in Firestore
|
|
506
|
+
- Manually editing the generated model to use the correct type
|
|
507
|
+
|
|
508
|
+
### "dart command not found" warning
|
|
509
|
+
|
|
510
|
+
The tool tries to auto-format generated files with `dart format`. If Dart SDK is not in your PATH, you'll see a warning:
|
|
511
|
+
|
|
512
|
+
```
|
|
513
|
+
⚠ Could not format files: dart command not found
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
This is **non-fatal** - your files are still generated correctly, just not formatted. To fix:
|
|
517
|
+
|
|
518
|
+
1. **Install Dart SDK** (if not installed): https://dart.dev/get-dart
|
|
519
|
+
2. **Add to PATH**: Make sure `dart` command is available in your terminal
|
|
520
|
+
3. **Manual format**: Run `dart format <output-directory>` manually after generation
|
|
521
|
+
|
|
522
|
+
Or ignore it - the generated code is valid, just might need manual formatting.
|
|
523
|
+
|
|
524
|
+
## Development
|
|
525
|
+
|
|
526
|
+
### Running Locally
|
|
527
|
+
|
|
528
|
+
1. Clone the repository
|
|
529
|
+
2. Install dependencies: `npm install`
|
|
530
|
+
3. Build: `npm run build`
|
|
531
|
+
4. Run: `npm run extract` or `npm run extract:single`
|
|
532
|
+
|
|
533
|
+
### Testing
|
|
534
|
+
|
|
535
|
+
The project includes comprehensive golden tests to ensure code generation quality:
|
|
536
|
+
|
|
537
|
+
```bash
|
|
538
|
+
# Run all tests
|
|
539
|
+
npm test
|
|
540
|
+
|
|
541
|
+
# Run tests in watch mode
|
|
542
|
+
npm run test:watch
|
|
543
|
+
|
|
544
|
+
# Run tests with coverage report
|
|
545
|
+
npm run test:coverage
|
|
546
|
+
|
|
547
|
+
# Update golden files (when intentionally changing output)
|
|
548
|
+
npm run test:update-goldens
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
Golden tests verify that the generated Dart code matches expected output exactly. See [test/README.md](test/README.md) for more details.
|
|
552
|
+
|
|
553
|
+
### Project Structure
|
|
554
|
+
|
|
555
|
+
```
|
|
556
|
+
firestore-dart-generator/
|
|
557
|
+
├── src/
|
|
558
|
+
│ ├── index.ts # CLI entry point
|
|
559
|
+
│ ├── firestore-client.ts # Firebase connection
|
|
560
|
+
│ ├── schema-analyzer.ts # Type detection logic
|
|
561
|
+
│ ├── dart-generator.ts # Code generation
|
|
562
|
+
│ ├── config-loader.ts # YAML config loader
|
|
563
|
+
│ ├── types.ts # TypeScript interfaces
|
|
564
|
+
│ └── templates/
|
|
565
|
+
│ └── model.hbs # Handlebars template
|
|
566
|
+
├── dist/ # Compiled JavaScript
|
|
567
|
+
├── package.json
|
|
568
|
+
├── tsconfig.json
|
|
569
|
+
└── README.md
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
## Security Notes
|
|
573
|
+
|
|
574
|
+
- ⚠️ **Never commit** service account JSON files
|
|
575
|
+
- Add `*service-account.json` to `.gitignore`
|
|
576
|
+
- Use environment variables for sensitive data
|
|
577
|
+
- Limit service account permissions to read-only Firestore access
|
|
578
|
+
|
|
579
|
+
## Contributing
|
|
580
|
+
|
|
581
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
582
|
+
|
|
583
|
+
## License
|
|
584
|
+
|
|
585
|
+
MIT
|
|
586
|
+
|
|
587
|
+
## Support
|
|
588
|
+
|
|
589
|
+
If you encounter any issues or have questions, please [open an issue](https://github.com/your-username/firestore-dart-generator/issues) on GitHub.
|
|
590
|
+
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export interface CLIConfig {
|
|
2
|
+
firebase?: {
|
|
3
|
+
serviceAccount?: string;
|
|
4
|
+
projectId?: string;
|
|
5
|
+
};
|
|
6
|
+
collections?: string[];
|
|
7
|
+
output?: {
|
|
8
|
+
directory?: string;
|
|
9
|
+
sampleSize?: number;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export declare class ConfigFileLoader {
|
|
13
|
+
private static CONFIG_FILES;
|
|
14
|
+
/**
|
|
15
|
+
* Load configuration from YAML file if exists
|
|
16
|
+
*/
|
|
17
|
+
static loadConfig(configPath?: string): CLIConfig | null;
|
|
18
|
+
/**
|
|
19
|
+
* Load config from specific path
|
|
20
|
+
*/
|
|
21
|
+
private static loadFromPath;
|
|
22
|
+
/**
|
|
23
|
+
* Validate configuration structure
|
|
24
|
+
*/
|
|
25
|
+
private static validateConfig;
|
|
26
|
+
/**
|
|
27
|
+
* Resolve service account path
|
|
28
|
+
*/
|
|
29
|
+
static resolveServiceAccountPath(config: CLIConfig | null, cliArg?: string): string | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* Resolve project ID
|
|
32
|
+
*/
|
|
33
|
+
static resolveProjectId(config: CLIConfig | null, cliArg?: string): string | undefined;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=config-file-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-file-loader.d.ts","sourceRoot":"","sources":["../src/config-file-loader.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,EAAE;QACT,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,MAAM,CAAC,EAAE;QACP,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAC,YAAY,CAKzB;IAEF;;OAEG;IACH,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAkBxD;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,YAAY;IAe3B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,cAAc;IAoB7B;;OAEG;IACH,MAAM,CAAC,yBAAyB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAS/F;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;CAMvF"}
|