@@ -51,6 +51,8 @@ import {
5151 AutofixRunStateSchema ,
5252 ClientKeyListSchema ,
5353 ClientKeySchema ,
54+ CustomInboundFilterListSchema ,
55+ CustomInboundFilterSchema ,
5456 CommitListSchema ,
5557 CommittersResponseSchema ,
5658 DashboardListSchema ,
@@ -130,6 +132,8 @@ import type {
130132 SearchAgentState ,
131133 ClientKey ,
132134 ClientKeyList ,
135+ CustomInboundFilter ,
136+ CustomInboundFilterList ,
133137 CommitList ,
134138 CommitterList ,
135139 Dashboard ,
@@ -346,6 +350,13 @@ type UpdateProjectRequest = {
346350 platform ?: string ;
347351} ;
348352
353+ type CustomInboundFilterWriteRequest = {
354+ name ?: string | null ;
355+ active ?: boolean ;
356+ dataType : string ;
357+ conditions : Array < { type : string ; value : string [ ] } > ;
358+ } ;
359+
349360type UpdateClientKeyRequest = {
350361 name ?: string ;
351362 isActive ?: boolean ;
@@ -2856,6 +2867,147 @@ export class SentryApiService {
28562867 return ClientKeyListSchema . parse ( body ) ;
28572868 }
28582869
2870+ /**
2871+ * Lists the custom inbound filters of a project.
2872+ *
2873+ * Source: src/sentry/api/endpoints/project_custom_inbound_filters.py
2874+ *
2875+ * @param params Query parameters
2876+ * @param params.organizationSlug Organization identifier
2877+ * @param params.projectSlug Project identifier
2878+ * @param params.limit Maximum number of filters per page
2879+ * @param params.cursor Pagination cursor from a previous call's nextCursor
2880+ * @param opts Request options
2881+ * @returns A page of custom inbound filters, plus a cursor for the next page (null once exhausted)
2882+ */
2883+ async listCustomInboundFilters (
2884+ {
2885+ organizationSlug,
2886+ projectSlug,
2887+ limit,
2888+ cursor,
2889+ } : {
2890+ organizationSlug : string ;
2891+ projectSlug : string ;
2892+ limit ?: number ;
2893+ cursor ?: string | null ;
2894+ } ,
2895+ opts ?: RequestOptions ,
2896+ ) : Promise < { filters : CustomInboundFilterList ; nextCursor : string | null } > {
2897+ const queryParams = new URLSearchParams ( ) ;
2898+ queryParams . set ( "per_page" , String ( limit ?? 25 ) ) ;
2899+ if ( cursor ) {
2900+ queryParams . set ( "cursor" , cursor ) ;
2901+ }
2902+ const basePath = apiPath `/projects/${ organizationSlug } /${ projectSlug } /custom-inbound-filters/` ;
2903+ const response = await this . request (
2904+ `${ basePath } ?${ queryParams . toString ( ) } ` ,
2905+ undefined ,
2906+ opts ,
2907+ ) ;
2908+ const body = await this . parseJsonResponse ( response ) ;
2909+ return {
2910+ filters : CustomInboundFilterListSchema . parse ( body ) ,
2911+ nextCursor : getNextCursor ( response . headers . get ( "link" ) ) ,
2912+ } ;
2913+ }
2914+
2915+ /**
2916+ * Creates a custom inbound filter in a project.
2917+ *
2918+ * Source: src/sentry/api/endpoints/project_custom_inbound_filters.py
2919+ */
2920+ async createCustomInboundFilter (
2921+ {
2922+ organizationSlug,
2923+ projectSlug,
2924+ ...filter
2925+ } : {
2926+ organizationSlug : string ;
2927+ projectSlug : string ;
2928+ } & CustomInboundFilterWriteRequest ,
2929+ opts ?: RequestOptions ,
2930+ ) : Promise < CustomInboundFilter > {
2931+ const body = await this . requestJSON (
2932+ apiPath `/projects/${ organizationSlug } /${ projectSlug } /custom-inbound-filters/` ,
2933+ {
2934+ method : "POST" ,
2935+ body : JSON . stringify ( filter ) ,
2936+ } ,
2937+ opts ,
2938+ ) ;
2939+ return CustomInboundFilterSchema . parse ( body ) ;
2940+ }
2941+
2942+ /**
2943+ * Updates a custom inbound filter. Only the provided fields change.
2944+ *
2945+ * Source: src/sentry/api/endpoints/project_custom_inbound_filters.py
2946+ */
2947+ async updateCustomInboundFilter (
2948+ {
2949+ organizationSlug,
2950+ projectSlug,
2951+ filterId,
2952+ ...filter
2953+ } : {
2954+ organizationSlug : string ;
2955+ projectSlug : string ;
2956+ filterId : string ;
2957+ } & Partial < CustomInboundFilterWriteRequest > ,
2958+ opts ?: RequestOptions ,
2959+ ) : Promise < CustomInboundFilter > {
2960+ const updateData : Partial < CustomInboundFilterWriteRequest > = { } ;
2961+ if ( filter . name !== undefined ) {
2962+ updateData . name = filter . name ;
2963+ }
2964+ if ( filter . active !== undefined ) {
2965+ updateData . active = filter . active ;
2966+ }
2967+ if ( filter . dataType !== undefined ) {
2968+ updateData . dataType = filter . dataType ;
2969+ }
2970+ if ( filter . conditions !== undefined ) {
2971+ updateData . conditions = filter . conditions ;
2972+ }
2973+ const body = await this . requestJSON (
2974+ apiPath `/projects/${ organizationSlug } /${ projectSlug } /custom-inbound-filters/${ filterId } /` ,
2975+ {
2976+ method : "PUT" ,
2977+ body : JSON . stringify ( updateData ) ,
2978+ } ,
2979+ opts ,
2980+ ) ;
2981+ return CustomInboundFilterSchema . parse ( body ) ;
2982+ }
2983+
2984+ /**
2985+ * Deletes a custom inbound filter.
2986+ *
2987+ * Source: src/sentry/api/endpoints/project_custom_inbound_filters.py
2988+ */
2989+ async deleteCustomInboundFilter (
2990+ {
2991+ organizationSlug,
2992+ projectSlug,
2993+ filterId,
2994+ } : {
2995+ organizationSlug : string ;
2996+ projectSlug : string ;
2997+ filterId : string ;
2998+ } ,
2999+ opts ?: RequestOptions ,
3000+ ) : Promise < void > {
3001+ // Treat 404 as success so repeated deletes are idempotent.
3002+ await this . request (
3003+ apiPath `/projects/${ organizationSlug } /${ projectSlug } /custom-inbound-filters/${ filterId } /` ,
3004+ {
3005+ method : "DELETE" ,
3006+ } ,
3007+ { ...opts , allowStatuses : [ 404 ] } ,
3008+ ) ;
3009+ }
3010+
28593011 /**
28603012 * Lists releases for an organization or specific project.
28613013 *
0 commit comments