@izumisy-tailor/tailor-data-viewer 0.2.14 → 0.2.16

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.
@@ -1,6 +1,7 @@
1
1
  import type { ReactNode } from "react";
2
2
  import type {
3
3
  FieldType,
4
+ TableMetadata,
4
5
  TableMetadataMap,
5
6
  } from "../generator/metadata-generator";
6
7
 
@@ -144,24 +145,40 @@ export interface Filter<TFieldName extends string = string> {
144
145
  * // | { field: "status"; operator: "eq" | "ne" | "in" | "notIn"; value: unknown }
145
146
  * ```
146
147
  */
148
+ /**
149
+ * Metadata-aware filter type from a single table metadata object.
150
+ *
151
+ * Given table metadata, produces a discriminated union over each field
152
+ * where the `operator` is narrowed to only those valid for that field's type.
153
+ *
154
+ * @typeParam TTable - A single table metadata object (as const).
155
+ */
156
+ export type TableMetadataFilter<TTable extends TableMetadata> =
157
+ TTable["fields"][number] extends infer F
158
+ ? F extends { readonly name: infer N; readonly type: infer T }
159
+ ? N extends string
160
+ ? T extends keyof FieldTypeToFilterConfigType
161
+ ? FieldTypeToFilterConfigType[T] extends never
162
+ ? never
163
+ : {
164
+ field: N;
165
+ operator: OperatorForFilterType[FieldTypeToFilterConfigType[T]];
166
+ value: unknown;
167
+ }
168
+ : never
169
+ : never
170
+ : never
171
+ : never;
172
+
173
+ /**
174
+ * Metadata-aware filter type.
175
+ *
176
+ * @deprecated Use `TableMetadataFilter<TMetadata[TTableName]>` instead.
177
+ */
147
178
  export type MetadataFilter<
148
179
  TMetadata extends TableMetadataMap,
149
180
  TTableName extends string & keyof TMetadata,
150
- > = TMetadata[TTableName]["fields"][number] extends infer F
151
- ? F extends { readonly name: infer N; readonly type: infer T }
152
- ? N extends string
153
- ? T extends keyof FieldTypeToFilterConfigType
154
- ? FieldTypeToFilterConfigType[T] extends never
155
- ? never
156
- : {
157
- field: N;
158
- operator: OperatorForFilterType[FieldTypeToFilterConfigType[T]];
159
- value: unknown;
160
- }
161
- : never
162
- : never
163
- : never
164
- : never;
181
+ > = TableMetadataFilter<TMetadata[TTableName]>;
165
182
 
166
183
  /**
167
184
  * Active sort state for a single field.
@@ -177,6 +194,8 @@ export interface SortState {
177
194
  export interface PageInfo {
178
195
  hasNextPage: boolean;
179
196
  endCursor: string | null;
197
+ hasPreviousPage: boolean;
198
+ startCursor: string | null;
180
199
  }
181
200
 
182
201
  // =============================================================================
@@ -211,8 +230,14 @@ export interface QueryVariables {
211
230
  * performed by `ValidateCollectionQuery` (specifically `CheckOrderField`).
212
231
  */
213
232
  order?: { field: string; direction: "Asc" | "Desc" }[];
214
- first: number;
233
+ /** Forward pagination: number of items to fetch */
234
+ first?: number | null;
235
+ /** Forward pagination: cursor to start after */
215
236
  after?: string | null;
237
+ /** Backward pagination: number of items to fetch from the end */
238
+ last?: number | null;
239
+ /** Backward pagination: cursor to fetch before */
240
+ before?: string | null;
216
241
  }
217
242
 
218
243
  // =============================================================================
@@ -438,14 +463,20 @@ export interface UseCollectionReturn<
438
463
  pageSize: number;
439
464
  /** Current cursor position */
440
465
  cursor: string | null;
441
- /** Navigate to next page */
466
+ /** Current pagination direction */
467
+ paginationDirection: "forward" | "backward";
468
+ /** Navigate to next page using endCursor from pageInfo */
442
469
  nextPage(endCursor: string): void;
443
- /** Navigate to previous page */
444
- prevPage(): void;
470
+ /** Navigate to previous page using startCursor from pageInfo */
471
+ prevPage(startCursor: string): void;
445
472
  /** Reset to first page */
446
473
  resetPage(): void;
447
- /** Whether there is a previous page */
474
+ /** Whether there is a previous page (from GraphQL pageInfo) */
448
475
  hasPrevPage: boolean;
476
+ /** Whether there is a next page (from GraphQL pageInfo) */
477
+ hasNextPage: boolean;
478
+ /** Set pageInfo from graphql result to track hasPrevPage/hasNextPage */
479
+ setPageInfo(pageInfo: PageInfo): void;
449
480
  }
450
481
 
451
482
  // =============================================================================
@@ -551,9 +582,11 @@ export interface UseDataTableReturn<TRow extends Record<string, unknown>> {
551
582
  /** Navigate to next page */
552
583
  nextPage: (endCursor: string) => void;
553
584
  /** Navigate to previous page */
554
- prevPage: () => void;
585
+ prevPage: (startCursor: string) => void;
555
586
  /** Whether a previous page exists */
556
587
  hasPrevPage: boolean;
588
+ /** Whether a next page exists */
589
+ hasNextPage: boolean;
557
590
 
558
591
  // Column management
559
592
  /** All column definitions */
@@ -583,16 +616,30 @@ export interface UseDataTableReturn<TRow extends Record<string, unknown>> {
583
616
  // =============================================================================
584
617
 
585
618
  /**
586
- * Extract field names from table metadata.
619
+ * Extract field names from a single table metadata object.
620
+ *
621
+ * @example
622
+ * ```ts
623
+ * type Names = TableFieldName<typeof tableMetadata.task>;
624
+ * // → "id" | "title" | "status" | "dueDate" | ...
625
+ * ```
626
+ */
627
+ export type TableFieldName<TTable extends TableMetadata> =
628
+ TTable["fields"][number] extends { readonly name: infer N }
629
+ ? N extends string
630
+ ? N
631
+ : never
632
+ : never;
633
+
634
+ /**
635
+ * Extract field names from table metadata map + table name.
636
+ *
637
+ * @deprecated Use `TableFieldName<TMetadata[TTableName]>` instead.
587
638
  */
588
639
  export type FieldName<
589
640
  TMetadata extends TableMetadataMap,
590
641
  TTableName extends keyof TMetadata,
591
- > = TMetadata[TTableName]["fields"][number] extends { readonly name: infer N }
592
- ? N extends string
593
- ? N
594
- : never
595
- : never;
642
+ > = TableFieldName<TMetadata[TTableName]>;
596
643
 
597
644
  /**
598
645
  * Field types that support ordering.
@@ -609,19 +656,16 @@ type OrderableFieldType =
609
656
  | "enum";
610
657
 
611
658
  /**
612
- * Extract only orderable field names from table metadata.
659
+ * Extract only orderable field names from a single table metadata object.
613
660
  *
614
661
  * Fields whose `type` is not in `OrderableFieldType` (e.g. `uuid`, `array`,
615
662
  * `nested`, `file`) are excluded. This allows `CheckOrderField` to compare
616
663
  * only the fields that Tailor Platform actually exposes in the
617
664
  * `OrderFieldEnum`, avoiding false positives for fields like `id`.
618
665
  */
619
- export type OrderableFieldName<
620
- TMetadata extends TableMetadataMap,
621
- TTableName extends keyof TMetadata,
622
- > =
666
+ export type TableOrderableFieldName<TTable extends TableMetadata> =
623
667
  Extract<
624
- TMetadata[TTableName]["fields"][number],
668
+ TTable["fields"][number],
625
669
  { readonly type: OrderableFieldType }
626
670
  > extends { readonly name: infer N }
627
671
  ? N extends string
@@ -629,6 +673,16 @@ export type OrderableFieldName<
629
673
  : never
630
674
  : never;
631
675
 
676
+ /**
677
+ * Extract only orderable field names from table metadata map + table name.
678
+ *
679
+ * @deprecated Use `TableOrderableFieldName<TMetadata[TTableName]>` instead.
680
+ */
681
+ export type OrderableFieldName<
682
+ TMetadata extends TableMetadataMap,
683
+ TTableName extends keyof TMetadata,
684
+ > = TableOrderableFieldName<TMetadata[TTableName]>;
685
+
632
686
  /**
633
687
  * Extract the `order[].field` union type from a GraphQL variables type.
634
688
  *
@@ -718,9 +772,58 @@ type CheckFirstVariable<TQuery> =
718
772
  };
719
773
 
720
774
  /**
721
- * Rule 2 — When both metadata and `$order` variable exist, metadata field
722
- * names must be assignable to the `field` enum inside the `OrderInput` type.
723
- * Skipped when `TFieldName` is the generic `string` (no metadata).
775
+ * Rule 2 — The query must declare `$after` as a variable.
776
+ */
777
+ type CheckAfterVariable<TQuery> =
778
+ "after" extends keyof ExtractQueryVariables<TQuery>
779
+ ? Pass
780
+ : {
781
+ __afterVariableError: `Query must declare an $after variable (e.g. $after: String).`;
782
+ };
783
+
784
+ /**
785
+ * Rule 3 — The query must declare `$last` as a variable.
786
+ */
787
+ type CheckLastVariable<TQuery> =
788
+ "last" extends keyof ExtractQueryVariables<TQuery>
789
+ ? Pass
790
+ : {
791
+ __lastVariableError: `Query must declare a $last variable (e.g. $last: Int).`;
792
+ };
793
+
794
+ /**
795
+ * Rule 4 — The query must declare `$before` as a variable.
796
+ */
797
+ type CheckBeforeVariable<TQuery> =
798
+ "before" extends keyof ExtractQueryVariables<TQuery>
799
+ ? Pass
800
+ : {
801
+ __beforeVariableError: `Query must declare a $before variable (e.g. $before: String).`;
802
+ };
803
+
804
+ /**
805
+ * Rule 5 — The query must declare `$query` as a variable.
806
+ */
807
+ type CheckQueryVariable<TQuery> =
808
+ "query" extends keyof ExtractQueryVariables<TQuery>
809
+ ? Pass
810
+ : {
811
+ __queryVariableError: `Query must declare a $query variable (e.g. $query: XxxQueryInput!).`;
812
+ };
813
+
814
+ /**
815
+ * Rule 6 — The query must declare `$order` as a variable.
816
+ */
817
+ type CheckOrderVariable<TQuery> =
818
+ "order" extends keyof ExtractQueryVariables<TQuery>
819
+ ? Pass
820
+ : {
821
+ __orderVariableError: `Query must declare an $order variable (e.g. $order: [XxxOrderInput]).`;
822
+ };
823
+
824
+ /**
825
+ * Rule 7 — When metadata is provided, metadata field names must be
826
+ * assignable to the `field` enum inside the `OrderInput` type.
724
827
  */
725
828
  type CheckOrderField<
726
829
  TQuery,
@@ -734,9 +837,8 @@ type CheckOrderField<
734
837
  : Pass;
735
838
 
736
839
  /**
737
- * Rule 3 — When both metadata and `$query` variable exist, metadata field
738
- * names must be a subset of the `QueryInput` type's keys.
739
- * Skipped when `TFieldName` is the generic `string` (no metadata).
840
+ * Rule 8 — When metadata is provided, metadata field names must be a
841
+ * subset of the `QueryInput` type's keys.
740
842
  */
741
843
  type CheckQueryInput<
742
844
  TQuery,
@@ -757,8 +859,13 @@ type CheckQueryInput<
757
859
  * intersecting independent rule types:
758
860
  *
759
861
  * 1. **`CheckFirstVariable`** — `$first` must exist.
760
- * 2. **`CheckOrderField`** — OrderInput field compatibility (metadata-aware).
761
- * 3. **`CheckQueryInput`** — QueryInput key compatibility (metadata-aware).
862
+ * 2. **`CheckAfterVariable`** — `$after` must exist.
863
+ * 3. **`CheckLastVariable`** — `$last` must exist.
864
+ * 4. **`CheckBeforeVariable`** — `$before` must exist.
865
+ * 5. **`CheckQueryVariable`** — `$query` must exist.
866
+ * 6. **`CheckOrderVariable`** — `$order` must exist.
867
+ * 7. **`CheckOrderField`** — OrderInput field compatibility (metadata-aware).
868
+ * 8. **`CheckQueryInput`** — QueryInput key compatibility (metadata-aware).
762
869
  *
763
870
  * Each rule resolves to `{}` on pass or `{ __xxxError: "…" }` on fail.
764
871
  * A failing rule adds a phantom error property that makes `TQuery`
@@ -778,9 +885,20 @@ export type ValidateCollectionQuery<
778
885
  ExtractQueryVariables<TQuery> extends never
779
886
  ? TQuery // No gql-tada type info → skip validation
780
887
  : string extends TFieldName
781
- ? TQuery & CheckFirstVariable<TQuery> // No metadata → only check $first
888
+ ? TQuery &
889
+ CheckFirstVariable<TQuery> &
890
+ CheckAfterVariable<TQuery> &
891
+ CheckLastVariable<TQuery> &
892
+ CheckBeforeVariable<TQuery> &
893
+ CheckQueryVariable<TQuery> &
894
+ CheckOrderVariable<TQuery>
782
895
  : TQuery &
783
896
  CheckFirstVariable<TQuery> &
897
+ CheckAfterVariable<TQuery> &
898
+ CheckLastVariable<TQuery> &
899
+ CheckBeforeVariable<TQuery> &
900
+ CheckQueryVariable<TQuery> &
901
+ CheckOrderVariable<TQuery> &
784
902
  CheckOrderField<TQuery, TOrderableFieldName> &
785
903
  CheckQueryInput<TQuery, TFieldName>;
786
904
 
@@ -791,6 +909,11 @@ export type ValidateCollectionQuery<
791
909
  */
792
910
  export type HasCollectionQueryError<T> = T extends
793
911
  | { __firstVariableError: string }
912
+ | { __afterVariableError: string }
913
+ | { __lastVariableError: string }
914
+ | { __beforeVariableError: string }
915
+ | { __queryVariableError: string }
916
+ | { __orderVariableError: string }
794
917
  | { __orderFieldError: string }
795
918
  | { __queryInputError: string }
796
919
  ? true
@@ -982,9 +1105,11 @@ export interface PaginationProps {
982
1105
  /** Navigate to next page */
983
1106
  nextPage: (endCursor: string) => void;
984
1107
  /** Navigate to previous page */
985
- prevPage: () => void;
1108
+ prevPage: (startCursor: string) => void;
986
1109
  /** Whether a previous page exists */
987
1110
  hasPrevPage: boolean;
1111
+ /** Whether a next page exists */
1112
+ hasNextPage: boolean;
988
1113
  }
989
1114
 
990
1115
  // =============================================================================