1- import { ResourceConfig } from '../entities/resource-config.js' ;
2-
3- import * as jsonSourceMap from 'json-source-map' ;
1+ import detectIndent from 'detect-indent' ;
42import jju from 'jju'
53
6- import { FileType , InMemoryFile } from '../parser/entities.js' ;
7- import { SourceMap , SourceMapCache } from '../parser/source-maps.js' ;
8- import detectIndent from 'detect-indent' ;
94import { Project } from '../entities/project.js' ;
105import { ProjectConfig } from '../entities/project-config.js' ;
6+ import { ResourceConfig } from '../entities/resource-config.js' ;
7+ import { FileType , InMemoryFile } from '../parser/entities.js' ;
8+ import { SourceMap } from '../parser/source-maps.js' ;
119import { prettyFormatFileDiff } from '../ui/file-diff-pretty-printer.js' ;
12- import { deepEqual } from './index.js' ;
13-
14- export enum ModificationType {
15- INSERT_OR_UPDATE ,
16- DELETE
17- }
18-
19- export interface ModifiedResource {
20- resource : ResourceConfig ;
21- modification : ModificationType
22- }
23-
24- export interface FileModificationResult {
25- newFile : string ;
26- diff : string ;
27- }
10+ import { deepEqual } from '../utils/index.js' ;
11+ import { FileModificationResult , ModificationType , ModifiedResource } from './index.js' ;
2812
2913export class FileModificationCalculator {
30- private existingFile : InMemoryFile ;
14+ private readonly existingFile : InMemoryFile ;
3115 private existingConfigs : ResourceConfig [ ] ;
32- private sourceMap : SourceMap ;
16+ private readonly sourceMap : SourceMap ;
3317 private totalConfigLength : number ;
34- private indentString : string ;
18+ private readonly indentString : string ;
3519
3620 constructor ( existing : Project ) {
37- const { file, sourceMap } = existing . sourceMaps ? .getSourceMap ( existing . codifyFiles [ 0 ] ) ! ;
21+ const { file, sourceMap } = existing . sourceMaps ! . getSourceMap ( existing . codifyFiles [ 0 ] ) ! ;
3822 this . existingFile = file ;
3923 this . sourceMap = sourceMap ;
4024 this . existingConfigs = [ ...existing . resourceConfigs ] ;
@@ -69,12 +53,11 @@ export class FileModificationCalculator {
6953 continue ;
7054 }
7155
72- const duplicateSourceKey = existing . sourceMapKey ?. split ( '#' ) . at ( 1 ) ! ;
73- const sourceIndex = Number . parseInt ( duplicateSourceKey . split ( '/' ) . at ( 1 ) ! )
74- const isOnly = this . totalConfigLength === 1 ;
56+ const duplicateSourceKey = existing . sourceMapKey ! . split ( '#' ) . at ( 1 ) ! ;
57+ const sourceIndex = Number . parseInt ( duplicateSourceKey . split ( '/' ) . at ( 1 ) ! , 10 )
7558
7659 if ( modified . modification === ModificationType . DELETE ) {
77- newFile = this . remove ( newFile , this . sourceMap , sourceIndex , isOnly ) ;
60+ newFile = this . remove ( newFile , sourceIndex ) ;
7861 this . totalConfigLength -= 1 ;
7962
8063 continue ;
@@ -99,7 +82,7 @@ export class FileModificationCalculator {
9982 }
10083
10184 return {
102- newFile : newFile ,
85+ newFile,
10386 diff : prettyFormatFileDiff ( this . existingFile . contents , newFile ) ,
10487 }
10588 }
@@ -110,7 +93,7 @@ export class FileModificationCalculator {
11093 return ;
11194 }
11295
113- if ( this . existingFile ?. fileType !== FileType . JSON && this . existingFile ?. fileType !== FileType . JSON5 && this . existingFile ?. fileType !== FileType . JSONC ) {
96+ if ( this . existingFile ?. fileType !== FileType . JSON && this . existingFile ?. fileType !== FileType . JSON5 && this . existingFile ?. fileType !== FileType . JSONC && this . existingFile ?. fileType !== FileType . CLOUD ) {
11497 throw new Error ( `Only updating .json, .json5, and .jsonc files are currently supported. Found ${ this . existingFile ?. filePath } ` ) ;
11598 }
11699
@@ -167,9 +150,7 @@ export class FileModificationCalculator {
167150
168151 private remove (
169152 file : string ,
170- sourceMap : SourceMap ,
171153 sourceIndex : number ,
172- isOnly : boolean ,
173154 ) : string {
174155 const isLast = sourceIndex === this . totalConfigLength - 1 ;
175156 const isFirst = sourceIndex === 0 ;
@@ -200,42 +181,18 @@ export class FileModificationCalculator {
200181 ) : string {
201182 // Updates: for now let's remove and re-add the entire object. Only two formatting availalbe either same line or multi-line
202183 const { value, valueEnd } = this . sourceMap . lookup ( `/${ sourceIndex } ` ) ! ;
203- const isFirst = sourceIndex === 0 ;
204184 const sortedResource = this . sortKeys ( resource . raw , existing . raw ) ;
205185
206- let content = jju . update ( file . slice ( value . position , valueEnd . position ) , sortedResource )
207- return this . splice ( file , value ?. position ! , valueEnd . position - value . position , content ) ;
208- }
209-
210- /** Attempt to make arrays and objects oneliners if they were before. It does this by creating a new source map */
211- private updateParamsToOnelineIfNeeded ( content : string , sourceMap : SourceMap , sourceIndex : number ) : string {
212- // Attempt to make arrays and objects oneliners if they were before. It does this by creating a new source map
213- const parsedContent = JSON . parse ( content ) ;
214- const parsedPointers = jsonSourceMap . parse ( content ) ;
215- const parsedSourceMap = new SourceMapCache ( )
216- parsedSourceMap . addSourceMap ( { filePath : '' , fileType : FileType . JSON , contents : parsedContent } , parsedPointers ) ;
217-
218- for ( const [ key , value ] of Object . entries ( parsedContent ) ) {
219- const source = sourceMap . lookup ( `/${ sourceIndex } /${ key } ` ) ;
220- if ( ( Array . isArray ( value ) || typeof value === 'object' ) && source && source . value . line === source . valueEnd . line ) {
221- const { value, valueEnd } = parsedSourceMap . lookup ( `#/${ key } ` ) !
222- content = this . splice (
223- content ,
224- value . position , valueEnd . position - value . position ,
225- JSON . stringify ( parsedContent [ key ] ) . replaceAll ( '\n' , '' ) . replaceAll ( / } $ / g, ' }' )
226- )
227- }
228- }
229-
230- return content ;
186+ const content = jju . update ( file . slice ( value . position , valueEnd . position ) , sortedResource )
187+ return this . splice ( file , value . position ! , valueEnd . position - value . position , content ) ;
231188 }
232189
233190 private splice ( s : string , start : number , deleteCount = 0 , insert = '' ) {
234- return s . substring ( 0 , start ) + insert + s . substring ( start + deleteCount ) ;
191+ return s . slice ( 0 , start ) + insert + s . slice ( start + deleteCount ) ;
235192 }
236193
237194 private removeSlice ( s : string , start : number , end : number ) {
238- return s . substring ( 0 , start ) + s . substring ( end ) ;
195+ return s . slice ( 0 , start ) + s . slice ( end ) ;
239196 }
240197
241198 private isResourceConfig ( config : ProjectConfig | ResourceConfig ) : config is ResourceConfig {
@@ -244,7 +201,7 @@ export class FileModificationCalculator {
244201
245202 private sortKeys ( obj : Record < string , unknown > , referenceOrder ?: Record < string , unknown > ) : Record < string , unknown > {
246203 const reference = Object . keys ( referenceOrder
247- ?? Object . fromEntries ( [ ... Object . keys ( obj ) ] . sort ( ) . map ( ( k ) => [ k , undefined ] ) )
204+ ?? Object . fromEntries ( Object . keys ( obj ) . sort ( ) . map ( ( k ) => [ k , undefined ] ) )
248205 ) ;
249206
250207 return Object . fromEntries (
@@ -262,7 +219,7 @@ export class FileModificationCalculator {
262219 )
263220 }
264221
265- private fileTypeString ( fileType : FileType ) : 'json ' | 'json5 ' | 'cjson ' {
222+ private fileTypeString ( fileType : FileType ) : 'cjson ' | 'json ' | 'json5 ' {
266223 if ( fileType === FileType . JSON ) {
267224 return 'json'
268225 }
@@ -275,6 +232,10 @@ export class FileModificationCalculator {
275232 return 'cjson'
276233 }
277234
235+ if ( fileType === FileType . CLOUD ) {
236+ return 'cjson'
237+ }
238+
278239 throw new Error ( `Unsupported file type ${ fileType } when trying to generate new configs` ) ;
279240 }
280241}
0 commit comments