@@ -178,6 +178,9 @@ export default async function validateModel (apiModel: model.Model, restSpec: Ma
178
178
return ep . request != null && ep . response != null
179
179
}
180
180
181
+ // Check that all type names are unique
182
+ validateUniqueTypeNames ( apiModel , modelError )
183
+
181
184
// Validate all endpoints. We start by those that are ready for validation so that transitive validation of common
182
185
// data types is associated with these endpoints and their errors are not filtered out in the error report.
183
186
apiModel . endpoints . filter ( ep => readyForValidation ( ep ) ) . forEach ( validateEndpoint )
@@ -204,6 +207,63 @@ export default async function validateModel (apiModel: model.Model, restSpec: Ma
204
207
205
208
// -----------------------------------------------------------------------------------------------
206
209
210
+ /**
211
+ * Validates that all type names in the model are unique
212
+ */
213
+ function validateUniqueTypeNames ( apiModel : model . Model , modelError : ( msg : string ) => void ) : void {
214
+ const existingDuplicates : Record < string , string [ ] > = {
215
+ Action : [ 'indices.modify_data_stream' , 'indices.update_aliases' , 'watcher._types' ] ,
216
+ Actions : [ 'ilm._types' , 'security.put_privileges' , 'watcher._types' ] ,
217
+ ComponentTemplate : [ 'cat.component_templates' , 'cluster._types' ] ,
218
+ Context : [ '_global.get_script_context' , '_global.search._types' , 'nodes._types' ] ,
219
+ DatabaseConfigurationMetadata : [ 'ingest.get_geoip_database' , 'ingest.get_ip_location_database' ] ,
220
+ Datafeed : [ 'ml._types' , 'xpack.usage' ] ,
221
+ Destination : [ '_global.reindex' , 'transform._types' ] ,
222
+ Feature : [ 'features._types' , 'indices.get' , 'xpack.info' ] ,
223
+ Features : [ 'indices.get' , 'xpack.info' ] ,
224
+ Filter : [ '_global.termvectors' , 'ml._types' ] ,
225
+ IndexingPressure : [ 'cluster.stats' , 'indices._types' , 'nodes._types' ] ,
226
+ IndexingPressureMemory : [ 'cluster.stats' , 'indices._types' , 'nodes._types' ] ,
227
+ Ingest : [ 'ingest._types' , 'nodes._types' ] ,
228
+ MigrationFeature : [ 'migration.get_feature_upgrade_status' , 'migration.post_feature_upgrade' ] ,
229
+ Operation : [ '_global.mget' , '_global.mtermvectors' ] ,
230
+ Phase : [ 'ilm._types' , 'xpack.usage' ] ,
231
+ Phases : [ 'ilm._types' , 'xpack.usage' ] ,
232
+ Pipeline : [ 'ingest._types' , 'logstash._types' ] ,
233
+ Policy : [ 'enrich._types' , 'ilm._types' , 'slm._types' ] ,
234
+ RequestItem : [ '_global.msearch' , '_global.msearch_template' ] ,
235
+ ResponseItem : [ '_global.bulk' , '_global.mget' , '_global.msearch' ] ,
236
+ RoleMapping : [ 'security._types' , 'xpack.usage' ] ,
237
+ RuntimeFieldTypes : [ 'cluster.stats' , 'xpack.usage' ] ,
238
+ ShardsStats : [ 'indices.field_usage_stats' , 'snapshot._types' ] ,
239
+ ShardStats : [ 'ccr._types' , 'indices.stats' ] ,
240
+ Source : [ '_global.reindex' , 'transform._types' ] ,
241
+ Token : [ '_global.termvectors' , 'security.authenticate' , 'security.create_service_token' , 'security.enroll_kibana' ]
242
+ }
243
+
244
+ // collect namespaces for each type name
245
+ const typeNames = new Map < string , string [ ] > ( )
246
+ for ( const type of apiModel . types ) {
247
+ const name = type . name . name
248
+ if ( name !== 'Request' && name !== 'Response' && name !== 'ResponseBase' ) {
249
+ const namespaces = typeNames . get ( name ) ?? [ ]
250
+ namespaces . push ( type . name . namespace )
251
+ typeNames . set ( name , namespaces )
252
+ }
253
+ }
254
+
255
+ // check for duplicates
256
+ for ( const [ name , namespaces ] of typeNames ) {
257
+ if ( namespaces . length > 1 ) {
258
+ const allowedDuplicates = existingDuplicates [ name ] ?? [ ]
259
+ const hasUnexpectedDuplicate = namespaces . some ( ns => ! allowedDuplicates . includes ( ns ) )
260
+ if ( hasUnexpectedDuplicate ) {
261
+ modelError ( `${ name } is present in multiple namespaces: ${ namespaces . sort ( ) . join ( ' and ' ) } ` )
262
+ }
263
+ }
264
+ }
265
+ }
266
+
207
267
/**
208
268
* Validate an endpoint
209
269
*/
0 commit comments