@@ -34,36 +34,45 @@ function generateIdFromName(name: string): string {
34
34
let hash = 0 ;
35
35
for ( let i = 0 ; i < name . length ; i ++ ) {
36
36
const char = name . charCodeAt ( i ) ;
37
- hash = ( ( hash << 5 ) - hash ) + char ;
37
+ hash = ( hash << 5 ) - hash + char ;
38
38
hash = hash & hash ;
39
39
}
40
-
40
+
41
41
const hashStr = Math . abs ( hash ) . toString ( 16 ) . padStart ( 8 , '0' ) ;
42
- return `${ hashStr . slice ( 0 , 8 ) } -${ hashStr . slice ( 0 , 4 ) } -4${ hashStr . slice ( 1 , 4 ) } -${ hashStr . slice ( 0 , 4 ) } -${ hashStr } ${ hashStr . slice ( 0 , 4 ) } ` ;
42
+ return `${ hashStr . slice ( 0 , 8 ) } -${ hashStr . slice ( 0 , 4 ) } -4${ hashStr . slice (
43
+ 1 ,
44
+ 4
45
+ ) } -${ hashStr . slice ( 0 , 4 ) } -${ hashStr } ${ hashStr . slice ( 0 , 4 ) } `;
43
46
}
44
47
45
- function parseVersionNumber ( version : string , revision : string , release : string ) : number {
48
+ function parseVersionNumber (
49
+ version : string ,
50
+ revision : string ,
51
+ release : string
52
+ ) : number {
46
53
const versionNum = parseInt ( version ) || 0 ;
47
54
const revisionNum = revision . charCodeAt ( 0 ) - 65 ;
48
55
const releaseNum = parseInt ( release ) || 0 ;
49
-
56
+
50
57
return versionNum * 1000000 + revisionNum * 1000 + releaseNum ;
51
58
}
52
59
53
60
function parseNsDocFilename ( filename : string ) : NsDocFileInfo | null {
54
- const match = filename . match ( / ^ I E C _ 6 1 8 5 0 - ( [ 0 - 9 ] + - [ 0 - 9 ] + ) _ ( \d { 4 } ) ( [ A - Z ] ) ( \d + ) - e n \. n s d o c $ / ) ;
61
+ const match = filename . match (
62
+ / ^ I E C _ 6 1 8 5 0 - ( [ 0 - 9 ] + - [ 0 - 9 ] + ) _ ( \d { 4 } ) ( [ A - Z ] ) ( \d + ) - e n \. n s d o c $ /
63
+ ) ;
55
64
if ( match ) {
56
65
const [ , standardPart , version , revision , release ] = match ;
57
66
const id = `IEC 61850-${ standardPart } ` ;
58
67
const fullVersion = `${ version } ${ revision } ${ release } ` ;
59
-
68
+
60
69
return {
61
70
id,
62
71
version,
63
72
revision,
64
73
release,
65
74
filename,
66
- fullVersion
75
+ fullVersion,
67
76
} ;
68
77
}
69
78
return null ;
@@ -75,110 +84,123 @@ async function isValidNsDocFile(filename: string): Promise<boolean> {
75
84
if ( ! response . ok ) {
76
85
return false ;
77
86
}
78
-
87
+
79
88
const content = await response . text ( ) ;
80
89
const doc = new DOMParser ( ) . parseFromString ( content , 'text/xml' ) ;
81
90
const nsElement = doc . querySelector ( 'NSDoc' ) ;
82
91
const xmlns = nsElement ?. getAttribute ( 'xmlns' ) ;
83
-
92
+
84
93
return xmlns === 'http://www.iec.ch/61850/2016/NSD' ;
85
94
} catch ( error ) {
86
95
return false ;
87
96
}
88
97
}
89
98
90
-
91
99
// Get NSDOC files from manifest.json
92
100
async function getNsDocFilesFromManifest ( ) : Promise < string [ ] > {
93
101
try {
94
102
const manifestResponse = await fetch ( '/public/nsdoc/manifest.json' ) ;
95
103
if ( ! manifestResponse . ok ) {
96
104
return [ ] ;
97
105
}
98
-
106
+
99
107
const manifest = await manifestResponse . json ( ) ;
100
108
if ( ! Array . isArray ( manifest ) ) {
101
109
return [ ] ;
102
110
}
103
-
104
- const nsdocFiles = manifest . filter ( ( filename : unknown ) =>
105
- typeof filename === 'string' && filename . endsWith ( '-en.nsdoc' )
111
+
112
+ const nsdocFiles = manifest . filter (
113
+ ( filename : unknown ) =>
114
+ typeof filename === 'string' && filename . endsWith ( '-en.nsdoc' )
106
115
) as string [ ] ;
107
-
116
+
108
117
return nsdocFiles ;
109
-
110
118
} catch ( error ) {
111
119
return [ ] ;
112
120
}
113
121
}
114
122
115
123
// Discover NSDOC files using pattern-based approach (fallback)
116
- async function getNsDocFilesByPattern ( ) : Promise < string [ ] > {
124
+ async function getNsDocFilesByPattern ( ) : Promise < string [ ] > {
117
125
const standards = [ '7-2' , '7-3' , '7-4' , '8-1' ] ;
118
126
const versions = [ '2003A2' , '2007B3' , '2007B4' , '2007B5' ] ;
119
-
127
+
120
128
const potentialFiles : string [ ] = [ ] ;
121
129
for ( const standard of standards ) {
122
130
for ( const version of versions ) {
123
131
potentialFiles . push ( `IEC_61850-${ standard } _${ version } -en.nsdoc` ) ;
124
132
}
125
133
}
126
-
127
- const testPromises = potentialFiles . map ( async ( filename ) => {
134
+
135
+ const testPromises = potentialFiles . map ( async filename => {
128
136
try {
129
137
const response = await fetch ( `/public/nsdoc/${ filename } ` ) ;
130
138
return response . ok ? filename : null ;
131
139
} catch ( e ) {
132
140
return null ;
133
141
}
134
142
} ) ;
135
-
143
+
136
144
const existingFiles = await Promise . all ( testPromises ) ;
137
- const discoveredFiles = existingFiles . filter ( ( filename ) : filename is string => filename !== null ) ;
138
-
145
+ const discoveredFiles = existingFiles . filter (
146
+ ( filename ) : filename is string => filename !== null
147
+ ) ;
148
+
139
149
return discoveredFiles ;
140
150
}
141
151
142
- async function parseAndValidateNsDocFiles ( filenames : string [ ] ) : Promise < NsDocFileInfo [ ] > {
152
+ async function parseAndValidateNsDocFiles (
153
+ filenames : string [ ]
154
+ ) : Promise < NsDocFileInfo [ ] > {
143
155
const parsedFiles : NsDocFileInfo [ ] = [ ] ;
144
-
156
+
145
157
for ( const filename of filenames ) {
146
158
const fileInfo = parseNsDocFilename ( filename ) ;
147
159
if ( fileInfo ) {
148
160
const isValid = await isValidNsDocFile ( filename ) ;
149
161
if ( isValid ) {
150
162
parsedFiles . push ( fileInfo ) ;
151
163
} else {
152
- console . warn ( `Skipping invalid NSDOC file: ${ filename } (missing or incorrect schema)` ) ;
164
+ console . warn (
165
+ `Skipping invalid NSDOC file: ${ filename } (missing or incorrect schema)`
166
+ ) ;
153
167
}
154
168
}
155
169
}
156
-
170
+
157
171
return parsedFiles ;
158
172
}
159
173
160
174
function selectLatestVersions ( parsedFiles : NsDocFileInfo [ ] ) : NsDocFile [ ] {
161
175
const standardsMap = new Map < string , NsDocFileInfo > ( ) ;
162
-
176
+
163
177
for ( const fileInfo of parsedFiles ) {
164
178
const currentFileInMap = standardsMap . get ( fileInfo . id ) ;
165
-
179
+
166
180
if ( ! currentFileInMap ) {
167
181
standardsMap . set ( fileInfo . id , fileInfo ) ;
168
182
} else {
169
- const currentVersionNum = parseVersionNumber ( currentFileInMap . version , currentFileInMap . revision , currentFileInMap . release ) ;
170
- const newVersionNum = parseVersionNumber ( fileInfo . version , fileInfo . revision , fileInfo . release ) ;
171
-
183
+ const currentVersionNum = parseVersionNumber (
184
+ currentFileInMap . version ,
185
+ currentFileInMap . revision ,
186
+ currentFileInMap . release
187
+ ) ;
188
+ const newVersionNum = parseVersionNumber (
189
+ fileInfo . version ,
190
+ fileInfo . revision ,
191
+ fileInfo . release
192
+ ) ;
193
+
172
194
if ( newVersionNum > currentVersionNum ) {
173
195
standardsMap . set ( fileInfo . id , fileInfo ) ;
174
196
}
175
197
}
176
198
}
177
-
199
+
178
200
return Array . from ( standardsMap . values ( ) ) . map ( fileInfo => ( {
179
201
filename : fileInfo . filename ,
180
202
name : fileInfo . id ,
181
- id : generateIdFromName ( fileInfo . id + fileInfo . fullVersion )
203
+ id : generateIdFromName ( fileInfo . id + fileInfo . fullVersion ) ,
182
204
} ) ) ;
183
205
}
184
206
@@ -188,12 +210,14 @@ async function getNsDocFiles(): Promise<NsDocFile[]> {
188
210
if ( nsdocFiles . length === 0 ) {
189
211
nsdocFiles = await getNsDocFilesByPattern ( ) ;
190
212
}
191
-
213
+
192
214
if ( nsdocFiles . length === 0 ) {
193
- console . warn ( 'No NSDOC files found using either manifest or pattern-based discovery' ) ;
215
+ console . warn (
216
+ 'No NSDOC files found using either manifest or pattern-based discovery'
217
+ ) ;
194
218
return [ ] ;
195
219
}
196
-
220
+
197
221
const parsedFiles = await parseAndValidateNsDocFiles ( nsdocFiles ) ;
198
222
199
223
return selectLatestVersions ( parsedFiles ) ;
@@ -210,31 +234,33 @@ export function CompasNSDocFileService(): {
210
234
return {
211
235
async listNsdocFiles ( ) : Promise < NsDocListResponse > {
212
236
const nsDocFiles = await getNsDocFiles ( ) ;
213
-
237
+
214
238
return {
215
239
files : nsDocFiles . map ( ( nsDocFile : NsDocFile ) => ( {
216
240
id : nsDocFile . id ,
217
241
nsdocId : nsDocFile . name ,
218
242
filename : nsDocFile . filename ,
219
- checksum : nsDocFile . id
220
- } ) )
243
+ checksum : nsDocFile . id ,
244
+ } ) ) ,
221
245
} ;
222
246
} ,
223
247
224
248
async getNsdocFile ( id : string ) : Promise < NsdocContentResponse > {
225
249
const nsDocFiles = await getNsDocFiles ( ) ;
226
- const nsDocFile : NsDocFile | undefined = nsDocFiles . find ( ( f : NsDocFile ) => f . id === id ) ;
250
+ const nsDocFile : NsDocFile | undefined = nsDocFiles . find (
251
+ ( f : NsDocFile ) => f . id === id
252
+ ) ;
227
253
228
254
if ( ! nsDocFile ) {
229
255
return Promise . reject ( `Unable to find nsDoc file with id ${ id } ` ) ;
230
256
}
231
-
257
+
232
258
const content = await fetch ( `/public/nsdoc/${ nsDocFile . filename } ` )
233
259
. catch ( handleError )
234
260
. then ( handleResponse ) ;
235
-
261
+
236
262
return {
237
- content
263
+ content,
238
264
} ;
239
265
} ,
240
266
} ;
0 commit comments