supabase-typed-query 0.6.0 → 0.7.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
@@ -12,6 +12,7 @@ Type-safe query builder and entity pattern for Supabase with TypeScript.
12
12
  - 🔄 **Composable queries** - Mix and match conditions, filters, and transformations
13
13
  - 🗑️ **Soft delete support** - Built-in soft delete filtering with per-query overrides
14
14
  - 🏢 **Multi-tenancy ready** - Automatic partition key filtering for tenant isolation
15
+ - 🗄️ **Custom schema support** - Query tables in any PostgreSQL schema, not just public
15
16
 
16
17
  ## Installation
17
18
 
@@ -150,6 +151,42 @@ const AdminEntity = Entity(supabase, "users", {
150
151
  })
151
152
  ```
152
153
 
154
+ ### Custom Schema Support
155
+
156
+ Query tables in any PostgreSQL schema (not just the default `public` schema):
157
+
158
+ ```typescript
159
+ import { Entity, PartitionedEntity, query } from "supabase-typed-query"
160
+
161
+ // Entity with custom schema
162
+ const InventoryEntity = Entity(supabase, "items", {
163
+ softDelete: false,
164
+ schema: "inventory", // Uses client.schema("inventory").from("items")
165
+ })
166
+
167
+ const items = await InventoryEntity.getItems({ where: { active: true } }).many()
168
+
169
+ // PartitionedEntity with custom schema
170
+ const TenantItemsEntity = PartitionedEntity(supabase, "items", {
171
+ partitionField: "tenant_id",
172
+ softDelete: true,
173
+ schema: "tenant_data",
174
+ })
175
+
176
+ // Query API with custom schema (7th parameter)
177
+ const results = await query(
178
+ supabase,
179
+ "items",
180
+ { active: true },
181
+ undefined, // is conditions
182
+ undefined, // wherein conditions
183
+ undefined, // order
184
+ "inventory", // schema
185
+ ).many()
186
+ ```
187
+
188
+ When no schema is specified, queries use the default `public` schema via `client.from()`. When a schema is specified, queries use `client.schema(name).from(table)`.
189
+
153
190
  ### Multi-Tenancy with Partition Keys
154
191
 
155
192
  Use partition keys to automatically scope queries to a tenant or partition:
@@ -253,7 +290,13 @@ const posts = await query(supabase, "posts", {
253
290
  ### Entity Configuration
254
291
 
255
292
  - `softDelete: boolean` - (Required) When `true`, automatically excludes soft-deleted items; when `false`, includes them
256
- - `partitionKey?: Record<string, unknown>` - (Optional) Automatically applies partition filtering (e.g., `{ tenant_id: "123" }` for multi-tenancy)
293
+ - `schema?: string` - (Optional) PostgreSQL schema to query from (defaults to `"public"`)
294
+
295
+ ### PartitionedEntity Configuration
296
+
297
+ - `partitionField: string` - (Required) Column name used for partition filtering (e.g., `"tenant_id"`)
298
+ - `softDelete: boolean` - (Required) When `true`, automatically excludes soft-deleted items
299
+ - `schema?: string` - (Optional) PostgreSQL schema to query from (defaults to `"public"`)
257
300
 
258
301
  ## Requirements
259
302
 
package/dist/index.js CHANGED
@@ -52,8 +52,8 @@ const wrapAsync$1 = (fn) => {
52
52
  };
53
53
  const QueryBuilder = (client, config) => {
54
54
  const buildSupabaseQuery = () => {
55
- const { table, conditions, order, limit, offset } = config;
56
- const baseQuery = client.from(table);
55
+ const { table, conditions, order, limit, offset, schema } = config;
56
+ const baseQuery = schema ? client.schema(schema).from(table) : client.from(table);
57
57
  const queryWithConditions = conditions.length === 1 ? applyCondition(baseQuery, conditions[0]) : applyOrConditions(baseQuery, conditions);
58
58
  const queryWithOrder = order ? queryWithConditions.order(order[0], order[1]) : queryWithConditions;
59
59
  const finalQuery = (() => {
@@ -555,13 +555,14 @@ const createMappedQuery = (sourceQuery, mapFn) => {
555
555
  }
556
556
  };
557
557
  };
558
- const createQuery = (client, table, where = {}, is, wherein, order, softDeleteConfig) => {
558
+ const createQuery = (client, table, where = {}, is, wherein, order, softDeleteConfig, schema) => {
559
559
  const config = {
560
560
  table,
561
561
  conditions: [{ where, is, wherein }],
562
562
  order,
563
563
  softDeleteMode: softDeleteConfig?.mode,
564
- softDeleteAppliedByDefault: softDeleteConfig?.appliedByDefault
564
+ softDeleteAppliedByDefault: softDeleteConfig?.appliedByDefault,
565
+ schema
565
566
  };
566
567
  return QueryBuilder(client, config);
567
568
  };
@@ -574,9 +575,10 @@ const isMappedQuery = (obj) => {
574
575
  const wrapAsync = (fn) => {
575
576
  return fn();
576
577
  };
577
- const getEntity = (client, table, where, is) => wrapAsync(async () => {
578
+ const getEntity = (client, table, where, is, schema) => wrapAsync(async () => {
578
579
  try {
579
- const baseQuery = client.from(table).select("*").match(where);
580
+ const tableQuery = schema ? client.schema(schema).from(table) : client.from(table);
581
+ const baseQuery = tableQuery.select("*").match(where);
580
582
  const queryWithIs = is ? functype.List(Object.entries(is)).foldLeft(baseQuery)(
581
583
  (query2, [column, value]) => query2.is(column, value)
582
584
  ) : baseQuery;
@@ -592,9 +594,10 @@ const getEntity = (client, table, where, is) => wrapAsync(async () => {
592
594
  const getEntities = (client, table, where = {}, is, wherein, order = [
593
595
  "id",
594
596
  { ascending: true }
595
- ]) => wrapAsync(async () => {
597
+ ], schema) => wrapAsync(async () => {
596
598
  try {
597
- const baseQuery = client.from(table).select("*").match(where);
599
+ const tableQuery = schema ? client.schema(schema).from(table) : client.from(table);
600
+ const baseQuery = tableQuery.select("*").match(where);
598
601
  const queryWithIn = wherein ? functype.List(Object.entries(wherein)).foldLeft(baseQuery)(
599
602
  (query2, [column, values]) => query2.in(column, values)
600
603
  ) : baseQuery;
@@ -611,9 +614,10 @@ const getEntities = (client, table, where = {}, is, wherein, order = [
611
614
  return functype.Err(toError(error));
612
615
  }
613
616
  });
614
- const addEntities = (client, table, entities) => wrapAsync(async () => {
617
+ const addEntities = (client, table, entities, schema) => wrapAsync(async () => {
615
618
  try {
616
- const { data, error } = await client.from(table).insert(entities).select();
619
+ const tableQuery = schema ? client.schema(schema).from(table) : client.from(table);
620
+ const { data, error } = await tableQuery.insert(entities).select();
617
621
  if (error) {
618
622
  return functype.Err(toError(error));
619
623
  }
@@ -622,9 +626,10 @@ const addEntities = (client, table, entities) => wrapAsync(async () => {
622
626
  return functype.Err(toError(error));
623
627
  }
624
628
  });
625
- const updateEntity = (client, table, entities, where, is, wherein) => wrapAsync(async () => {
629
+ const updateEntity = (client, table, entities, where, is, wherein, schema) => wrapAsync(async () => {
626
630
  try {
627
- const baseQuery = client.from(table).update(entities).match(where);
631
+ const tableQuery = schema ? client.schema(schema).from(table) : client.from(table);
632
+ const baseQuery = tableQuery.update(entities).match(where);
628
633
  const queryWithIn = wherein ? functype.List(Object.entries(wherein)).foldLeft(baseQuery)(
629
634
  (query2, [column, values]) => query2.in(column, values)
630
635
  ) : baseQuery;
@@ -640,10 +645,11 @@ const updateEntity = (client, table, entities, where, is, wherein) => wrapAsync(
640
645
  return functype.Err(toError(error));
641
646
  }
642
647
  });
643
- const upsertEntities = (client, table, entities, identity = "id", where, is, wherein) => wrapAsync(async () => {
648
+ const upsertEntities = (client, table, entities, identity = "id", where, is, wherein, schema) => wrapAsync(async () => {
644
649
  try {
645
650
  const onConflict = Array.isArray(identity) ? identity.join(",") : identity;
646
- const baseQuery = client.from(table).upsert(entities, { onConflict }).match(where ?? {});
651
+ const tableQuery = schema ? client.schema(schema).from(table) : client.from(table);
652
+ const baseQuery = tableQuery.upsert(entities, { onConflict }).match(where ?? {});
647
653
  const queryWithIn = wherein ? functype.List(Object.entries(wherein)).foldLeft(baseQuery)(
648
654
  (query2, [column, values]) => query2.in(column, values)
649
655
  ) : baseQuery;
@@ -659,8 +665,8 @@ const upsertEntities = (client, table, entities, identity = "id", where, is, whe
659
665
  return functype.Err(toError(error));
660
666
  }
661
667
  });
662
- const query = (client, table, where = {}, is, wherein, order) => {
663
- return createQuery(client, table, where, is, wherein, order);
668
+ const query = (client, table, where = {}, is, wherein, order, schema) => {
669
+ return createQuery(client, table, where, is, wherein, order, void 0, schema);
664
670
  };
665
671
  function MultiMutationQuery(promise) {
666
672
  const result = Object.assign(promise, {
@@ -704,43 +710,63 @@ function buildWhereWithPartitionAndId(partitionField, partitionKey, id, where) {
704
710
  const partitionCondition = { [partitionField]: partitionKey };
705
711
  return { ...partitionCondition, ...where, id };
706
712
  }
707
- function createGetItemQuery(client, name, whereConditions, is, softDeleteMode) {
708
- return createQuery(client, name, whereConditions, is, void 0, void 0, {
709
- mode: softDeleteMode,
710
- appliedByDefault: true
711
- });
713
+ function createGetItemQuery(client, name, whereConditions, is, softDeleteMode, schema) {
714
+ return createQuery(
715
+ client,
716
+ name,
717
+ whereConditions,
718
+ is,
719
+ void 0,
720
+ void 0,
721
+ {
722
+ mode: softDeleteMode,
723
+ appliedByDefault: true
724
+ },
725
+ schema
726
+ );
712
727
  }
713
- function createGetItemsQuery(client, name, whereConditions, is, wherein, order, softDeleteMode) {
714
- return createQuery(client, name, whereConditions, is, wherein, order, {
715
- mode: softDeleteMode,
716
- appliedByDefault: true
717
- });
728
+ function createGetItemsQuery(client, name, whereConditions, is, wherein, order, softDeleteMode, schema) {
729
+ return createQuery(
730
+ client,
731
+ name,
732
+ whereConditions,
733
+ is,
734
+ wherein,
735
+ order,
736
+ {
737
+ mode: softDeleteMode,
738
+ appliedByDefault: true
739
+ },
740
+ schema
741
+ );
718
742
  }
719
- function createAddItemsMutation(client, name, items) {
720
- return MultiMutationQuery(addEntities(client, name, items));
743
+ function createAddItemsMutation(client, name, items, schema) {
744
+ return MultiMutationQuery(
745
+ addEntities(client, name, items, schema)
746
+ );
721
747
  }
722
- function createUpdateItemMutation(client, name, item, whereConditions, is, wherein) {
748
+ function createUpdateItemMutation(client, name, item, whereConditions, is, wherein, schema) {
723
749
  return SingleMutationQuery(
724
- updateEntity(client, name, item, whereConditions, is, wherein)
750
+ updateEntity(client, name, item, whereConditions, is, wherein, schema)
725
751
  );
726
752
  }
727
- function createUpdateItemsMutation(client, name, data, where, is, wherein) {
753
+ function createUpdateItemsMutation(client, name, data, where, is, wherein, schema) {
728
754
  return MultiMutationQuery(
729
- upsertEntities(client, name, [data], void 0, where, is, wherein)
755
+ upsertEntities(client, name, [data], void 0, where, is, wherein, schema)
730
756
  );
731
757
  }
732
- function createUpsertItemsMutation(client, name, items, identity) {
758
+ function createUpsertItemsMutation(client, name, items, identity, schema) {
733
759
  return MultiMutationQuery(
734
- upsertEntities(client, name, items, identity, void 0, void 0, void 0)
760
+ upsertEntities(client, name, items, identity, void 0, void 0, void 0, schema)
735
761
  );
736
762
  }
737
- function makeGetItem(client, name, softDeleteMode) {
763
+ function makeGetItem(client, name, softDeleteMode, schema) {
738
764
  return function getItem({ id, where, is }) {
739
765
  const whereConditions = { ...where, id };
740
- return createGetItemQuery(client, name, whereConditions, is, softDeleteMode);
766
+ return createGetItemQuery(client, name, whereConditions, is, softDeleteMode, schema);
741
767
  };
742
768
  }
743
- function makeGetItems(client, name, softDeleteMode) {
769
+ function makeGetItems(client, name, softDeleteMode, schema) {
744
770
  return function getItems({ where, is, wherein, order } = {}) {
745
771
  return createGetItemsQuery(
746
772
  client,
@@ -749,11 +775,12 @@ function makeGetItems(client, name, softDeleteMode) {
749
775
  is,
750
776
  wherein,
751
777
  order,
752
- softDeleteMode
778
+ softDeleteMode,
779
+ schema
753
780
  );
754
781
  };
755
782
  }
756
- function makePartitionedGetItem(client, name, partitionField, softDeleteMode) {
783
+ function makePartitionedGetItem(client, name, partitionField, softDeleteMode, schema) {
757
784
  return function getItem(partitionKey, { id, where, is }) {
758
785
  const whereConditions = buildWhereWithPartitionAndId(partitionField, partitionKey, id, where);
759
786
  return createGetItemQuery(
@@ -761,11 +788,12 @@ function makePartitionedGetItem(client, name, partitionField, softDeleteMode) {
761
788
  name,
762
789
  whereConditions,
763
790
  is,
764
- softDeleteMode
791
+ softDeleteMode,
792
+ schema
765
793
  );
766
794
  };
767
795
  }
768
- function makePartitionedGetItems(client, name, partitionField, softDeleteMode) {
796
+ function makePartitionedGetItems(client, name, partitionField, softDeleteMode, schema) {
769
797
  return function getItems(partitionKey, { where, is, wherein, order } = {}) {
770
798
  const whereConditions = buildWhereWithPartition(partitionField, partitionKey, where);
771
799
  return createGetItemsQuery(
@@ -775,16 +803,25 @@ function makePartitionedGetItems(client, name, partitionField, softDeleteMode) {
775
803
  is,
776
804
  wherein,
777
805
  order,
778
- softDeleteMode
806
+ softDeleteMode,
807
+ schema
779
808
  );
780
809
  };
781
810
  }
782
- function makeUpdateItem(client, name) {
811
+ function makeUpdateItem(client, name, schema) {
783
812
  return function updateItem({ where, data, is, wherein }) {
784
- return createUpdateItemMutation(client, name, data, where, is, wherein);
813
+ return createUpdateItemMutation(
814
+ client,
815
+ name,
816
+ data,
817
+ where,
818
+ is,
819
+ wherein,
820
+ schema
821
+ );
785
822
  };
786
823
  }
787
- function makePartitionedUpdateItem(client, name, partitionField) {
824
+ function makePartitionedUpdateItem(client, name, partitionField, schema) {
788
825
  return function updateItem(partitionKey, { where, data, is, wherein }) {
789
826
  const whereConditions = buildWhereWithPartition(partitionField, partitionKey, where);
790
827
  return createUpdateItemMutation(
@@ -793,16 +830,25 @@ function makePartitionedUpdateItem(client, name, partitionField) {
793
830
  data,
794
831
  whereConditions,
795
832
  is,
796
- wherein
833
+ wherein,
834
+ schema
797
835
  );
798
836
  };
799
837
  }
800
- function makeUpdateItems(client, name) {
838
+ function makeUpdateItems(client, name, schema) {
801
839
  return function updateItems({ where, data, is, wherein }) {
802
- return createUpdateItemsMutation(client, name, data, where, is, wherein);
840
+ return createUpdateItemsMutation(
841
+ client,
842
+ name,
843
+ data,
844
+ where,
845
+ is,
846
+ wherein,
847
+ schema
848
+ );
803
849
  };
804
850
  }
805
- function makePartitionedUpdateItems(client, name, partitionField) {
851
+ function makePartitionedUpdateItems(client, name, partitionField, schema) {
806
852
  return function updateItems(partitionKey, { where, data, is, wherein }) {
807
853
  const whereConditions = buildWhereWithPartition(partitionField, partitionKey, where);
808
854
  return createUpdateItemsMutation(
@@ -811,72 +857,74 @@ function makePartitionedUpdateItems(client, name, partitionField) {
811
857
  data,
812
858
  whereConditions,
813
859
  is,
814
- wherein
860
+ wherein,
861
+ schema
815
862
  );
816
863
  };
817
864
  }
818
- function makeAddItems(client, name) {
865
+ function makeAddItems(client, name, schema) {
819
866
  return function addItems({ items }) {
820
- return createAddItemsMutation(client, name, items);
867
+ return createAddItemsMutation(client, name, items, schema);
821
868
  };
822
869
  }
823
- function makeUpsertItems(client, name) {
870
+ function makeUpsertItems(client, name, schema) {
824
871
  return function upsertItems({
825
872
  items,
826
873
  identity = "id"
827
874
  }) {
828
- return createUpsertItemsMutation(client, name, items, identity);
875
+ return createUpsertItemsMutation(client, name, items, identity, schema);
829
876
  };
830
877
  }
831
- function makePartitionedUpsertItems(client, name, _partitionField) {
878
+ function makePartitionedUpsertItems(client, name, _partitionField, schema) {
832
879
  return function upsertItems(_partitionKey, { items, identity = "id" }) {
833
- return createUpsertItemsMutation(client, name, items, identity);
880
+ return createUpsertItemsMutation(client, name, items, identity, schema);
834
881
  };
835
882
  }
836
883
  const Entity = (client, name, config) => {
837
884
  const softDeleteMode = getSoftDeleteMode(config.softDelete);
885
+ const { schema } = config;
838
886
  return {
839
887
  /**
840
888
  * Retrieve a single item from the table by ID.
841
889
  * @param params Query parameters including id, where conditions, and is conditions
842
890
  * @returns A chainable query that can be executed with .one(), .many(), or .first()
843
891
  */
844
- getItem: makeGetItem(client, name, softDeleteMode),
892
+ getItem: makeGetItem(client, name, softDeleteMode, schema),
845
893
  /**
846
894
  * Get a list of items from the table filtered by conditions.
847
895
  * @param params Optional query parameters including where, is, wherein, and order
848
896
  * @returns A chainable query that can be executed with .one(), .many(), or .first()
849
897
  */
850
- getItems: makeGetItems(client, name, softDeleteMode),
898
+ getItems: makeGetItems(client, name, softDeleteMode, schema),
851
899
  /**
852
900
  * Adds multiple items to the table.
853
901
  * @param params Parameters including items array
854
902
  * @returns A mutation query with OrThrow methods
855
903
  */
856
- addItems: makeAddItems(client, name),
904
+ addItems: makeAddItems(client, name, schema),
857
905
  /**
858
906
  * Update a single item in the table.
859
907
  * @param params Update parameters including id, item data, and optional filters
860
908
  * @returns A mutation query with OrThrow methods
861
909
  */
862
- updateItem: makeUpdateItem(client, name),
910
+ updateItem: makeUpdateItem(client, name, schema),
863
911
  /**
864
912
  * Update multiple items in the table.
865
913
  * @param params Update parameters including items array, identity, and optional filters
866
914
  * @returns A mutation query with OrThrow methods
867
915
  */
868
- updateItems: makeUpdateItems(client, name),
916
+ updateItems: makeUpdateItems(client, name, schema),
869
917
  /**
870
918
  * Upsert multiple items with different data per row.
871
919
  * @param params Upsert parameters including items array and identity columns
872
920
  * @returns A mutation query with OrThrow methods
873
921
  */
874
- upsertItems: makeUpsertItems(client, name)
922
+ upsertItems: makeUpsertItems(client, name, schema)
875
923
  };
876
924
  };
877
925
  const PartitionedEntity = (client, name, config) => {
878
926
  const softDeleteMode = getSoftDeleteMode(config.softDelete);
879
- const { partitionField } = config;
927
+ const { partitionField, schema } = config;
880
928
  return {
881
929
  /**
882
930
  * Retrieve a single item from the table by ID within a partition.
@@ -884,35 +932,35 @@ const PartitionedEntity = (client, name, config) => {
884
932
  * @param params Query parameters including id, where conditions, and is conditions
885
933
  * @returns A chainable query that can be executed with .one(), .many(), or .first()
886
934
  */
887
- getItem: makePartitionedGetItem(client, name, partitionField, softDeleteMode),
935
+ getItem: makePartitionedGetItem(client, name, partitionField, softDeleteMode, schema),
888
936
  /**
889
937
  * Get a list of items from the table within a partition.
890
938
  * @param partitionKey The partition key value (e.g., tenantId)
891
939
  * @param params Optional query parameters including where, is, wherein, and order
892
940
  * @returns A chainable query that can be executed with .one(), .many(), or .first()
893
941
  */
894
- getItems: makePartitionedGetItems(client, name, partitionField, softDeleteMode),
942
+ getItems: makePartitionedGetItems(client, name, partitionField, softDeleteMode, schema),
895
943
  /**
896
944
  * Adds multiple items to the table.
897
945
  * Note: Items should include the partition key value in their data.
898
946
  * @param params Parameters including items array
899
947
  * @returns A mutation query with OrThrow methods
900
948
  */
901
- addItems: makeAddItems(client, name),
949
+ addItems: makeAddItems(client, name, schema),
902
950
  /**
903
951
  * Update a single item in the table within a partition.
904
952
  * @param partitionKey The partition key value (e.g., tenantId)
905
953
  * @param params Update parameters including id, item data, and optional filters
906
954
  * @returns A mutation query with OrThrow methods
907
955
  */
908
- updateItem: makePartitionedUpdateItem(client, name, partitionField),
956
+ updateItem: makePartitionedUpdateItem(client, name, partitionField, schema),
909
957
  /**
910
958
  * Update multiple items in the table within a partition.
911
959
  * @param partitionKey The partition key value (e.g., tenantId)
912
960
  * @param params Update parameters including items array, identity, and optional filters
913
961
  * @returns A mutation query with OrThrow methods
914
962
  */
915
- updateItems: makePartitionedUpdateItems(client, name, partitionField),
963
+ updateItems: makePartitionedUpdateItems(client, name, partitionField, schema),
916
964
  /**
917
965
  * Upsert multiple items with different data per row within a partition.
918
966
  * Note: Items should include the partition key value in their data.
@@ -920,7 +968,7 @@ const PartitionedEntity = (client, name, config) => {
920
968
  * @param params Upsert parameters including items array and identity columns
921
969
  * @returns A mutation query with OrThrow methods
922
970
  */
923
- upsertItems: makePartitionedUpsertItems(client, name)
971
+ upsertItems: makePartitionedUpsertItems(client, name, partitionField, schema)
924
972
  };
925
973
  };
926
974
  Object.defineProperty(exports, "Err", {