@@ -6,29 +6,85 @@ import * as Protocol from '../src/index';
66
77const OUT_DIR = path . resolve ( __dirname , '../json-schema' ) ;
88
9+ /**
10+ * Safely ensure directory exists with retry logic
11+ */
12+ function ensureDir ( dirPath : string , retries = 3 ) : void {
13+ for ( let i = 0 ; i < retries ; i ++ ) {
14+ try {
15+ if ( ! fs . existsSync ( dirPath ) ) {
16+ fs . mkdirSync ( dirPath , { recursive : true } ) ;
17+ }
18+ // Verify the directory was created successfully
19+ if ( fs . existsSync ( dirPath ) && fs . statSync ( dirPath ) . isDirectory ( ) ) {
20+ return ;
21+ }
22+ } catch ( error ) {
23+ if ( i === retries - 1 ) {
24+ throw new Error ( `Failed to create directory ${ dirPath } : ${ error } ` ) ;
25+ }
26+ // Wait a bit before retrying
27+ const delay = 100 * ( i + 1 ) ;
28+ Atomics . wait ( new Int32Array ( new SharedArrayBuffer ( 4 ) ) , 0 , 0 , delay ) ;
29+ }
30+ }
31+ }
32+
33+ /**
34+ * Safely write file with retry logic
35+ */
36+ function writeFileWithRetry ( filePath : string , content : string , retries = 3 ) : void {
37+ for ( let i = 0 ; i < retries ; i ++ ) {
38+ try {
39+ // Ensure the parent directory exists
40+ const dir = path . dirname ( filePath ) ;
41+ ensureDir ( dir ) ;
42+
43+ fs . writeFileSync ( filePath , content ) ;
44+ return ;
45+ } catch ( error ) {
46+ if ( i === retries - 1 ) {
47+ throw new Error ( `Failed to write file ${ filePath } : ${ error } ` ) ;
48+ }
49+ // Wait a bit before retrying
50+ const delay = 100 * ( i + 1 ) ;
51+ Atomics . wait ( new Int32Array ( new SharedArrayBuffer ( 4 ) ) , 0 , 0 , delay ) ;
52+ }
53+ }
54+ }
55+
956// Clean output directory ensures no stale files remain
1057if ( fs . existsSync ( OUT_DIR ) ) {
1158 console . log ( `Cleaning output directory: ${ OUT_DIR } ` ) ;
1259 fs . rmSync ( OUT_DIR , { recursive : true , force : true , maxRetries : 3 , retryDelay : 100 } ) ;
60+
61+ // Wait a bit to ensure file system has synced
62+ // This prevents ENOENT errors on some file systems
63+ const syncDelay = 50 ;
64+ Atomics . wait ( new Int32Array ( new SharedArrayBuffer ( 4 ) ) , 0 , 0 , syncDelay ) ;
1365}
1466
1567// Ensure output directory exists
16- if ( ! fs . existsSync ( OUT_DIR ) ) {
17- fs . mkdirSync ( OUT_DIR , { recursive : true } ) ;
18- }
68+ ensureDir ( OUT_DIR ) ;
1969
2070console . log ( `Generating JSON Schemas to ${ OUT_DIR } ...` ) ;
2171
2272let count = 0 ;
73+ let errorCount = 0 ;
2374
2475// Protocol now exports namespaces (Data, UI, System, AI, API)
2576// We need to iterate through each namespace
2677for ( const [ namespaceName , namespaceExports ] of Object . entries ( Protocol ) ) {
2778 if ( typeof namespaceExports === 'object' && namespaceExports !== null ) {
2879 // Create category subdirectory (e.g., data, ui, system, ai, api)
2980 const categoryDir = path . join ( OUT_DIR , namespaceName . toLowerCase ( ) ) ;
30- if ( ! fs . existsSync ( categoryDir ) ) {
31- fs . mkdirSync ( categoryDir , { recursive : true } ) ;
81+
82+ try {
83+ ensureDir ( categoryDir ) ;
84+ } catch ( error ) {
85+ console . error ( `Failed to create directory for namespace ${ namespaceName } :` , error ) ;
86+ errorCount ++ ;
87+ continue ;
3288 }
3389
3490 console . log ( `\n[${ namespaceName } ]` ) ;
@@ -39,21 +95,31 @@ for (const [namespaceName, namespaceExports] of Object.entries(Protocol)) {
3995 if ( value instanceof z . ZodType ) {
4096 const schemaName = key . endsWith ( 'Schema' ) ? key . replace ( 'Schema' , '' ) : key ;
4197
42- // Convert to JSON Schema
43- const jsonSchema = zodToJsonSchema ( value , {
44- name : schemaName ,
45- $refStrategy : "none" // We want self-contained schemas for now
46- } ) ;
47-
48- const fileName = `${ schemaName } .json` ;
49- const filePath = path . join ( categoryDir , fileName ) ;
50-
51- fs . writeFileSync ( filePath , JSON . stringify ( jsonSchema , null , 2 ) ) ;
52- console . log ( `✓ ${ namespaceName . toLowerCase ( ) } /${ fileName } ` ) ;
53- count ++ ;
98+ try {
99+ // Convert to JSON Schema
100+ const jsonSchema = zodToJsonSchema ( value , {
101+ name : schemaName ,
102+ $refStrategy : "none" // We want self-contained schemas for now
103+ } ) ;
104+
105+ const fileName = `${ schemaName } .json` ;
106+ const filePath = path . join ( categoryDir , fileName ) ;
107+
108+ writeFileWithRetry ( filePath , JSON . stringify ( jsonSchema , null , 2 ) ) ;
109+ console . log ( `✓ ${ namespaceName . toLowerCase ( ) } /${ fileName } ` ) ;
110+ count ++ ;
111+ } catch ( error ) {
112+ console . error ( `Failed to generate schema for ${ namespaceName } .${ key } :` , error ) ;
113+ errorCount ++ ;
114+ }
54115 }
55116 }
56117 }
57118}
58119
59- console . log ( `\nSuccessfully generated ${ count } schemas.` ) ;
120+ if ( errorCount > 0 ) {
121+ console . error ( `\n❌ Completed with ${ errorCount } error(s). ${ count } schemas generated successfully.` ) ;
122+ process . exit ( 1 ) ;
123+ }
124+
125+ console . log ( `\n✅ Successfully generated ${ count } schemas.` ) ;
0 commit comments