22
33const fs = require ( 'fs' ) ;
44const path = require ( 'path' ) ;
5- const { execSync } = require ( 'child_process' ) ;
65
76// Configuration
87const PASSPORT_ROOT = './sample/Assets/Scripts/Passport' ;
@@ -26,75 +25,140 @@ try {
2625 // Create mapping of script filename to feature name
2726 featuresJson . features . forEach ( feature => {
2827 const [ featureName , scriptFile ] = Object . entries ( feature ) [ 0 ] ;
28+ // Store both the full filename and just the filename without path
2929 featuresMap [ scriptFile ] = featureName ;
30+ featuresMap [ path . basename ( scriptFile ) ] = featureName ;
3031 } ) ;
3132} catch ( error ) {
3233 console . error ( `Error reading features.json: ${ error . message } ` ) ;
3334 process . exit ( 1 ) ;
3435}
3536
36- // Find all metadata.json files
37+ // Platform-independent recursive file search
3738const findMetadataFiles = ( ) => {
38- const result = execSync ( `find "${ PASSPORT_ROOT } " -name "metadata.json" -type f` ) . toString ( ) . trim ( ) ;
39- return result . split ( '\n' ) . filter ( Boolean ) ;
39+ const metadataFiles = [ ] ;
40+
41+ const walkDir = ( dir ) => {
42+ if ( ! fs . existsSync ( dir ) ) {
43+ console . warn ( `Directory does not exist: ${ dir } ` ) ;
44+ return ;
45+ }
46+
47+ try {
48+ const files = fs . readdirSync ( dir ) ;
49+
50+ files . forEach ( file => {
51+ const filePath = path . join ( dir , file ) ;
52+
53+ try {
54+ const stat = fs . statSync ( filePath ) ;
55+
56+ if ( stat . isDirectory ( ) ) {
57+ walkDir ( filePath ) ;
58+ } else if ( file === 'metadata.json' ) {
59+ metadataFiles . push ( filePath ) ;
60+ }
61+ } catch ( err ) {
62+ console . warn ( `Error accessing file ${ filePath } : ${ err . message } ` ) ;
63+ }
64+ } ) ;
65+ } catch ( err ) {
66+ console . warn ( `Error reading directory ${ dir } : ${ err . message } ` ) ;
67+ }
68+ } ;
69+
70+ walkDir ( PASSPORT_ROOT ) ;
71+ return metadataFiles ;
4072} ;
4173
4274// Process metadata files
4375const processMetadataFiles = ( metadataFiles ) => {
44- const features = [ ] ;
76+ const featuresObject = { } ;
4577
4678 metadataFiles . forEach ( metadataFile => {
4779 console . log ( `Processing ${ metadataFile } ` ) ;
4880
4981 // Extract feature directory
5082 const featureDir = path . dirname ( metadataFile ) ;
5183
52- // Find script file in this directory
84+ // Get directory name as fallback feature name
85+ const dirName = path . basename ( featureDir ) ;
86+
87+ // Try to find feature name in feature map, fallback to directory name
5388 let featureName = '' ;
5489 try {
90+ // Look for any script file in this directory
5591 const dirFiles = fs . readdirSync ( featureDir ) ;
5692 const scriptFiles = dirFiles . filter ( file => file . endsWith ( '.cs' ) ) ;
5793
58- if ( scriptFiles . length > 0 ) {
59- // Look up the feature name in featuresMap
60- const scriptFile = scriptFiles [ 0 ] ;
61- featureName = featuresMap [ scriptFile ] || '' ;
94+ // Try to match any script file to our feature map
95+ let found = false ;
96+ for ( const scriptFile of scriptFiles ) {
97+ if ( featuresMap [ scriptFile ] ) {
98+ featureName = featuresMap [ scriptFile ] ;
99+ found = true ;
100+ break ;
101+ }
62102 }
63103
64- // If not found in features.json, fallback to directory name
65- if ( ! featureName ) {
66- console . warn ( `Feature for script in ${ featureDir } not found in features.json, using directory name` ) ;
67- featureName = path . basename ( featureDir ) ;
104+ if ( ! found ) {
105+ console . warn ( `No feature found in features.json for ${ featureDir } , using directory name` ) ;
106+ featureName = dirName ;
68107 }
69108 } catch ( error ) {
70109 console . warn ( `Error processing directory ${ featureDir } : ${ error . message } ` ) ;
71- featureName = path . basename ( featureDir ) ;
110+ featureName = dirName ;
111+ }
112+
113+ // Create feature key (kebab-case)
114+ const featureKey = featureName
115+ . replace ( / ( [ a - z ] ) ( [ A - Z ] ) / g, '$1-$2' )
116+ . replace ( / \s + / g, '-' )
117+ . replace ( / [ ^ a - z 0 - 9 - ] / gi, '' )
118+ . toLowerCase ( ) ;
119+
120+ if ( ! featureKey ) {
121+ console . warn ( `Generated empty feature key for ${ featureDir } , skipping` ) ;
122+ return ;
72123 }
73124
74- console . log ( `Feature name: ${ featureName } ` ) ;
125+ // Check for tutorial.md in the same directory
126+ const tutorialPath = path . join ( featureDir , 'tutorial.md' ) ;
127+ const tutorialExists = fs . existsSync ( tutorialPath ) ;
128+ const tutorialFile = tutorialExists ? `${ featureKey } .md` : null ;
129+
130+ if ( ! tutorialExists ) {
131+ console . warn ( `No tutorial.md found for feature ${ featureName } in ${ featureDir } ` ) ;
132+ }
75133
76134 // Read and process metadata
77135 try {
78136 const metadataContent = fs . readFileSync ( metadataFile , 'utf8' ) ;
79137 const metadata = JSON . parse ( metadataContent ) ;
80138
81- // Add feature name to metadata
82- metadata . name = featureName ;
83- features . push ( metadata ) ;
139+ // Add additional fields
140+ metadata . title = metadata . title || featureName ;
141+ metadata . sidebar_order = metadata . sidebar_order || 0 ;
142+ metadata . deprecated = metadata . deprecated || false ;
143+
144+ // Create the feature entry
145+ featuresObject [ featureKey ] = {
146+ tutorial : tutorialFile ,
147+ metadata : metadata
148+ } ;
84149 } catch ( error ) {
85150 console . error ( `Error processing metadata file ${ metadataFile } : ${ error . message } ` ) ;
86151 }
87152 } ) ;
88153
89- return features ;
154+ return featuresObject ;
90155} ;
91156
92157// Main execution
93158const metadataFiles = findMetadataFiles ( ) ;
94159const features = processMetadataFiles ( metadataFiles ) ;
95160
96161// Create the final passport-features.json
97- const passportFeatures = { features } ;
98- fs . writeFileSync ( OUTPUT_FILE , JSON . stringify ( passportFeatures , null , 2 ) ) ;
162+ fs . writeFileSync ( OUTPUT_FILE , JSON . stringify ( features , null , 2 ) ) ;
99163
100- console . log ( `Created ${ OUTPUT_FILE } ` ) ;
164+ console . log ( `Created ${ OUTPUT_FILE } ` ) ;
0 commit comments