@@ -83,6 +83,7 @@ export default abstract class PostgrestBuilder<
8383 protected signal ?: AbortSignal
8484 protected fetch : Fetch
8585 protected isMaybeSingle : boolean
86+ protected shouldStripNulls : boolean
8687 protected urlLengthLimit : number
8788
8889 // Retry configuration - enabled by default
@@ -123,6 +124,7 @@ export default abstract class PostgrestBuilder<
123124 signal ?: AbortSignal
124125 fetch ?: Fetch
125126 isMaybeSingle ?: boolean
127+ shouldStripNulls ?: boolean
126128 urlLengthLimit ?: number
127129 // Retry option
128130 retry ?: boolean
@@ -135,6 +137,7 @@ export default abstract class PostgrestBuilder<
135137 this . shouldThrowOnError = builder . shouldThrowOnError ?? false
136138 this . signal = builder . signal
137139 this . isMaybeSingle = builder . isMaybeSingle ?? false
140+ this . shouldStripNulls = builder . shouldStripNulls ?? false
138141 this . urlLengthLimit = builder . urlLengthLimit ?? 8000
139142 this . retryEnabled = builder . retry ?? true
140143
@@ -158,6 +161,63 @@ export default abstract class PostgrestBuilder<
158161 return this as this & PostgrestBuilder < ClientOptions , Result , true >
159162 }
160163
164+ /**
165+ * Strip null values from the response data. Properties with `null` values
166+ * will be omitted from the returned JSON objects.
167+ *
168+ * Requires PostgREST 11.2.0+.
169+ *
170+ * {@link https://docs.postgrest.org/en/stable/references/api/resource_representation.html#stripped-nulls}
171+ *
172+ * @category Database
173+ *
174+ * @example With `select()`
175+ * ```ts
176+ * const { data, error } = await supabase
177+ * .from('characters')
178+ * .select()
179+ * .stripNulls()
180+ * ```
181+ *
182+ * @exampleSql With `select()`
183+ * ```sql
184+ * create table
185+ * characters (id int8 primary key, name text, bio text);
186+ *
187+ * insert into
188+ * characters (id, name, bio)
189+ * values
190+ * (1, 'Luke', null),
191+ * (2, 'Leia', 'Princess of Alderaan');
192+ * ```
193+ *
194+ * @exampleResponse With `select()`
195+ * ```json
196+ * {
197+ * "data": [
198+ * {
199+ * "id": 1,
200+ * "name": "Luke"
201+ * },
202+ * {
203+ * "id": 2,
204+ * "name": "Leia",
205+ * "bio": "Princess of Alderaan"
206+ * }
207+ * ],
208+ * "status": 200,
209+ * "statusText": "OK"
210+ * }
211+ * ```
212+ */
213+ stripNulls ( ) : this {
214+ if ( this . headers . get ( 'Accept' ) === 'text/csv' ) {
215+ throw new Error ( 'stripNulls() cannot be used with csv()' )
216+ }
217+ this . shouldStripNulls = true
218+ return this
219+ }
220+
161221 /**
162222 * Set an HTTP header for the request.
163223 *
@@ -222,6 +282,16 @@ export default abstract class PostgrestBuilder<
222282 this . headers . set ( 'Content-Type' , 'application/json' )
223283 }
224284
285+ // https://docs.postgrest.org/en/stable/references/api/resource_representation.html#stripped-nulls
286+ if ( this . shouldStripNulls ) {
287+ const currentAccept = this . headers . get ( 'Accept' )
288+ if ( currentAccept === 'application/vnd.pgrst.object+json' ) {
289+ this . headers . set ( 'Accept' , 'application/vnd.pgrst.object+json;nulls=stripped' )
290+ } else if ( ! currentAccept || currentAccept === 'application/json' ) {
291+ this . headers . set ( 'Accept' , 'application/vnd.pgrst.array+json;nulls=stripped' )
292+ }
293+ }
294+
225295 // NOTE: Invoke w/o `this` to avoid illegal invocation error.
226296 // https://github.com/supabase/postgrest-js/pull/247
227297 const _fetch = this . fetch
0 commit comments