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