supabase-typed-query 0.5.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,54 +710,90 @@ 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
- return createGetItemsQuery(client, name, where, is, wherein, order, softDeleteMode);
771
+ return createGetItemsQuery(
772
+ client,
773
+ name,
774
+ where,
775
+ is,
776
+ wherein,
777
+ order,
778
+ softDeleteMode,
779
+ schema
780
+ );
746
781
  };
747
782
  }
748
- function makePartitionedGetItem(client, name, partitionField, softDeleteMode) {
783
+ function makePartitionedGetItem(client, name, partitionField, softDeleteMode, schema) {
749
784
  return function getItem(partitionKey, { id, where, is }) {
750
785
  const whereConditions = buildWhereWithPartitionAndId(partitionField, partitionKey, id, where);
751
- return createGetItemQuery(client, name, whereConditions, is, softDeleteMode);
786
+ return createGetItemQuery(
787
+ client,
788
+ name,
789
+ whereConditions,
790
+ is,
791
+ softDeleteMode,
792
+ schema
793
+ );
752
794
  };
753
795
  }
754
- function makePartitionedGetItems(client, name, partitionField, softDeleteMode) {
796
+ function makePartitionedGetItems(client, name, partitionField, softDeleteMode, schema) {
755
797
  return function getItems(partitionKey, { where, is, wherein, order } = {}) {
756
798
  const whereConditions = buildWhereWithPartition(partitionField, partitionKey, where);
757
799
  return createGetItemsQuery(
@@ -761,94 +803,128 @@ function makePartitionedGetItems(client, name, partitionField, softDeleteMode) {
761
803
  is,
762
804
  wherein,
763
805
  order,
764
- softDeleteMode
806
+ softDeleteMode,
807
+ schema
765
808
  );
766
809
  };
767
810
  }
768
- function makeUpdateItem(client, name) {
811
+ function makeUpdateItem(client, name, schema) {
769
812
  return function updateItem({ where, data, is, wherein }) {
770
- 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
+ );
771
822
  };
772
823
  }
773
- function makePartitionedUpdateItem(client, name, partitionField) {
824
+ function makePartitionedUpdateItem(client, name, partitionField, schema) {
774
825
  return function updateItem(partitionKey, { where, data, is, wherein }) {
775
826
  const whereConditions = buildWhereWithPartition(partitionField, partitionKey, where);
776
- return createUpdateItemMutation(client, name, data, whereConditions, is, wherein);
827
+ return createUpdateItemMutation(
828
+ client,
829
+ name,
830
+ data,
831
+ whereConditions,
832
+ is,
833
+ wherein,
834
+ schema
835
+ );
777
836
  };
778
837
  }
779
- function makeUpdateItems(client, name) {
838
+ function makeUpdateItems(client, name, schema) {
780
839
  return function updateItems({ where, data, is, wherein }) {
781
- 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
+ );
782
849
  };
783
850
  }
784
- function makePartitionedUpdateItems(client, name, partitionField) {
851
+ function makePartitionedUpdateItems(client, name, partitionField, schema) {
785
852
  return function updateItems(partitionKey, { where, data, is, wherein }) {
786
853
  const whereConditions = buildWhereWithPartition(partitionField, partitionKey, where);
787
- return createUpdateItemsMutation(client, name, data, whereConditions, is, wherein);
854
+ return createUpdateItemsMutation(
855
+ client,
856
+ name,
857
+ data,
858
+ whereConditions,
859
+ is,
860
+ wherein,
861
+ schema
862
+ );
788
863
  };
789
864
  }
790
- function makeAddItems(client, name) {
865
+ function makeAddItems(client, name, schema) {
791
866
  return function addItems({ items }) {
792
- return createAddItemsMutation(client, name, items);
867
+ return createAddItemsMutation(client, name, items, schema);
793
868
  };
794
869
  }
795
- function makeUpsertItems(client, name) {
870
+ function makeUpsertItems(client, name, schema) {
796
871
  return function upsertItems({
797
872
  items,
798
873
  identity = "id"
799
874
  }) {
800
- return createUpsertItemsMutation(client, name, items, identity);
875
+ return createUpsertItemsMutation(client, name, items, identity, schema);
801
876
  };
802
877
  }
803
- function makePartitionedUpsertItems(client, name, _partitionField) {
878
+ function makePartitionedUpsertItems(client, name, _partitionField, schema) {
804
879
  return function upsertItems(_partitionKey, { items, identity = "id" }) {
805
- return createUpsertItemsMutation(client, name, items, identity);
880
+ return createUpsertItemsMutation(client, name, items, identity, schema);
806
881
  };
807
882
  }
808
883
  const Entity = (client, name, config) => {
809
884
  const softDeleteMode = getSoftDeleteMode(config.softDelete);
885
+ const { schema } = config;
810
886
  return {
811
887
  /**
812
888
  * Retrieve a single item from the table by ID.
813
889
  * @param params Query parameters including id, where conditions, and is conditions
814
890
  * @returns A chainable query that can be executed with .one(), .many(), or .first()
815
891
  */
816
- getItem: makeGetItem(client, name, softDeleteMode),
892
+ getItem: makeGetItem(client, name, softDeleteMode, schema),
817
893
  /**
818
894
  * Get a list of items from the table filtered by conditions.
819
895
  * @param params Optional query parameters including where, is, wherein, and order
820
896
  * @returns A chainable query that can be executed with .one(), .many(), or .first()
821
897
  */
822
- getItems: makeGetItems(client, name, softDeleteMode),
898
+ getItems: makeGetItems(client, name, softDeleteMode, schema),
823
899
  /**
824
900
  * Adds multiple items to the table.
825
901
  * @param params Parameters including items array
826
902
  * @returns A mutation query with OrThrow methods
827
903
  */
828
- addItems: makeAddItems(client, name),
904
+ addItems: makeAddItems(client, name, schema),
829
905
  /**
830
906
  * Update a single item in the table.
831
907
  * @param params Update parameters including id, item data, and optional filters
832
908
  * @returns A mutation query with OrThrow methods
833
909
  */
834
- updateItem: makeUpdateItem(client, name),
910
+ updateItem: makeUpdateItem(client, name, schema),
835
911
  /**
836
912
  * Update multiple items in the table.
837
913
  * @param params Update parameters including items array, identity, and optional filters
838
914
  * @returns A mutation query with OrThrow methods
839
915
  */
840
- updateItems: makeUpdateItems(client, name),
916
+ updateItems: makeUpdateItems(client, name, schema),
841
917
  /**
842
918
  * Upsert multiple items with different data per row.
843
919
  * @param params Upsert parameters including items array and identity columns
844
920
  * @returns A mutation query with OrThrow methods
845
921
  */
846
- upsertItems: makeUpsertItems(client, name)
922
+ upsertItems: makeUpsertItems(client, name, schema)
847
923
  };
848
924
  };
849
925
  const PartitionedEntity = (client, name, config) => {
850
926
  const softDeleteMode = getSoftDeleteMode(config.softDelete);
851
- const { partitionField } = config;
927
+ const { partitionField, schema } = config;
852
928
  return {
853
929
  /**
854
930
  * Retrieve a single item from the table by ID within a partition.
@@ -856,35 +932,35 @@ const PartitionedEntity = (client, name, config) => {
856
932
  * @param params Query parameters including id, where conditions, and is conditions
857
933
  * @returns A chainable query that can be executed with .one(), .many(), or .first()
858
934
  */
859
- getItem: makePartitionedGetItem(client, name, partitionField, softDeleteMode),
935
+ getItem: makePartitionedGetItem(client, name, partitionField, softDeleteMode, schema),
860
936
  /**
861
937
  * Get a list of items from the table within a partition.
862
938
  * @param partitionKey The partition key value (e.g., tenantId)
863
939
  * @param params Optional query parameters including where, is, wherein, and order
864
940
  * @returns A chainable query that can be executed with .one(), .many(), or .first()
865
941
  */
866
- getItems: makePartitionedGetItems(client, name, partitionField, softDeleteMode),
942
+ getItems: makePartitionedGetItems(client, name, partitionField, softDeleteMode, schema),
867
943
  /**
868
944
  * Adds multiple items to the table.
869
945
  * Note: Items should include the partition key value in their data.
870
946
  * @param params Parameters including items array
871
947
  * @returns A mutation query with OrThrow methods
872
948
  */
873
- addItems: makeAddItems(client, name),
949
+ addItems: makeAddItems(client, name, schema),
874
950
  /**
875
951
  * Update a single item in the table within a partition.
876
952
  * @param partitionKey The partition key value (e.g., tenantId)
877
953
  * @param params Update parameters including id, item data, and optional filters
878
954
  * @returns A mutation query with OrThrow methods
879
955
  */
880
- updateItem: makePartitionedUpdateItem(client, name, partitionField),
956
+ updateItem: makePartitionedUpdateItem(client, name, partitionField, schema),
881
957
  /**
882
958
  * Update multiple items in the table within a partition.
883
959
  * @param partitionKey The partition key value (e.g., tenantId)
884
960
  * @param params Update parameters including items array, identity, and optional filters
885
961
  * @returns A mutation query with OrThrow methods
886
962
  */
887
- updateItems: makePartitionedUpdateItems(client, name, partitionField),
963
+ updateItems: makePartitionedUpdateItems(client, name, partitionField, schema),
888
964
  /**
889
965
  * Upsert multiple items with different data per row within a partition.
890
966
  * Note: Items should include the partition key value in their data.
@@ -892,7 +968,7 @@ const PartitionedEntity = (client, name, config) => {
892
968
  * @param params Upsert parameters including items array and identity columns
893
969
  * @returns A mutation query with OrThrow methods
894
970
  */
895
- upsertItems: makePartitionedUpsertItems(client, name)
971
+ upsertItems: makePartitionedUpsertItems(client, name, partitionField, schema)
896
972
  };
897
973
  };
898
974
  Object.defineProperty(exports, "Err", {