@@ -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
+ let 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