1
+ #!/usr/bin/env node
2
+
3
+ 'use strict' ;
4
+
5
+ const fs = require ( 'fs' ) ;
6
+ const path = require ( 'path' ) ;
7
+
8
+ // Configuration
9
+ const PASSPORT_ROOT = './sample/Assets/Scripts/Passport' ;
10
+ const TUTORIALS_DIR = path . join ( PASSPORT_ROOT , '_tutorials' ) ;
11
+ const OUTPUT_DIR = './_parsed' ;
12
+ const OUTPUT_FILE = path . join ( OUTPUT_DIR , 'passport-features.json' ) ;
13
+ const FEATURES_JSON_PATH = path . join ( PASSPORT_ROOT , 'features.json' ) ;
14
+
15
+ // Ensure output directory exists
16
+ try {
17
+ if ( ! fs . existsSync ( OUTPUT_DIR ) ) {
18
+ fs . mkdirSync ( OUTPUT_DIR , { recursive : true } ) ;
19
+ }
20
+ } catch ( error ) {
21
+ console . error ( `Error creating output directory: ${ error . message } ` ) ;
22
+ process . exit ( 1 ) ;
23
+ }
24
+
25
+ console . log ( 'Processing Passport features metadata...' ) ;
26
+
27
+ // Load features.json to get feature groups and their features
28
+ let featureGroups = { } ;
29
+ try {
30
+ const featuresContent = fs . readFileSync ( FEATURES_JSON_PATH , 'utf8' ) ;
31
+ const featuresJson = JSON . parse ( featuresContent ) ;
32
+ featureGroups = featuresJson . features || { } ;
33
+ } catch ( error ) {
34
+ console . error ( `Error reading features.json: ${ error . message } ` ) ;
35
+ process . exit ( 1 ) ;
36
+ }
37
+
38
+ // Find all feature group directories in _tutorials
39
+ const findFeatureGroupDirectories = ( ) => {
40
+ const featureGroupDirs = [ ] ;
41
+
42
+ if ( ! fs . existsSync ( TUTORIALS_DIR ) ) {
43
+ console . warn ( `Tutorials directory does not exist: ${ TUTORIALS_DIR } ` ) ;
44
+ return featureGroupDirs ;
45
+ }
46
+
47
+ try {
48
+ const dirs = fs . readdirSync ( TUTORIALS_DIR , { withFileTypes : true } ) ;
49
+
50
+ dirs . forEach ( ( dirent ) => {
51
+ if ( dirent . isDirectory ( ) ) {
52
+ featureGroupDirs . push ( path . join ( TUTORIALS_DIR , dirent . name ) ) ;
53
+ }
54
+ } ) ;
55
+ } catch ( err ) {
56
+ console . warn ( `Error reading tutorials directory ${ TUTORIALS_DIR } : ${ err . message } ` ) ;
57
+ }
58
+
59
+ return featureGroupDirs ;
60
+ } ;
61
+
62
+ // Process metadata files
63
+ const processFeatureGroups = ( featureGroupDirs ) => {
64
+ const featuresObject = { } ;
65
+
66
+ featureGroupDirs . forEach ( ( groupDir ) => {
67
+ const groupName = path . basename ( groupDir ) ;
68
+ console . log ( `Processing feature group: ${ groupName } ` ) ;
69
+
70
+ // Check if this group exists in features.json (case-insensitive)
71
+ const matchingGroup = Object . keys ( featureGroups ) . find (
72
+ key => key . toLowerCase ( ) === groupName . toLowerCase ( )
73
+ ) ;
74
+
75
+ if ( ! matchingGroup ) {
76
+ console . warn ( `Feature group ${ groupName } not found in features.json, skipping` ) ;
77
+ return ;
78
+ }
79
+
80
+ // Path to metadata.json in this feature group directory
81
+ const metadataPath = path . join ( groupDir , 'metadata.json' ) ;
82
+ if ( ! fs . existsSync ( metadataPath ) ) {
83
+ console . warn ( `No metadata.json found for feature group ${ groupName } in ${ groupDir } ` ) ;
84
+ return ;
85
+ }
86
+
87
+ // Path to tutorial.md in this feature group directory
88
+ const tutorialPath = path . join ( groupDir , 'tutorial.md' ) ;
89
+ const tutorialExists = fs . existsSync ( tutorialPath ) ;
90
+
91
+ // Use the folder name directly as the feature key
92
+ const featureKey = groupName ;
93
+
94
+ if ( ! featureKey ) {
95
+ console . warn ( `Generated empty feature key for ${ groupDir } , skipping` ) ;
96
+ return ;
97
+ }
98
+
99
+ const tutorialFile = tutorialExists ? `${ featureKey } .md` : null ;
100
+
101
+ if ( ! tutorialExists ) {
102
+ console . warn ( `No tutorial.md found for feature group ${ groupName } in ${ groupDir } ` ) ;
103
+ }
104
+
105
+ // Read and process metadata
106
+ try {
107
+ const metadataContent = fs . readFileSync ( metadataPath , 'utf8' ) ;
108
+ const metadata = JSON . parse ( metadataContent ) ;
109
+
110
+ // Add additional fields
111
+ metadata . title = metadata . title || matchingGroup ;
112
+ metadata . sidebar_order = metadata . sidebar_order || 0 ;
113
+ metadata . deprecated = metadata . deprecated || false ;
114
+
115
+ // Add feature group information
116
+ metadata . feature_group = matchingGroup ;
117
+ metadata . features = Object . keys ( featureGroups [ matchingGroup ] || { } ) ;
118
+
119
+ // Create the feature entry
120
+ featuresObject [ featureKey ] = {
121
+ tutorial : tutorialFile ,
122
+ metadata : metadata
123
+ } ;
124
+ } catch ( error ) {
125
+ console . error ( `Error processing metadata file ${ metadataPath } : ${ error . message } ` ) ;
126
+ }
127
+ } ) ;
128
+
129
+ return featuresObject ;
130
+ } ;
131
+
132
+ try {
133
+ // Main execution
134
+ const featureGroupDirs = findFeatureGroupDirectories ( ) ;
135
+
136
+ if ( featureGroupDirs . length === 0 ) {
137
+ console . warn ( 'No feature group directories found. Output file will be empty.' ) ;
138
+ }
139
+
140
+ const features = processFeatureGroups ( featureGroupDirs ) ;
141
+
142
+ // Create the final passport-features.json
143
+ fs . writeFileSync ( OUTPUT_FILE , JSON . stringify ( features , null , 2 ) ) ;
144
+ console . log ( `Created ${ OUTPUT_FILE } ` ) ;
145
+ } catch ( error ) {
146
+ console . error ( `Fatal error: ${ error . message } ` ) ;
147
+ process . exit ( 1 ) ;
148
+ }
0 commit comments