@@ -3,12 +3,12 @@ import { SalesforcePackageComponentFile } from './package';
3
3
import { outputFile } from 'fs-extra' ;
4
4
import { MetadataRegistry , MetadataType } from '../metadataRegistry' ;
5
5
import { injectable } from '@vlocode/core' ;
6
- import { asArray , substringBefore , XML } from '@vlocode/util' ;
6
+ import { asArray , count , substringBefore , XML } from '@vlocode/util' ;
7
7
import * as mimeTypes from 'mime-db' ;
8
8
9
9
interface MetadataFile extends SalesforcePackageComponentFile {
10
10
content ( ) : Promise < Buffer > ;
11
- metadata ( ) : Promise < ( object & { "@type" : string } ) | undefined > ;
11
+ metadata ( ) : Promise < object | undefined > ;
12
12
}
13
13
14
14
interface OutputFile {
@@ -20,35 +20,33 @@ export class MetadataExpander {
20
20
21
21
public async expandMetadata ( metadata : MetadataFile ) : Promise < Record < string , Buffer > > {
22
22
const content = await metadata . content ( ) ;
23
+ const metadataObj = await metadata . metadata ( ) ;
23
24
const type = MetadataRegistry . getMetadataType ( metadata . componentType ) ;
24
25
25
26
if ( type ?. childXmlNames . length ) {
26
27
return this . expandMetadataChildren ( metadata . componentName , type , XML . parse ( content ) ) ;
27
28
}
28
29
29
- const metadataObj = await metadata . metadata ( ) ;
30
- if ( ! metadataObj ) {
31
- return this . expandContentAsMeta ( metadata , content ) ;
32
- }
33
-
34
- if ( metadataObj [ '@type' ] === 'StaticResource' ) {
35
- return this . expandStaticResource ( metadata , content , metadataObj ) ;
30
+ if ( type ?. name === 'StaticResource' ) {
31
+ return metadataObj ? this . expandStaticResource ( metadata , content , metadataObj ) : { } ;
36
32
}
37
33
38
- return this . expandAsContent ( metadata , content ) ;
34
+ return this . expandContent ( metadata , content ) ;
39
35
}
40
36
41
37
private expandStaticResource ( metadata : MetadataFile , content : Buffer , meta : object ) : Record < string , Buffer > {
42
- const basename = this . baseName ( metadata . packagePath ) ;
38
+ const basename = this . baseName ( metadata . packagePath , true ) ;
43
39
const contentType = meta [ 'contentType' ] ?. toLowerCase ( ) ;
44
40
const mimeType = mimeTypes [ contentType ] ;
45
41
const suffix = mimeType ?. extensions ?. [ 0 ] || 'resource' ;
42
+ const metaXml = XML . stringify ( { StaticResource : meta } , { indent : 4 , attributePrefix : '@attributes' } ) ;
46
43
return {
47
- [ `${ basename } .${ suffix } ` ] : content
44
+ [ `${ basename } .${ suffix } ` ] : content ,
45
+ [ `${ basename } .${ suffix } -meta.xml` ] : Buffer . from ( metaXml )
48
46
} ;
49
47
}
50
-
51
- private expandContentAsMeta ( metadata : MetadataFile , content : Buffer ) : Record < string , Buffer > {
48
+
49
+ private expandContent ( metadata : MetadataFile , content : Buffer ) : Record < string , Buffer > {
52
50
const basename = this . baseName ( metadata . packagePath ) ;
53
51
const appendMetaXml = this . shouldAppendMetaXml ( metadata . packagePath , content ) ;
54
52
const expandedName = appendMetaXml ? `${ basename } -meta.xml` : basename ;
@@ -57,32 +55,36 @@ export class MetadataExpander {
57
55
} ;
58
56
}
59
57
60
- private expandAsContent ( metadata : MetadataFile , content : Buffer ) : Record < string , Buffer > {
61
- const basename = this . baseName ( metadata . packagePath ) ;
62
- return {
63
- [ basename ] : content
64
- } ;
65
- }
66
-
67
58
private expandMetadataChildren ( name : string , type : MetadataType , metadata : object ) : Record < string , Buffer > {
68
59
const expandedMetadata : Record < string , Buffer > = { } ;
69
60
70
- for ( const childType of Object . values ( type . children ?. types ?? { } ) ) {
71
- const childContent = metadata [ type . name ] [ childType . directoryName ] ;
61
+ if ( ! type . children ) {
62
+ throw new Error ( `Metadata type ${ type . name } does not have child types defined` ) ;
63
+ }
64
+
65
+ for ( const [ childNode , childTypeId ] of Object . entries ( type . children . directories ?? { } ) ) {
66
+ const childType = type . children . types [ childTypeId ] ;
67
+ const childContent = metadata [ type . name ] [ childNode ] ;
72
68
for ( const childItem of asArray ( childContent ?? [ ] ) ) {
73
- const childName = childItem . fullName ;
69
+ const childName = childType . uniqueIdElement ? childItem [ childType . uniqueIdElement ] : childItem . fullName ;
70
+ if ( ! childName ) {
71
+ throw new Error ( `Missing unique identifier for child type ${ childType . name } in metadata ${ type . name } ` ) ;
72
+ }
74
73
const childFileName = path . posix . join ( name , childType . directoryName , `${ childName } .${ childType . suffix } -meta.xml` ) ;
75
74
expandedMetadata [ childFileName ] = Buffer . from ( XML . stringify ( { [ childType . name ] : childItem } , 4 ) ) ;
76
75
}
77
76
78
77
if ( childContent ) {
79
- delete metadata [ type . name ] [ childType . directoryName ] ;
78
+ delete metadata [ type . name ] [ childNode ] ;
80
79
}
81
80
}
82
81
83
- const parentFileName = path . posix . join ( name , `${ name } .${ type . suffix } -meta.xml` ) ;
84
- expandedMetadata [ parentFileName ] = Buffer . from ( XML . stringify ( { [ type . name ] : metadata [ type . name ] } , 4 ) ) ;
85
-
82
+ const isParentEmpty = count ( Object . keys ( metadata [ type . name ] ) , key => key != '$' ) === 0 ;
83
+ if ( ! isParentEmpty ) {
84
+ // Do not include parent metadata if it has no children
85
+ const parentFileName = path . posix . join ( name , `${ name } .${ type . suffix } -meta.xml` ) ;
86
+ expandedMetadata [ parentFileName ] = Buffer . from ( XML . stringify ( { [ type . name ] : metadata [ type . name ] } , 4 ) ) ;
87
+ }
86
88
return expandedMetadata ;
87
89
}
88
90
0 commit comments