1+ import * as vscode from 'vscode' ;
2+ import { getExtensionConfig , buildFilePath , modelOptionsToSet } from './configUtils' ;
3+ import { JsonCollectionInput } from "../configs/types"
4+ import { generateDartModel } from './dartGenUtils' ;
5+
6+ export async function generateCollectionModels ( ) : Promise < void > {
7+ // Get collection name first
8+ const collectionName = await vscode . window . showInputBox ( {
9+ placeHolder : 'Enter collection name (e.g. UserManagement, AuthSystem)' ,
10+ prompt : 'This will be used as the base folder name for all models in this collection.\nExample: "UserManagement" creates lib/data/models/user_management/ folder.'
11+ } ) ;
12+
13+ if ( ! collectionName ) return ;
14+
15+ // Get JSON collection input
16+ const jsonCollectionInput = await vscode . window . showInputBox ( {
17+ placeHolder : 'Paste your JSON collection here' ,
18+ prompt : 'Format: {"ModelName": {"type": "Request|Response", "data": {...}}, ...}\n\nExample:\n{\n "Login": {"type": "Request", "data": {"email": "", "password": ""}},\n "User": {"type": "Response", "data": {"id": 1, "name": "", "email": ""}}\n}' ,
19+ validateInput : text => {
20+ try {
21+ const parsed = JSON . parse ( text ) ;
22+ if ( typeof parsed !== 'object' || Array . isArray ( parsed ) ) {
23+ return 'Must be a JSON object with model definitions' ;
24+ }
25+
26+ // Validate structure
27+ for ( const [ key , value ] of Object . entries ( parsed ) ) {
28+ if ( ! value || typeof value !== 'object' ) {
29+ return `Invalid structure for "${ key } ": must be an object` ;
30+ }
31+ const item = value as any ;
32+ if ( ! item . type || ! [ 'Request' , 'Response' ] . includes ( item . type ) ) {
33+ return `Invalid type for "${ key } ": must be "Request" or "Response"` ;
34+ }
35+ if ( ! item . data || typeof item . data !== 'object' ) {
36+ return `Invalid data for "${ key } ": must be a valid JSON object` ;
37+ }
38+ }
39+ return null ;
40+ } catch ( e ) {
41+ return 'Invalid JSON format' ;
42+ }
43+ }
44+ } ) ;
45+
46+ if ( ! jsonCollectionInput ) return ;
47+
48+ try {
49+ const collection = parseJsonCollection ( jsonCollectionInput , collectionName ) ;
50+ await generateAllModelsFromCollection ( collection ) ;
51+ } catch ( error ) {
52+ vscode . window . showErrorMessage ( `Failed to parse collection: ${ error } ` ) ;
53+ }
54+ }
55+
56+ function parseJsonCollection ( input : string , collectionName : string ) : JsonCollectionInput {
57+ const parsed = JSON . parse ( input ) ;
58+ const jsonObjects = [ ] ;
59+
60+ for ( const [ modelName , config ] of Object . entries ( parsed ) ) {
61+ const item = config as any ;
62+ jsonObjects . push ( {
63+ name : modelName ,
64+ type : item . type ,
65+ json : item . data
66+ } ) ;
67+ }
68+
69+ return {
70+ collectionName,
71+ jsonObjects
72+ } ;
73+ }
74+
75+ async function generateAllModelsFromCollection ( collection : JsonCollectionInput ) : Promise < void > {
76+ const config = getExtensionConfig ( ) ;
77+ const workspaceFolder = vscode . workspace . workspaceFolders ?. [ 0 ] ;
78+
79+ if ( ! workspaceFolder ) {
80+ vscode . window . showWarningMessage ( 'No workspace folder found. Cannot create collection.' ) ;
81+ return ;
82+ }
83+
84+ const results : string [ ] = [ ] ;
85+ const errors : string [ ] = [ ] ;
86+
87+ // Show progress
88+ await vscode . window . withProgress ( {
89+ location : vscode . ProgressLocation . Notification ,
90+ title : `Generating ${ collection . jsonObjects . length } models for ${ collection . collectionName } ` ,
91+ cancellable : false
92+ } , async ( progress ) => {
93+ const increment = 100 / collection . jsonObjects . length ;
94+
95+ for ( let i = 0 ; i < collection . jsonObjects . length ; i ++ ) {
96+ const model = collection . jsonObjects [ i ] ;
97+ progress . report ( {
98+ increment,
99+ message : `Creating ${ model . name } ${ model . type } ...`
100+ } ) ;
101+
102+ try {
103+ const finalClassName = `${ model . name } ${ model . type } ` ;
104+ const relativePath = buildFilePath ( config , model . name , model . type ) ;
105+
106+ // For collections, we might want to group them under the collection name
107+ const collectionPath = relativePath . replace (
108+ config . baseFolder ,
109+ `${ config . baseFolder } /${ collection . collectionName . toLowerCase ( ) } `
110+ ) ;
111+
112+ const featuresSet = modelOptionsToSet ( config . modelOptions ) ;
113+ const dartCode = generateDartModel ( model . json , finalClassName , featuresSet ) ;
114+
115+ // Create directories
116+ const dirPath = vscode . Uri . joinPath ( workspaceFolder . uri , collectionPath . substring ( 0 , collectionPath . lastIndexOf ( '/' ) ) ) ;
117+ await vscode . workspace . fs . createDirectory ( dirPath ) ;
118+
119+ // Write file
120+ const fullPath = vscode . Uri . joinPath ( workspaceFolder . uri , collectionPath ) ;
121+ const encoder = new TextEncoder ( ) ;
122+ await vscode . workspace . fs . writeFile ( fullPath , encoder . encode ( dartCode ) ) ;
123+
124+ results . push ( collectionPath ) ;
125+
126+ } catch ( error ) {
127+ errors . push ( `${ model . name } ${ model . type } : ${ error } ` ) ;
128+ }
129+ }
130+ } ) ;
131+
132+ // Show results
133+ if ( results . length > 0 ) {
134+ const message = `Successfully generated ${ results . length } models in ${ collection . collectionName } ` ;
135+ vscode . window . showInformationMessage ( message ) ;
136+
137+ // Optionally show all created files
138+ const showFiles = await vscode . window . showInformationMessage (
139+ message ,
140+ 'Show Files'
141+ ) ;
142+
143+ if ( showFiles ) {
144+ const fileList = results . join ( '\n• ' ) ;
145+ vscode . window . showInformationMessage ( `Created files:\n• ${ fileList } ` ) ;
146+ }
147+ }
148+
149+ if ( errors . length > 0 ) {
150+ vscode . window . showErrorMessage ( `Failed to generate ${ errors . length } models. Check output for details.` ) ;
151+ console . error ( 'Generation errors:' , errors ) ;
152+ }
153+ }
0 commit comments