@rebasepro/types 0.7.0 → 0.8.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.
Files changed (37) hide show
  1. package/dist/controllers/client.d.ts +53 -1
  2. package/dist/controllers/data.d.ts +19 -47
  3. package/dist/controllers/registry.d.ts +0 -2
  4. package/dist/index.es.js +157 -10
  5. package/dist/index.es.js.map +1 -1
  6. package/dist/index.umd.js +163 -9
  7. package/dist/index.umd.js.map +1 -1
  8. package/dist/types/auth_adapter.d.ts +5 -5
  9. package/dist/types/backend.d.ts +4 -0
  10. package/dist/types/collections.d.ts +158 -82
  11. package/dist/types/data_source.d.ts +3 -3
  12. package/dist/types/entity_callbacks.d.ts +18 -6
  13. package/dist/types/filter-operators.d.ts +108 -0
  14. package/dist/types/index.d.ts +3 -2
  15. package/dist/types/policy.d.ts +137 -0
  16. package/dist/types/properties.d.ts +115 -37
  17. package/dist/types/property_config.d.ts +1 -1
  18. package/dist/types/storage_source.d.ts +83 -0
  19. package/package.json +1 -1
  20. package/src/controllers/client.ts +61 -1
  21. package/src/controllers/data.ts +20 -59
  22. package/src/controllers/registry.ts +0 -2
  23. package/src/types/auth_adapter.ts +5 -5
  24. package/src/types/backend.ts +5 -0
  25. package/src/types/collections.ts +191 -106
  26. package/src/types/data_source.ts +5 -5
  27. package/src/types/entity_callbacks.ts +18 -7
  28. package/src/types/filter-operators.ts +167 -0
  29. package/src/types/index.ts +3 -2
  30. package/src/types/policy.ts +173 -0
  31. package/src/types/properties.ts +123 -38
  32. package/src/types/property_config.tsx +0 -1
  33. package/src/types/storage_source.ts +90 -0
  34. package/dist/types/backend_hooks.d.ts +0 -109
  35. package/dist/types/entity_overrides.d.ts +0 -10
  36. package/src/types/backend_hooks.ts +0 -114
  37. package/src/types/entity_overrides.tsx +0 -11
@@ -1,16 +1,17 @@
1
1
  import React from "react";
2
2
  import type { Entity, EntityStatus } from "./entities";
3
3
  import type { EntityCallbacks } from "./entity_callbacks";
4
- import type { Properties } from "./properties";
4
+ import type { Properties, PostgresProperties, FirebaseProperties, MongoProperties } from "./properties";
5
5
  import type { ExportConfig } from "./export_import";
6
- import type { EntityOverrides } from "./entity_overrides";
7
6
  import type { User } from "../users";
8
7
  import type { RebaseContext } from "../rebase_context";
9
8
  import type { Relation } from "./relations";
10
9
  import type { EntityCustomView, FormViewConfig } from "./entity_views";
11
10
  import type { EntityAction } from "./entity_actions";
11
+ import type { PolicyExpression } from "./policy";
12
12
  import type { ComponentRef } from "./component_ref";
13
13
  import type { CollectionComponentOverrideMap } from "./component_overrides";
14
+ import type { FilterValues, FilterPreset } from "./filter-operators";
14
15
  /**
15
16
  * Base interface containing all driver-agnostic collection properties.
16
17
  * Use {@link PostgresCollection} or {@link FirebaseCollection} for
@@ -66,17 +67,18 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
66
67
  */
67
68
  dataSource?: string;
