supabase-typed-query 0.12.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -128,8 +128,47 @@ const selectedPosts = await query(supabase, "posts", {
128
128
  const drafts = await query(supabase, "posts", {
129
129
  published_at: { is: null },
130
130
  }).many()
131
+
132
+ // IS NOT NULL checks (using NOT operator)
133
+ const publishedPosts = await query(supabase, "posts", {
134
+ not: { is: { published_at: null } },
135
+ }).many()
136
+
137
+ // NOT IN queries
138
+ const activePosts = await query(supabase, "posts", {
139
+ not: { in: { status: ["draft", "archived"] } },
140
+ }).many()
141
+ ```
142
+
143
+ ### NOT Operator
144
+
145
+ The `not` operator follows Supabase conventions for negating conditions:
146
+
147
+ ```typescript
148
+ // IS NOT NULL - find posts with external_id set
149
+ const linkedPosts = await PostEntity.getItems({
150
+ not: { is: { external_id: null } },
151
+ }).many()
152
+
153
+ // IS NOT TRUE / IS NOT FALSE
154
+ const nonFeatured = await PostEntity.getItems({
155
+ not: { is: { featured: true } },
156
+ }).many()
157
+
158
+ // NOT IN - exclude specific statuses
159
+ const visiblePosts = await PostEntity.getItems({
160
+ not: { in: { status: ["spam", "trash", "deleted"] } },
161
+ }).many()
162
+
163
+ // Combine NOT with other conditions
164
+ const activeLinkedPosts = await PostEntity.getItems({
165
+ where: { status: "published" },
166
+ not: { is: { external_id: null } },
167
+ }).many()
131
168
  ```
132
169
 
170
+ > **Note**: `neq: null` is deprecated. Use `not: { is: { field: null } }` instead for IS NOT NULL checks.
171
+
133
172
  ### Chaining OR Conditions
134
173
 
135
174
  ```typescript
package/dist/index.js CHANGED
@@ -69,7 +69,7 @@ const QueryBuilder = (client, config) => {
69
69
  return finalQuery;
70
70
  };
71
71
  const applyCondition = (query2, condition) => {
72
- const { where, is, wherein, gt, gte, lt, lte, neq, like, ilike } = condition;
72
+ const { where, is, wherein, gt, gte, lt, lte, neq, like, ilike, not } = condition;
73
73
  const processedWhere = {};
74
74
  const extractedOperators = {};
75
75
  if (where) {
@@ -183,10 +183,18 @@ const QueryBuilder = (client, config) => {
183
183
  const queryWithGte = Object.keys(mergedGte).length > 0 ? Object.entries(mergedGte).reduce((q, [key, value]) => q.gte(key, value), queryWithGt) : queryWithGt;
184
184
  const queryWithLt = Object.keys(mergedLt).length > 0 ? Object.entries(mergedLt).reduce((q, [key, value]) => q.lt(key, value), queryWithGte) : queryWithGte;
185
185
  const queryWithLte = Object.keys(mergedLte).length > 0 ? Object.entries(mergedLte).reduce((q, [key, value]) => q.lte(key, value), queryWithLt) : queryWithLt;
186
- const queryWithNeq = Object.keys(mergedNeq).length > 0 ? Object.entries(mergedNeq).reduce((q, [key, value]) => q.neq(key, value), queryWithLte) : queryWithLte;
186
+ const queryWithNeq = Object.keys(mergedNeq).length > 0 ? Object.entries(mergedNeq).reduce((q, [key, value]) => {
187
+ if (value === null) {
188
+ log.warn(`neq: null is deprecated. Use not: { is: { ${key}: null } } for IS NOT NULL`);
189
+ return q.not(key, "is", null);
190
+ }
191
+ return q.neq(key, value);
192
+ }, queryWithLte) : queryWithLte;
187
193
  const queryWithLike = Object.keys(mergedLike).length > 0 ? Object.entries(mergedLike).reduce((q, [key, pattern]) => q.like(key, pattern), queryWithNeq) : queryWithNeq;
188
194
  const queryWithIlike = Object.keys(mergedIlike).length > 0 ? Object.entries(mergedIlike).reduce((q, [key, pattern]) => q.ilike(key, pattern), queryWithLike) : queryWithLike;
189
- return queryWithIlike;
195
+ const queryWithNotIs = not?.is ? Object.entries(not.is).reduce((q, [key, value]) => q.not(key, "is", value), queryWithIlike) : queryWithIlike;
196
+ const queryWithNot = not?.in ? Object.entries(not.in).reduce((q, [key, values]) => q.not(key, "in", values), queryWithNotIs) : queryWithNotIs;
197
+ return queryWithNot;
190
198
  };
191
199
  const applyOrConditions = (query2, conditions) => {
192
200
  const selectQuery = query2.select("*");
@@ -223,7 +231,8 @@ const QueryBuilder = (client, config) => {
223
231
  return {
224
232
  where: newWhere,
225
233
  is: condition.is,
226
- wherein: condition.wherein
234
+ wherein: condition.wherein,
235
+ not: condition.not
227
236
  };
228
237
  })
229
238
  );
@@ -287,6 +296,7 @@ const QueryBuilder = (client, config) => {
287
296
  if (condition.neq) {
288
297
  Object.entries(condition.neq).forEach(([key, value]) => {
289
298
  if (value === null) {
299
+ log.warn(`neq: null is deprecated. Use not: { is: { ${key}: null } } for IS NOT NULL`);
290
300
  parts.push(`${key}.not.is.null`);
291
301
  } else {
292
302
  parts.push(`${key}.neq."${value}"`);
@@ -303,6 +313,25 @@ const QueryBuilder = (client, config) => {
303
313
  parts.push(`${key}.ilike."${pattern}"`);
304
314
  });
305
315
  }
316
+ if (condition.not) {
317
+ if (condition.not.is) {
318
+ Object.entries(condition.not.is).forEach(([key, value]) => {
319
+ if (value === null) {
320
+ parts.push(`${key}.not.is.null`);
321
+ } else {
322
+ parts.push(`${key}.not.is.${value}`);
323
+ }
324
+ });
325
+ }
326
+ if (condition.not.in) {
327
+ Object.entries(condition.not.in).forEach(([key, values]) => {
328
+ if (values && Array.isArray(values) && values.length > 0) {
329
+ const valueList = values.map((v) => `"${v}"`).join(",");
330
+ parts.push(`${key}.not.in.(${valueList})`);
331
+ }
332
+ });
333
+ }
334
+ }
306
335
  return parts.join(",");
307
336
  }).filter((condition) => condition.length > 0);
308
337
  const finalQuery = orConditions.length > 0 ? queryWithCommon.or(orConditions.join(",")) : queryWithCommon;
@@ -555,10 +584,10 @@ const createMappedQuery = (sourceQuery, mapFn) => {
555
584
  }
556
585
  };
557
586
  };
558
- const createQuery = (client, table, where = {}, is, wherein, order, softDeleteConfig, schema, comparison) => {
587
+ const createQuery = (client, table, where = {}, is, wherein, order, softDeleteConfig, schema, comparison, not) => {
559
588
  const config = {
560
589
  table,
561
- conditions: [{ where, is, wherein, ...comparison }],
590
+ conditions: [{ where, is, wherein, ...comparison, not }],
562
591
  order,
563
592
  softDeleteMode: softDeleteConfig?.mode,
564
593
  softDeleteAppliedByDefault: softDeleteConfig?.appliedByDefault,
@@ -868,7 +897,7 @@ function createGetItemQuery(client, name, whereConditions, is, softDeleteMode, s
868
897
  schema
869
898
  );
870
899
  }
871
- function createGetItemsQuery(client, name, whereConditions, is, wherein, order, softDeleteMode, schema, comparison) {
900
+ function createGetItemsQuery(client, name, whereConditions, is, wherein, order, softDeleteMode, schema, comparison, not) {
872
901
  return createQuery(
873
902
  client,
874
903
  name,
@@ -881,7 +910,8 @@ function createGetItemsQuery(client, name, whereConditions, is, wherein, order,
881
910
  appliedByDefault: true
882
911
  },
883
912
  schema,
884
- comparison
913
+ comparison,
914
+ not
885
915
  );
886
916
  }
887
917
  function createAddItemsMutation(client, name, items, schema) {
@@ -948,7 +978,8 @@ function makeGetItems(client, name, softDeleteMode, schema) {
948
978
  lt,
949
979
  neq,
950
980
  like,
951
- ilike
981
+ ilike,
982
+ not
952
983
  } = {}) {
953
984
  return createGetItemsQuery(
954
985
  client,
@@ -959,7 +990,8 @@ function makeGetItems(client, name, softDeleteMode, schema) {
959
990
  order,
960
991
  softDeleteMode,
961
992
  schema,
962
- { gte, gt, lte, lt, neq, like, ilike }
993
+ { gte, gt, lte, lt, neq, like, ilike },
994
+ not
963
995
  );
964
996
  };
965
997
  }
@@ -977,7 +1009,7 @@ function makePartitionedGetItem(client, name, partitionField, softDeleteMode, sc
977
1009
  };
978
1010
  }
979
1011
  function makePartitionedGetItems(client, name, partitionField, softDeleteMode, schema) {
980
- return function getItems(partitionKey, { where, is, wherein, order, gte, gt, lte, lt, neq, like, ilike } = {}) {
1012
+ return function getItems(partitionKey, { where, is, wherein, order, gte, gt, lte, lt, neq, like, ilike, not } = {}) {
981
1013
  const whereConditions = buildWhereWithPartition(partitionField, partitionKey, where);
982
1014
  return createGetItemsQuery(
983
1015
  client,
@@ -988,7 +1020,8 @@ function makePartitionedGetItems(client, name, partitionField, softDeleteMode, s
988
1020
  order,
989
1021
  softDeleteMode,
990
1022
  schema,
991
- { gte, gt, lte, lt, neq, like, ilike }
1023
+ { gte, gt, lte, lt, neq, like, ilike },
1024
+ not
992
1025
  );
993
1026
  };
994
1027
  }