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.
Files changed (40) hide show
  1. package/CONFIG_FILE_GUIDE.md +445 -0
  2. package/IMPLEMENTATION_SUMMARY.md +305 -0
  3. package/LICENSE +22 -0
  4. package/QUICK_START.md +241 -0
  5. package/README.md +590 -0
  6. package/dist/config-file-loader.d.ts +35 -0
  7. package/dist/config-file-loader.d.ts.map +1 -0
  8. package/dist/config-file-loader.js +130 -0
  9. package/dist/config-file-loader.js.map +1 -0
  10. package/dist/config-loader.d.ts +21 -0
  11. package/dist/config-loader.d.ts.map +1 -0
  12. package/dist/config-loader.js +125 -0
  13. package/dist/config-loader.js.map +1 -0
  14. package/dist/dart-generator.d.ts +35 -0
  15. package/dist/dart-generator.d.ts.map +1 -0
  16. package/dist/dart-generator.js +167 -0
  17. package/dist/dart-generator.js.map +1 -0
  18. package/dist/firestore-client.d.ts +49 -0
  19. package/dist/firestore-client.d.ts.map +1 -0
  20. package/dist/firestore-client.js +227 -0
  21. package/dist/firestore-client.js.map +1 -0
  22. package/dist/index.d.ts +3 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +65 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/interactive-cli.d.ts +5 -0
  27. package/dist/interactive-cli.d.ts.map +1 -0
  28. package/dist/interactive-cli.js +310 -0
  29. package/dist/interactive-cli.js.map +1 -0
  30. package/dist/schema-analyzer.d.ts +38 -0
  31. package/dist/schema-analyzer.d.ts.map +1 -0
  32. package/dist/schema-analyzer.js +350 -0
  33. package/dist/schema-analyzer.js.map +1 -0
  34. package/dist/templates/model.hbs +39 -0
  35. package/dist/types.d.ts +58 -0
  36. package/dist/types.d.ts.map +1 -0
  37. package/dist/types.js +3 -0
  38. package/dist/types.js.map +1 -0
  39. package/firestore-dart-gen.example.yaml +28 -0
  40. package/package.json +61 -0