68
69
  /**
69
- * The engine backing this collection (`"postgres"`, `"firestore"`,
70
- * `"mongodb"`, or a custom id). Drives editor capabilities (relations vs
71
- * subcollections, RLS, column types).
70
+ * The database engine backing this collection (`"postgres"`, `"firestore"`,
71
+ * `"mongodb"`, or a custom id).
72
72
  *
73
- * @deprecated Prefer {@link dataSource} for routing. `driver` is retained
74
- * as an engine hint and for backward compatibility: when `dataSource` is
75
- * omitted it also acts as the data-source key.
73
+ * On concrete collection types ({@link PostgresCollection},
74
+ * {@link FirebaseCollection}, {@link MongoDBCollection}) this is a literal
75
+ * discriminant. On the base type it is optional and gets stamped
76
+ * automatically during collection normalization from the registered
77
+ * {@link DataSourceDefinition}.
76
78
  *
77
- * If not specified, `"postgres"` is assumed.
79
+ * Prefer setting {@link dataSource} and letting the engine be resolved.
78
80
  */
79
- driver?: string;
81
+ engine?: string;
80
82
  /**
81
83
  * Which database within the engine.
82
84
  * - For Firestore: The Firestore database ID (e.g., for multi-database projects)
@@ -261,8 +263,8 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
261
263
  defaultSize?: CollectionSize;
262
264
  /**
263
265
  * Can the elements in this collection be edited inline in the collection
264
- * view. If this flag is set to false but `permissions.edit` is `true`, entities
265
- * can still be edited in the side panel
266
+ * view. Even when inline editing is disabled, entities can still be
267
+ * edited in the side panel (subject to `securityRules`).
266
268
  */
267
269
  inlineEditing?: boolean;
268
270
  /**
@@ -311,10 +313,6 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
311
313
  * Used by domain apps to store custom per-collection config.
312
314
  */
313
315
  metadata?: Record<string, unknown>;
314
- /**
315
- * Overrides for the entity view, like the data source or the storage source.
316
- */
317
- overrides?: EntityOverrides;
318
316
  /**
319
317
  * Width of the side dialog (in pixels) when opening an entity in this collection.
320
318
  */
@@ -435,12 +433,12 @@ export interface BaseEntityCollection<M extends Record<string, unknown> = Record
435
433
  * @group Models
436
434
  */