@@ -0,0 +1,130 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.ConfigFileLoader = void 0;
40
+ const fs = __importStar(require("fs"));
41
+ const path = __importStar(require("path"));
42
+ const yaml = __importStar(require("js-yaml"));
43
+ const chalk_1 = __importDefault(require("chalk"));
44
+ class ConfigFileLoader {
45
+ /**
46
+ * Load configuration from YAML file if exists
47
+ */
48
+ static loadConfig(configPath) {
49
+ // If path provided, try to load it
50
+ if (configPath) {
51
+ return this.loadFromPath(configPath);
52
+ }
53
+ // Try default config file names
54
+ for (const fileName of this.CONFIG_FILES) {
55
+ const filePath = path.resolve(process.cwd(), fileName);
56
+ if (fs.existsSync(filePath)) {
57
+ console.log(chalk_1.default.gray(`📄 Found config file: ${fileName}\n`));
58
+ return this.loadFromPath(filePath);
59
+ }
60
+ }
61
+ return null;
62
+ }
63
+ /**
64
+ * Load config from specific path
65
+ */
66
+ static loadFromPath(filePath) {
67
+ try {
68
+ const fileContents = fs.readFileSync(filePath, 'utf8');
69
+ const config = yaml.load(fileContents);
70
+ // Validate basic structure
71
+ this.validateConfig(config);
72
+ return config;
73
+ }
74
+ catch (error) {
75
+ console.error(chalk_1.default.yellow(`âš  Could not load config file: ${error}`));
76
+ return null;
77
+ }
78
+ }
79
+ /**
80
+ * Validate configuration structure
81
+ */
82
+ static validateConfig(config) {
83
+ // Validate service account path if provided
84
+ if (config.firebase?.serviceAccount) {
85
+ const fullPath = path.resolve(process.cwd(), config.firebase.serviceAccount);
86
+ if (!fs.existsSync(fullPath)) {
87
+ console.warn(chalk_1.default.yellow(`âš  Service account file not found: ${config.firebase.serviceAccount}`));
88
+ }
89
+ }
90
+ // Validate collections is array if provided
91
+ if (config.collections && !Array.isArray(config.collections)) {
92
+ throw new Error('Config error: collections must be an array');
93
+ }
94
+ // Validate sample size if provided
95
+ if (config.output?.sampleSize && config.output.sampleSize < 1) {
96
+ throw new Error('Config error: sampleSize must be greater than 0');
97
+ }
98
+ }
99
+ /**
100
+ * Resolve service account path
101
+ */
102
+ static resolveServiceAccountPath(config, cliArg) {
103
+ // Priority: CLI argument > config file > env variable
104
+ if (cliArg)
105
+ return cliArg;
106
+ if (config?.firebase?.serviceAccount) {
107
+ return path.resolve(process.cwd(), config.firebase.serviceAccount);
108
+ }
109
+ return process.env.GOOGLE_APPLICATION_CREDENTIALS;
110
+ }
111
+ /**
112
+ * Resolve project ID
113
+ */
114
+ static resolveProjectId(config, cliArg) {
115
+ // Priority: CLI argument > config file > env variable
116
+ if (cliArg)
117
+ return cliArg;
118
+ if (config?.firebase?.projectId)
119
+ return config.firebase.projectId;
120
+ return process.env.FIREBASE_PROJECT_ID;
121
+ }
122
+ }
123
+ exports.ConfigFileLoader = ConfigFileLoader;
124
+ ConfigFileLoader.CONFIG_FILES = [
125
+ 'firestore-dart-gen.yaml',
126
+ 'firestore-dart-gen.yml',
127
+ '.firestore-dart-gen.yaml',
128
+ '.firestore-dart-gen.yml',
129
+ ];
130
+ //# sourceMappingURL=config-file-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-file-loader.js","sourceRoot":"","sources":["../src/config-file-loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { ConfigFile, CollectionConfig } from './types';
2
+ export declare class ConfigLoader {
3
+ /**
4
+ * Load collections configuration from YAML file
5
+ */
6
+ static loadConfig(configPath: string): ConfigFile;
7
+ /**
8
+ * Validate configuration structure
9
+ */
10
+ private static validateConfig;
11
+ /**
12
+ * Get all collections to process (including subcollections)
13
+ */
14
+ static getCollectionsToProcess(collectionConfig: CollectionConfig): Array<{
15
+ name: string;
16
+ output: string;
17
+ isSubcollection: boolean;
18
+ parentCollection?: string;
19
+ }>;
20
+ }
21
+ //# sourceMappingURL=config-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEvD,qBAAa,YAAY;IACvB;;OAEG;IACH,MAAM,CAAC,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU;IA0BjD;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,cAAc;IAkC7B;;OAEG;IACH,MAAM,CAAC,uBAAuB,CAAC,gBAAgB,EAAE,gBAAgB,GAAG,KAAK,CAAC;QACxE,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,eAAe,EAAE,OAAO,CAAC;QACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B,CAAC;CA2BH"}
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.ConfigLoader = void 0;
40
+ const fs = __importStar(require("fs"));
41
+ const path = __importStar(require("path"));
42
+ const yaml = __importStar(require("js-yaml"));
43
+ const chalk_1 = __importDefault(require("chalk"));
44
+ class ConfigLoader {
45
+ /**
46
+ * Load collections configuration from YAML file
47
+ */
48
+ static loadConfig(configPath) {
49
+ const fullPath = path.resolve(process.cwd(), configPath);
50
+ if (!fs.existsSync(fullPath)) {
51
+ throw new Error(`Configuration file not found: ${fullPath}`);
52
+ }
53
+ try {
54
+ const fileContents = fs.readFileSync(fullPath, 'utf8');
55
+ const config = yaml.load(fileContents);
56
+ // Validate configuration
57
+ this.validateConfig(config);
58
+ console.log(chalk_1.default.green(`✓ Loaded configuration from: ${configPath}`));
59
+ console.log(chalk_1.default.gray(` Found ${config.collections.length} collection(s) to process\n`));
60
+ return config;
61
+ }
62
+ catch (error) {
63
+ if (error instanceof Error) {
64
+ throw new Error(`Failed to parse configuration file: ${error.message}`);
65
+ }
66
+ throw error;
67
+ }
68
+ }
69
+ /**
70
+ * Validate configuration structure
71
+ */
72
+ static validateConfig(config) {
73
+ if (!config.collections || !Array.isArray(config.collections)) {
74
+ throw new Error('Configuration must have a "collections" array');
75
+ }
76
+ if (config.collections.length === 0) {
77
+ throw new Error('Configuration must have at least one collection');
78
+ }
79
+ config.collections.forEach((collection, index) => {
80
+ if (!collection.name) {
81
+ throw new Error(`Collection at index ${index} is missing "name" field`);
82
+ }
83
+ if (!collection.output) {
84
+ throw new Error(`Collection "${collection.name}" is missing "output" field`);
85
+ }
86
+ // Validate sample size if provided
87
+ if (collection.sampleSize !== undefined) {
88
+ if (typeof collection.sampleSize !== 'number' || collection.sampleSize < 1) {
89
+ throw new Error(`Collection "${collection.name}" has invalid sampleSize (must be a positive number)`);
90
+ }
91
+ }
92
+ // Validate subcollections if provided
93
+ if (collection.subcollections !== undefined) {
94
+ if (!Array.isArray(collection.subcollections)) {
95
+ throw new Error(`Collection "${collection.name}" subcollections must be an array`);
96
+ }
97
+ }
98
+ });
99
+ }
100
+ /**
101
+ * Get all collections to process (including subcollections)
102
+ */
103
+ static getCollectionsToProcess(collectionConfig) {
104
+ const collections = [
105
+ {
106
+ name: collectionConfig.name,
107
+ output: collectionConfig.output,
108
+ isSubcollection: false
109
+ }
110
+ ];
111
+ if (collectionConfig.subcollections && collectionConfig.subcollections.length > 0) {
112
+ collectionConfig.subcollections.forEach(subName => {
113
+ collections.push({
114
+ name: subName,
115
+ output: collectionConfig.output,
116
+ isSubcollection: true,
117
+ parentCollection: collectionConfig.name
118
+ });
119
+ });
120
+ }
121
+ return collections;
122
+ }
123
+ }
124
+ exports.ConfigLoader = ConfigLoader;
125
+ //# sourceMappingURL=config-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-loader.js","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import { SchemaInfo } from './types';
2
+ export declare class DartGenerator {
3
+ private template;
4
+ constructor();
5
+ /**
6
+ * Register Handlebars helpers
7
+ */
8
+ private registerHelpers;
9
+ /**
10
+ * Load the Handlebars template
11
+ */
12
+ private loadTemplate;
13
+ /**
14
+ * Generate Dart model code from schema
15
+ */
16
+ generateModel(schema: SchemaInfo): string;
17
+ /**
18
+ * Generate code for a nested class
19
+ */
20
+ private generateNestedClass;
21
+ /**
22
+ * Write Dart model to file
23
+ */
24
+ writeModelToFile(schema: SchemaInfo, outputDir: string): Promise<string>;
25
+ /**
26
+ * Convert PascalCase to snake_case
27
+ * Handles acronyms properly (e.g., UserDTO -> user_dto, Gamesv2DTO -> gamesv2_dto)
28
+ */
29
+ private toSnakeCase;
30
+ /**
31
+ * Generate barrel file (models.dart) that exports all models
32
+ */
33
+ generateBarrelFile(outputDir: string, modelFiles: string[]): Promise<void>;
34
+ }
35
+ //# sourceMappingURL=dart-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dart-generator.d.ts","sourceRoot":"","sources":["../src/dart-generator.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAA2C;;IAM3D;;OAEG;IACH,OAAO,CAAC,eAAe;IAOvB;;OAEG;IACH,OAAO,CAAC,YAAY;IAepB;;OAEG;IACH,aAAa,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM;IAsCzC;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAc3B;;OAEG;IACG,gBAAgB,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAqB9E;;;OAGG;IACH,OAAO,CAAC,WAAW;IAWnB;;OAEG;IACG,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAgBjF"}
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.DartGenerator = void 0;
40
+ const chalk_1 = __importDefault(require("chalk"));
41
+ const fs = __importStar(require("fs"));
42
+ const handlebars_1 = __importDefault(require("handlebars"));
43
+ const path = __importStar(require("path"));
44
+ class DartGenerator {
45
+ constructor() {
46
+ this.template = null;
47
+ this.registerHelpers();
48
+ }
49
+ /**
50
+ * Register Handlebars helpers
51
+ */
52
+ registerHelpers() {
53
+ // Helper to check equality
54
+ handlebars_1.default.registerHelper('eq', (a, b) => {
55
+ return a === b;
56
+ });
57
+ }
58
+ /**
59
+ * Load the Handlebars template
60
+ */
61
+ loadTemplate() {
62
+ if (this.template) {
63
+ return;
64
+ }
65
+ const templatePath = path.join(__dirname, 'templates', 'model.hbs');
66
+ if (!fs.existsSync(templatePath)) {
67
+ throw new Error(`Template file not found: ${templatePath}`);
68
+ }
69
+ const templateSource = fs.readFileSync(templatePath, 'utf8');
70
+ this.template = handlebars_1.default.compile(templateSource);
71
+ }
72
+ /**
73
+ * Generate Dart model code from schema
74
+ */
75
+ generateModel(schema) {
76
+ this.loadTemplate();
77
+ if (!this.template) {
78
+ throw new Error('Template not loaded');
79
+ }
80
+ console.log(chalk_1.default.blue(`Generating Dart code for ${schema.className}...`));
81
+ // Start with import statement
82
+ let code = "import 'package:equatable/equatable.dart';\n\n";
83
+ // Generate nested classes first
84
+ if (schema.nestedClasses && schema.nestedClasses.length > 0) {
85
+ const nestedClassesCode = schema.nestedClasses
86
+ .map(nestedSchema => this.generateNestedClass(nestedSchema))
87
+ .join('\n\n');
88
+ code += nestedClassesCode + '\n\n';
89
+ }
90
+ // Prepare template context with additional computed values
91
+ const templateContext = {
92
+ ...schema,
93
+ classNameLower: schema.className.toLowerCase(),
94
+ isNestedClass: false, // Main class is not nested
95
+ };
96
+ const mainCode = this.template(templateContext);
97
+ code += mainCode;
98
+ console.log(chalk_1.default.green(`✓ Generated ${schema.className} model`));
99
+ if (schema.nestedClasses && schema.nestedClasses.length > 0) {
100
+ console.log(chalk_1.default.green(` with ${schema.nestedClasses.length} nested class(es)`));
101
+ }
102
+ return code;
103
+ }
104
+ /**
105
+ * Generate code for a nested class
106
+ */
107
+ generateNestedClass(schema) {
108
+ if (!this.template) {
109
+ throw new Error('Template not loaded');
110
+ }
111
+ const templateContext = {
112
+ ...schema,
113
+ classNameLower: schema.className.toLowerCase(),
114
+ isNestedClass: true,
115
+ };
116
+ return this.template(templateContext);
117
+ }
118
+ /**
119
+ * Write Dart model to file
120
+ */
121
+ async writeModelToFile(schema, outputDir) {
122
+ const code = this.generateModel(schema);
123
+ // Ensure output directory exists
124
+ if (!fs.existsSync(outputDir)) {
125
+ fs.mkdirSync(outputDir, { recursive: true });
126
+ console.log(chalk_1.default.green(`✓ Created directory: ${outputDir}`));
127
+ }
128
+ // Convert class name to snake_case for filename
129
+ const fileName = this.toSnakeCase(schema.className) + '.dart';
130
+ const filePath = path.join(outputDir, fileName);
131
+ // Write file
132
+ fs.writeFileSync(filePath, code, 'utf8');
133
+ console.log(chalk_1.default.green(`✓ Written to: ${filePath}`));
134
+ return filePath;
135
+ }
136
+ /**
137
+ * Convert PascalCase to snake_case
138
+ * Handles acronyms properly (e.g., UserDTO -> user_dto, Gamesv2DTO -> gamesv2_dto)
139
+ */
140
+ toSnakeCase(str) {
141
+ return str
142
+ // Insert underscore before uppercase letters that follow lowercase letters
143
+ .replace(/([a-z])([A-Z])/g, '$1_$2')
144
+ // Insert underscore before uppercase letters that follow numbers
145
+ .replace(/([0-9])([A-Z])/g, '$1_$2')
146
+ // Insert underscore before uppercase letter followed by lowercase (for acronyms)
147
+ .replace(/([A-Z])([A-Z][a-z])/g, '$1_$2')
148
+ .toLowerCase();
149
+ }
150
+ /**
151
+ * Generate barrel file (models.dart) that exports all models
152
+ */
153
+ async generateBarrelFile(outputDir, modelFiles) {
154
+ const barrelPath = path.join(outputDir, 'models.dart');
155
+ const exports = modelFiles
156
+ .map(file => {
157
+ const fileName = path.basename(file);
158
+ return `export '${fileName}';`;
159
+ })
160
+ .join('\n');
161
+ const content = `// Generated barrel file for models\n${exports}\n`;
162
+ fs.writeFileSync(barrelPath, content, 'utf8');
163
+ console.log(chalk_1.default.green(`✓ Generated barrel file: ${barrelPath}`));
164
+ }
165
+ }
166
+ exports.DartGenerator = DartGenerator;
167
+ //# sourceMappingURL=dart-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dart-generator.js","sourceRoot":"","sources":["../src/dart-generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ import * as admin from 'firebase-admin';
2
+ export declare class FirestoreClient {
3
+ private projectId?;
4
+ private serviceAccountPath?;
5
+ private db;
6
+ private initialized;
7
+ constructor(projectId?: string | undefined, serviceAccountPath?: string | undefined);
8
+ /**
9
+ * Initialize Firebase Admin SDK
10
+ */
11
+ initialize(): Promise<void>;
12
+ /**
13
+ * Get Firestore instance
14
+ */
15
+ getFirestore(): admin.firestore.Firestore;
16
+ /**
17
+ * Fetch sample documents from a collection
18
+ */
19
+ fetchSampleDocuments(collectionPath: string, limit?: number): Promise<admin.firestore.DocumentSnapshot[]>;
20
+ /**
21
+ * Fetch sample documents from a subcollection
22
+ */
23
+ fetchSampleDocumentsFromSubcollection(parentCollectionPath: string, subcollectionName: string, limit?: number): Promise<admin.firestore.DocumentSnapshot[]>;
24
+ /**
25
+ * Check if collection exists
26
+ */
27
+ collectionExists(collectionPath: string): Promise<boolean>;
28
+ /**
29
+ * Check if subcollection exists
30
+ */
31
+ subcollectionExists(parentCollectionPath: string, subcollectionName: string): Promise<boolean>;
32
+ /**
33
+ * List all root-level collections in the database
34
+ */
35
+ listCollections(): Promise<string[]>;
36
+ /**
37
+ * List subcollections for a given collection (by checking first document)
38
+ */
39
+ listSubcollections(collectionPath: string): Promise<string[]>;
40
+ /**
41
+ * Get project ID from initialized Firebase app
42
+ */
43
+ getProjectId(): string | undefined;
44
+ /**
45
+ * Close Firebase connection
46
+ */
47
+ close(): Promise<void>;
48
+ }
49
+ //# sourceMappingURL=firestore-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"firestore-client.d.ts","sourceRoot":"","sources":["../src/firestore-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,gBAAgB,CAAC;AAKxC,qBAAa,eAAe;IAKxB,OAAO,CAAC,SAAS,CAAC;IAClB,OAAO,CAAC,kBAAkB,CAAC;IAL7B,OAAO,CAAC,EAAE,CAA0C;IACpD,OAAO,CAAC,WAAW,CAAS;gBAGlB,SAAS,CAAC,EAAE,MAAM,YAAA,EAClB,kBAAkB,CAAC,EAAE,MAAM,YAAA;IAGrC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAiDjC;;OAEG;IACH,YAAY,IAAI,KAAK,CAAC,SAAS,CAAC,SAAS;IAOzC;;OAEG;IACG,oBAAoB,CACxB,cAAc,EAAE,MAAM,EACtB,KAAK,GAAE,MAAW,GACjB,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,gBAAgB,EAAE,CAAC;IAqB9C;;OAEG;IACG,qCAAqC,CACzC,oBAAoB,EAAE,MAAM,EAC5B,iBAAiB,EAAE,MAAM,EACzB,KAAK,GAAE,MAAW,GACjB,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,gBAAgB,EAAE,CAAC;IAoC9C;;OAEG;IACG,gBAAgB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAShE;;OAEG;IACG,mBAAmB,CACvB,oBAAoB,EAAE,MAAM,EAC5B,iBAAiB,EAAE,MAAM,GACxB,OAAO,CAAC,OAAO,CAAC;IAwBnB;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAS1C;;OAEG;IACG,kBAAkB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAiBnE;;OAEG;IACH,YAAY,IAAI,MAAM,GAAG,SAAS;IAIlC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAO7B"}