437
435
  export interface PostgresCollection<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> extends BaseEntityCollection<M, USER> {
438
- properties: Properties;
436
+ properties: PostgresProperties;
439
437
  /**
440
- * The driver for this collection. For Postgres collections this
438
+ * The database engine for this collection. For Postgres collections this
441
439
  * can be omitted (Postgres is the default) or set to `"postgres"`.
442
440
  */
443
- driver?: "postgres" | undefined;
441
+ engine?: "postgres" | undefined;
444
442
  /**
445
443
  * The PostgreSQL table name for this collection.
446
444
  */
@@ -484,9 +482,31 @@ export interface PostgresCollection<M extends Record<string, unknown> = Record<s
484
482
  */
485
483
  export interface FirebaseCollection<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> extends BaseEntityCollection<M, USER> {
486
484
  /**
487
- * The driver for this collection. Must be set to `"firestore"`.
485
+ * The database engine for this collection. Must be set to `"firestore"`.
486
+ */
487
+ engine: "firestore";
488
+ /**
489
+ * Set of properties that compose an entity.
490
+ * Firestore collections support `reference` properties but not `relation`.
488
491
  */
489
- driver: "firestore";
492
+ properties: FirebaseProperties;
493
+ /**
494
+ * The Firestore collection path to query. Defaults to `slug` if not set.
495
+ * Use this when the Firestore path differs from the slug
496
+ * (e.g., when a PostgreSQL collection already uses the same slug).
497
+ *
498
+ * @example
499
+ * ```typescript
500
+ * const fsCustomer: FirebaseCollection = {
501
+ * slug: "fs_customer", // URL: /c/fs_customer
502
+ * path: "customer", // Firestore path: customer
503
+ * name: "Customers (Firestore)",
504
+ * engine: "firestore",
505
+ * properties: { ... }
506
+ * };
507
+ * ```
508
+ */
509
+ path?: string;
490
510
  /**
491
511
  * You can add subcollections to your entity in the same way you define the root
492
512
  * collections. The collections added here will be displayed when opening
@@ -504,9 +524,31 @@ export interface FirebaseCollection<M extends Record<string, unknown> = Record<s
504
524
  */
505
525
  export interface MongoDBCollection<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> extends BaseEntityCollection<M, USER> {
506
526
  /**
507
- * The driver for this collection. Must be set to `"mongodb"`.
527
+ * The database engine for this collection. Must be set to `"mongodb"`.
528
+ */
529
+ engine: "mongodb";
530
+ /**
531
+ * Set of properties that compose an entity.
532
+ * MongoDB collections support `reference` properties but not `relation`.
533
+ */
534
+ properties: MongoProperties;
535
+ /**
536
+ * The MongoDB collection name to use. Defaults to `slug` if not set.
537
+ * Use this when the MongoDB collection name differs from the slug
538
+ * (e.g., when a PostgreSQL collection already uses the same slug).
539
+ *
540
+ * @example
541
+ * ```typescript
542
+ * const mongoCustomer: MongoDBCollection = {
543
+ * slug: "mongo_customer", // URL: /c/mongo_customer
544
+ * path: "customer", // MongoDB collection: customer
545
+ * name: "Customers (MongoDB)",
546
+ * engine: "mongodb",
547
+ * properties: { ... }
548
+ * };
549
+ * ```
508
550
  */
509
- driver: "mongodb";
551
+ path?: string;
510
552
  }
511
553
  /**
512
554
  * A collection backed by any data source.
@@ -517,22 +559,9 @@ export interface MongoDBCollection<M extends Record<string, unknown> = Record<st
517
559
  * @group Models
518
560
  */
519
561
  export type EntityCollection<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> = PostgresCollection<M, USER> | FirebaseCollection<M, USER> | MongoDBCollection<M, USER>;
520
- /**
521
- * An EntityCollection that supports SQL-style relations (e.g. Postgres).
522
- * @deprecated Use `EntityCollection` directly — `table`, `relations`, and `securityRules` are now on `BaseEntityCollection`.
523
- */
524
- export type CollectionWithRelations<M extends Record<string, unknown> = Record<string, unknown>> = EntityCollection<M> & {
525
- table?: string;
526
- relations?: Relation[];
527
- securityRules?: SecurityRule[];
528
- };
529
- /** An EntityCollection that supports subcollections (e.g. Firestore). */
530
- export type CollectionWithSubcollections<M extends Record<string, unknown> = Record<string, unknown>> = EntityCollection<M> & {
531
- subcollections?: () => EntityCollection<Record<string, unknown>>[];
532
- };
533
562
  /**
534
563
  * Type guard for PostgreSQL collections.
535
- * Returns true if the collection uses the Postgres driver (or the default driver).
564
+ * Returns true if the collection uses the Postgres engine (or the default engine).
536
565
  * @group Models
537
566
  */
538
567
  export declare function isPostgresCollection<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>(collection: EntityCollection<M, USER>): collection is PostgresCollection<M, USER>;
@@ -546,6 +575,23 @@ export declare function isFirebaseCollection<M extends Record<string, unknown> =
546
575
  * @group Models
547
576
  */
548
577
  export declare function isMongoDBCollection<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>(collection: EntityCollection<M, USER>): collection is MongoDBCollection<M, USER>;
578
+ /**
579
+ * Returns the data path for a collection.
580
+ * For Firestore or MongoDB collections with a `path`, returns that value;
581
+ * otherwise falls back to `slug`.
582
+ */
583
+ export declare function getCollectionDataPath<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>(collection: EntityCollection<M, USER>): string;
584
+ /**
585
+ * Reads a collection's driver-declared subcollections thunk (the `subcollections`
586
+ * field) independent of engine identity, so engine-agnostic code doesn't have to
587
+ * type-guard against a specific driver. Returns `undefined` when the collection
588
+ * declares none.
589
+ *
590
+ * Pair with `getDataSourceCapabilities(engine).supportsSubcollections` to decide
591
+ * whether the engine honours subcollections at all before reading them.
592
+ * @group Models
593
+ */
594
+ export declare function getDeclaredSubcollections<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User>(collection: EntityCollection<M, USER>): (() => EntityCollection<Record<string, unknown>>[]) | undefined;
549
595
  /**
550
596
  * Configuration for Kanban board view mode.
551
597
  * @group Collections
@@ -641,42 +687,7 @@ export interface SelectionController<M extends Record<string, unknown> = Record<
641
687
  isEntitySelected(entity: Entity<M>): boolean;
642
688
  toggleEntitySelection(entity: Entity<M>, newSelectedState?: boolean): void;
643
689
  }
644
- /**
645
- * Filter conditions in a `Query.where()` clause are specified using the
646
- * strings `<`, `<=`, `==`, `>=`, `>`, `array-contains`, `in`, and `array-contains-any`.
647
- * @group Models
648
- */
649
- export type WhereFilterOp = "<" | "<=" | "==" | "!=" | ">=" | ">" | "array-contains" | "in" | "not-in" | "array-contains-any";
650
- /**
651
- * Used to define filters applied in collections
652
- *
653
- * e.g. `{ age: [">=", 18] }`
654
- *
655
- * @group Models
656
- */
657
- export type FilterValues<Key extends string> = Partial<Record<Key, [WhereFilterOp, unknown] | [WhereFilterOp, unknown][]>>;
658
- /**
659
- * A pre-defined filter preset for quick access in the collection toolbar.
660
- * Users can select a preset to instantly apply a set of filters and
661
- * optionally a sort order.
662
- *
663
- * @group Models
664
- */
665
- export interface FilterPreset<Key extends string = string> {
666
- /**
667
- * Display label shown in the preset menu.
668
- * If omitted, a summary is auto-generated from the filter keys.
669
- */
670
- label?: string;
671
- /**
672
- * The filter values to apply when this preset is selected.
673
- */
674
- filterValues: FilterValues<Key>;
675
- /**
676
- * Optional sort override to apply alongside the filter values.
677
- */
678
- sort?: [Key, "asc" | "desc"];
679
- }
690
+ export type { WhereFilterOp, FilterValues, WireFilterValues, FilterPreset } from "./filter-operators";
680
691
  /**
681
692
  * Used to indicate valid filter combinations (e.g. created in Firestore)
682
693
  * If the user selects a specific filter/sort combination, the CMS checks if it's
@@ -814,13 +825,21 @@ export type SecurityOperation = "select" | "insert" | "update" | "delete" | "all
814
825
  * operation. Permissive rules are OR'd together (any one passing is enough).
815
826
  * Restrictive rules are AND'd (all must pass). This mirrors Supabase behavior.
816
827
  *
817
- * **Mutual exclusivity:** `ownerField`, `access`, and raw SQL (`using`/`withCheck`)
818
- * cannot be combined. The type system enforces this — attempting to set
819
- * conflicting fields will produce a compile-time error.
828
+ * **Mutual exclusivity:** `ownerField`, `access`, structured `condition`, and
829
+ * raw SQL (`using`/`withCheck`) cannot be combined. The type system enforces
830
+ * this — attempting to set conflicting fields will produce a compile-time
831
+ * error.
832
+ *
833
+ * **Which form to reach for:** prefer the structured {@link StructuredSecurityRule}
834
+ * (`condition`/`check`) or the shortcuts (`ownerField`, `access`, `roles`). These
835
+ * are engine-agnostic and evaluated identically by the database and the admin UI,
836
+ * so the UI never shows an action the database will reject. Raw SQL
837
+ * ({@link RawSQLSecurityRule}) keeps full PostgreSQL power but is Postgres-only
838
+ * and server-authoritative (the UI cannot evaluate arbitrary SQL locally).
820
839
  *
821
840
  * @group Models
822
841
  */
823
- export type SecurityRule = OwnerSecurityRule | PublicSecurityRule | RawSQLSecurityRule | RolesOnlySecurityRule;
842
+ export type SecurityRule = OwnerSecurityRule | PublicSecurityRule | StructuredSecurityRule | RawSQLSecurityRule | RolesOnlySecurityRule;
824
843
  /**
825
844
  * Shared fields for all SecurityRule variants.
826
845
  * @group Models
@@ -885,11 +904,16 @@ export interface SecurityRuleBase {
885
904
  * application roles managed by Rebase, stored in the `rebase.user_roles`
886
905
  * table, and injected into each transaction via `auth.roles()`.
887
906
  *
888
- * Generates a condition like:
889
- * `auth.roles() ~ '<role1>|<role2>'`
907
+ * Generates a safe array-overlap condition — the user passes if they hold
908
+ * *any* of the listed roles:
909
+ * `string_to_array(auth.roles(), ',') && ARRAY['<role1>', '<role2>']`
890
910
  *
891
- * Can be combined with `ownerField`, `access`, or raw `using`/`withCheck`.
892
- * When combined, the role check is AND'd with the other condition.
911
+ * (Note: this is a true set intersection, NOT a regex/substring match, so
912
+ * a role named `admin` never matches `nonadmin` or `superadmin`.)
913
+ *
914
+ * Can be combined with `ownerField`, `access`, `condition`, or raw
915
+ * `using`/`withCheck`. When combined, the role check is AND'd with the
916
+ * other condition.
893
917
  *
894
918
  * @example
895
919
  * // Only admins can delete
@@ -940,6 +964,8 @@ export interface OwnerSecurityRule extends SecurityRuleBase {
940
964
  access?: never;
941
965
  using?: never;
942
966
  withCheck?: never;
967
+ condition?: never;
968
+ check?: never;
943
969
  }
944
970
  /**
945
971
  * Security rule that grants unrestricted row access (no row filtering).
@@ -963,11 +989,57 @@ export interface PublicSecurityRule extends SecurityRuleBase {
963
989
  ownerField?: never;
964
990
  using?: never;
965
991
  withCheck?: never;
992
+ condition?: never;
993
+ check?: never;
994
+ }
995
+ /**
996
+ * Security rule expressed as a structured, engine-agnostic
997
+ * {@link PolicyExpression}. This is the **recommended** way to write a
998
+ * non-trivial condition: it compiles to PostgreSQL `USING`/`WITH CHECK` SQL
999
+ * *and* is evaluated identically by the admin UI, so the UI can never show an
1000
+ * action the database will reject.
1001
+ *
1002
+ * Cannot be combined with `ownerField`, `access`, or raw `using`/`withCheck`.
1003
+ *
1004
+ * @example
1005
+ * // Owner, or any user holding the `moderator` role
1006
+ * {
1007
+ * operation: "update",
1008
+ * condition: policy.or(
1009
+ * policy.compare(policy.field("user_id"), "eq", policy.authUid()),
1010
+ * policy.rolesOverlap(["moderator"])
1011
+ * )
1012
+ * }
1013
+ *
1014
+ * @group Models
1015
+ */
1016
+ export interface StructuredSecurityRule extends SecurityRuleBase {
1017
+ /**
1018
+ * Structured condition for the `USING` clause — which *existing* rows are
1019
+ * visible / can be modified / deleted (SELECT, UPDATE, DELETE).
1020
+ */
1021
+ condition: PolicyExpression;
1022
+ /**
1023
+ * Structured condition for the `WITH CHECK` clause — which *new/updated*
1024
+ * row values are allowed (INSERT, UPDATE). Defaults to `condition` when
1025
+ * omitted, mirroring PostgreSQL's own behavior.
1026
+ */
1027
+ check?: PolicyExpression;
1028
+ ownerField?: never;
1029
+ access?: never;
1030
+ using?: never;
1031
+ withCheck?: never;
966
1032
  }
967
1033
  /**
968
1034
  * Security rule using raw SQL expressions for full PostgreSQL RLS power.
969
1035
  *
970
- * Cannot be combined with `ownerField` or `access`.
1036
+ * **Postgres-only and server-authoritative.** Arbitrary SQL cannot be
1037
+ * evaluated by the admin UI, so a rule using this form is treated as *unknown*
1038
+ * client-side (never silently allowed) and its effect on visible actions is
1039
+ * reflected from the server. For conditions that should also drive the UI
1040
+ * precisely, prefer the structured {@link StructuredSecurityRule}.
1041
+ *
1042
+ * Cannot be combined with `ownerField`, `access`, or structured `condition`.
971
1043
  *
972
1044
  * You can reference columns via `{column_name}` which will be resolved to
973
1045
  * `table.column_name` in the generated Drizzle code.
@@ -1003,6 +1075,8 @@ export interface RawSQLSecurityRule extends SecurityRuleBase {
1003
1075
  withCheck?: string;
1004
1076
  ownerField?: never;
1005
1077
  access?: never;
1078
+ condition?: never;
1079
+ check?: never;
1006
1080
  }
1007
1081
  /**
1008
1082
  * Security rule that only filters by application roles, without any
@@ -1022,6 +1096,8 @@ export interface RolesOnlySecurityRule extends SecurityRuleBase {
1022
1096
  access?: never;
1023
1097
  using?: never;
1024
1098
  withCheck?: never;
1099
+ condition?: never;
1100
+ check?: never;
1025
1101
  }
1026
1102
  /**
1027
1103
  * Configuration for authentication collections.
@@ -128,11 +128,11 @@ export declare const MONGODB_CAPABILITIES: DataSourceCapabilities;
128
128
  */
129
129
  export declare const DEFAULT_CAPABILITIES: DataSourceCapabilities;
130
130
  /**
131
- * Look up capabilities for a given driver key.
132
- * If `driver` is undefined or not found, returns `DEFAULT_CAPABILITIES`.
131
+ * Look up capabilities for a given engine key.
132
+ * If `engine` is undefined or not found, returns `DEFAULT_CAPABILITIES`.
133
133
  * @group Models
134
134
  */
135
- export declare function getDataSourceCapabilities(driver?: string): DataSourceCapabilities;
135
+ export declare function getDataSourceCapabilities(engine?: string): DataSourceCapabilities;
136
136
  /**
137
137
  * Register custom capabilities for a third-party driver.
138
138
  * @group Models
@@ -3,14 +3,24 @@ import type { Entity, EntityStatus, EntityValues } from "./entities";
3
3
  import type { User } from "../users";
4
4
  import type { RebaseCallContext } from "../rebase_context";
5
5
  /**
6
- * This interface defines all the callbacks that can be used when an entity
7
- * is being created, updated or deleted.
8
- * Useful for adding your own logic or blocking the execution of the operation.
6
+ * Lifecycle callbacks for entity CRUD operations.
7
+ *
8
+ * Register per-collection on the collection's `callbacks` field, or globally
9
+ * via `initBackend({ callbacks })`. Fires on **every** data path — REST API,
10
+ * WebSocket / realtime subscriptions, and server-side `rebase.data`.
11
+ *
12
+ * When both global and per-collection callbacks are registered, execution
13
+ * order is: **global → collection → property callbacks**.
14
+ *
9
15
  * @group Models
10
16
  */
11
17
  export type EntityCallbacks<M extends Record<string, unknown> = Record<string, unknown>, USER extends User = User> = {
12
18
  /**
13
- * Callback used after fetching data
19
+ * Callback used after fetching data.
20
+ *
21
+ * Fires on every read path. Use this for security-critical redaction
22
+ * (PII masking, row filtering) — no read path bypasses it.
23
+ *
14
24
  * @param props
15
25
  */
16
26
  afterRead?(props: EntityAfterReadProps<M, USER>): Promise<Entity<M>> | Entity<M>;
@@ -19,11 +29,13 @@ export type EntityCallbacks<M extends Record<string, unknown> = Record<string, u
19
29
  * saved. If you throw an error in this method the process stops, and an
20
30
  * error snackbar gets displayed.
21
31
  * This runs after schema validation.
32
+ *
22
33
  * @param props
23
34
  */
24
35
  beforeSave?(props: EntityBeforeSaveProps<M, USER>): Promise<Partial<EntityValues<M>>> | Partial<EntityValues<M>>;
25
36
  /**
26
- * Callback used when save is successful
37
+ * Callback used when save is successful.
38
+ *
27
39
  * @param props
28
40
  */
29
41
  afterSave?(props: EntityAfterSaveProps<M, USER>): Promise<void> | void;
@@ -45,7 +57,7 @@ export type EntityCallbacks<M extends Record<string, unknown> = Record<string, u
45
57
  *
46
58
  * @param props
47
59
  */
48
- afterDelete?(props: EntityAfterDeleteProps<M, USER>): void;
60
+ afterDelete?(props: EntityAfterDeleteProps<M, USER>): Promise<void> | void;
49
61
  };
50
62
  /**
51
63
  * Parameters passed to hooks when an entity is fetched
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Canonical filter operators and REST wire-format mappings.
3
+ *
4
+ * `WhereFilterOp` is THE operator type used at every layer — from React
5
+ * components through the SDK, server, and down to the database driver.
6
+ *
7
+ * PostgREST short-codes (`eq`, `gt`, `cs`, …) exist **only** at the
8
+ * HTTP wire boundary, handled by `serializeFilter` / `deserializeFilter`
9
+ * in `@rebasepro/common`.
10
+ *
11
+ * ┌──────────────────┬───────────────┬──────────────────────────┐
12
+ * │ Canonical │ REST short │ Meaning │
13
+ * ├──────────────────┼───────────────┼──────────────────────────┤
14
+ * │ "==" │ "eq" │ Equal │
15
+ * │ "!=" │ "neq" │ Not equal │
16
+ * │ ">" │ "gt" │ Greater than │
17
+ * │ ">=" │ "gte" │ Greater than or equal │
18
+ * │ "<" │ "lt" │ Less than │
19
+ * │ "<=" │ "lte" │ Less than or equal │
20
+ * │ "in" │ "in" │ Value in list │
21
+ * │ "not-in" │ "nin" │ Value not in list │
22
+ * │ "array-contains" │ "cs" │ Array contains element │
23
+ * │ "array-contains-any" │ "csa" │ Array contains any of │
24
+ * └──────────────────┴───────────────┴──────────────────────────┘
25
+ *
26
+ * @module
27
+ */
28
+ /**
29
+ * Canonical filter operators supported across all database backends.
30
+ * Each DB driver translates these to its native query format.
31
+ *
32
+ * @group Models
33
+ */
34
+ export type WhereFilterOp = "<" | "<=" | "==" | "!=" | ">=" | ">" | "array-contains" | "in" | "not-in" | "array-contains-any";
35
+ /**
36
+ * Used to define filters applied in collections.
37
+ *
38
+ * A single condition is a tuple `[operator, value]`.
39
+ * Multiple conditions on the same field use an array of tuples.
40
+ *
41
+ * @example
42
+ * // Single condition per field
43
+ * { status: ["==", "active"], price: [">=", 9.99] }
44
+ *
45
+ * // Multiple conditions on one field
46
+ * { age: [[">=", 18], ["<", 65]] }
47
+ *
48
+ * // Array operators
49
+ * { role: ["in", ["admin", "editor"]] }
50
+ * { tags: ["array-contains", "featured"] }
51
+ *
52
+ * @group Models
53
+ */
54
+ export type FilterValues<Key extends string> = Partial<Record<Key, [WhereFilterOp, unknown] | [WhereFilterOp, unknown][]>>;
55
+ /**
56
+ * Relaxed filter type that also accepts pre-serialized PostgREST strings.
57
+ * **Internal only** — used at the wire-format boundary
58
+ * (`serializeFilter` / `deserializeFilter` in `@rebasepro/common`).
59
+ *
60
+ * Application code, UI components, and SDK consumers should use
61
+ * {@link FilterValues} instead.
62
+ *
63
+ * @internal
64
+ */
65
+ export type WireFilterValues<Key extends string> = Partial<Record<Key, [WhereFilterOp, unknown] | [WhereFilterOp, unknown][] | string>>;
66
+ /**
67
+ * A pre-defined filter preset for quick access in the collection toolbar.
68
+ * Users can select a preset to instantly apply a set of filters and
69
+ * optionally a sort order.
70
+ *
71
+ * @group Models
72
+ */
73
+ export interface FilterPreset<Key extends string = string> {
74
+ /**
75
+ * Display label shown in the preset menu.
76
+ * If omitted, a summary is auto-generated from the filter keys.
77
+ */
78
+ label?: string;
79
+ /**
80
+ * The filter values to apply when this preset is selected.
81
+ */
82
+ filterValues: FilterValues<Key>;
83
+ /**
84
+ * Optional sort override to apply alongside the filter values.
85
+ */
86
+ sort?: [Key, "asc" | "desc"];
87
+ }
88
+ /**
89
+ * PostgREST short-code operators. Wire format only — these never appear
90
+ * in application code. Used by `serializeFilter`/`deserializeFilter`
91
+ * in `@rebasepro/common`.
92
+ */
93
+ export type RestFilterOp = "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" | "nin" | "cs" | "csa";
94
+ /** Maps canonical operators to their REST short-code equivalents. */
95
+ export declare const CANONICAL_TO_REST: Readonly<Record<WhereFilterOp, RestFilterOp>>;
96
+ /** Maps REST short-code operators to their canonical equivalents. */
97
+ export declare const REST_TO_CANONICAL: Readonly<Record<RestFilterOp, WhereFilterOp>>;
98
+ /**
99
+ * Resolve any operator string (canonical or REST short-code) to its
100
+ * canonical `WhereFilterOp` form. Returns `undefined` for unknown operators.
101
+ *
102
+ * @example
103
+ * toCanonicalOp("==") // "=="
104
+ * toCanonicalOp("eq") // "=="
105
+ * toCanonicalOp("cs") // "array-contains"
106
+ * toCanonicalOp("xyz") // undefined
107
+ */
108
+ export declare function toCanonicalOp(op: string): WhereFilterOp | undefined;
@@ -1,13 +1,14 @@
1
1
  export * from "./entities";
2
+ export * from "./filter-operators";
2
3
  export * from "./chips";
3
4
  export * from "./properties";
4
5
  export * from "./collections";
5
6
  export * from "./relations";
7
+ export * from "./policy";
6
8
  export * from "./locales";
7
9
  export * from "./entity_link_builder";
8
10
  export * from "./user_management_delegate";
9
11
  export * from "./entity_callbacks";
10
- export * from "./entity_overrides";
11
12
  export * from "./export_import";
12
13
  export * from "./modify_collections";
13
14
  export * from "./formex";
@@ -21,8 +22,8 @@ export * from "./entity_actions";
21
22
  export * from "./property_config";
22
23
  export * from "./entity_views";
23
24
  export * from "./data_source";
25
+ export * from "./storage_source";
24
26
  export * from "./cron";
25
- export * from "./backend_hooks";
26
27
  export * from "./component_ref";
27
28
  export * from "./auth_adapter";
28
29
  export * from "./database_adapter";