@dyrected/core 2.10.0 → 2.11.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.
@@ -162,12 +162,24 @@ interface AdminDashboardComponentSlots {
162
162
  beforeDashboard?: string[];
163
163
  afterDashboard?: string[];
164
164
  }
165
+ /** Ordered custom component keys rendered around an operational view's content. */
166
+ interface CollectionViewComponentSlots {
167
+ beforeViewHeader?: string[];
168
+ afterViewHeader?: string[];
169
+ beforeViewContent?: string[];
170
+ afterViewContent?: string[];
171
+ }
165
172
  /** Ordered custom component keys rendered around a collection's list content. */
166
173
  interface CollectionListComponentSlots {
167
174
  beforeList?: string[];
168
175
  beforeListTable?: string[];
169
176
  afterListTable?: string[];
170
177
  afterList?: string[];
178
+ beforeViewHeader?: string[];
179
+ afterViewHeader?: string[];
180
+ beforeViewContent?: string[];
181
+ afterViewContent?: string[];
182
+ collectionView?: CollectionViewComponentSlots;
171
183
  }
172
184
  /**
173
185
  * Branding and metadata options for the Dyrected Admin UI.
@@ -944,6 +956,95 @@ type InferAggregateResult<T extends AggregateInput> = {
944
956
  [K in keyof T]: any;
945
957
  };
946
958
 
959
+ /**
960
+ * Dyrected Where Clause DSL — shared query language across all database adapters.
961
+ *
962
+ * Adapters translate this DSL into their native format:
963
+ * - SQL adapters (SQLite, Postgres, MySQL): use parseSqlWhere()
964
+ * - MongoDB adapter: use parseMongoWhere()
965
+ * - Future adapters: implement their own translator against WhereClause
966
+ *
967
+ * Exhaustive operator handling is enforced at compile time via `assertNever`,
968
+ * so adding a new operator without handling it will produce a TypeScript error
969
+ * in every adapter translator.
970
+ */
971
+ type WhereOperatorName = 'equals' | 'not_equals' | 'in' | 'not_in' | 'gt' | 'greater_than' | 'gte' | 'greater_than_equal' | 'greater_than_or_equal' | 'lt' | 'less_than' | 'lte' | 'less_than_equal' | 'less_than_or_equal' | 'contains' | 'like' | 'starts_with' | 'exists';
972
+ type WhereOperator = {
973
+ equals: any;
974
+ } | {
975
+ not_equals: any;
976
+ } | {
977
+ in: any[];
978
+ } | {
979
+ not_in: any[];
980
+ } | {
981
+ gt: any;
982
+ } | {
983
+ greater_than: any;
984
+ } | {
985
+ gte: any;
986
+ } | {
987
+ greater_than_equal: any;
988
+ } | {
989
+ greater_than_or_equal: any;
990
+ } | {
991
+ lt: any;
992
+ } | {
993
+ less_than: any;
994
+ } | {
995
+ lte: any;
996
+ } | {
997
+ less_than_equal: any;
998
+ } | {
999
+ less_than_or_equal: any;
1000
+ } | {
1001
+ contains: string;
1002
+ } | {
1003
+ like: string;
1004
+ } | {
1005
+ starts_with: string;
1006
+ } | {
1007
+ exists: boolean;
1008
+ };
1009
+ /** Top-level where clause. Fields map to operator objects or shorthand scalar values. */
1010
+ type WhereClause = {
1011
+ [field: string]: WhereOperator | any;
1012
+ OR?: WhereClause[];
1013
+ or?: WhereClause[];
1014
+ AND?: WhereClause[];
1015
+ and?: WhereClause[];
1016
+ };
1017
+ interface SqlWhereResult {
1018
+ sql: string;
1019
+ params: any[];
1020
+ }
1021
+ /**
1022
+ * Translates a WhereClause into a parameterized SQL WHERE fragment.
1023
+ *
1024
+ * @param where The Dyrected where DSL object
1025
+ * @param getJsonField Returns the SQL expression for a JSON-stored field (dialect-specific):
1026
+ * SQLite: (f) => `json_extract(data, '$.${f}')`
1027
+ * Postgres: (f) => `data->>'${f}'`
1028
+ * MySQL: (f) => `JSON_UNQUOTE(JSON_EXTRACT(data, '$.${f}'))`
1029
+ * @param placeholder '?' for SQLite/MySQL, 'pg' for auto-incrementing Postgres $1/$2/…
1030
+ */
1031
+ declare function parseSqlWhere(where: WhereClause, getJsonField: (field: string) => string, placeholder?: '?' | 'pg',
1032
+ /**
1033
+ * SQL keyword used for `contains`/`starts_with`. Postgres `LIKE` is
1034
+ * case-sensitive, so the Postgres adapter defaults to `'ILIKE'` to keep substring
1035
+ * matching case-insensitive like SQLite and MySQL.
1036
+ */
1037
+ likeOperator?: 'LIKE' | 'ILIKE'): SqlWhereResult;
1038
+ /**
1039
+ * Translates a WhereClause into a MongoDB filter object.
1040
+ * Handles nested OR/AND via $or/$and, and all operators via $eq/$in/$gt etc.
1041
+ */
1042
+ declare function parseMongoWhere(where: WhereClause): Record<string, any>;
1043
+
1044
+ /**
1045
+ * Custom component slots rendered around an operational view's content.
1046
+ */
1047
+ type ViewComponentSlots = CollectionViewComponentSlots;
947
1048
  /**
948
1049
  * Supported layout engines for operational views in the Dyrected Admin UI:
949
1050
  * - `'table'`: The workhorse — column sorting, search, faceted filters, and bulk actions.
@@ -1072,7 +1173,7 @@ interface ViewConfig {
1072
1173
  /** Layout engine to render: `'table' | 'spreadsheet' | 'kanban' | 'calendar' | 'gantt' | 'cards'`. Defaults to `'table'`. */
1073
1174
  layout?: ViewLayout;
1074
1175
  /** Base query filter applied before user toolbar filters (e.g. `{ attending: { equals: true } }` or JEXL string). */
1075
- filter?: Record<string, any> | string;
1176
+ filter?: WhereClause | string;
1076
1177
  /** Field name used to organize records into kanban columns or collapsible grouped sections in table, cards, and spreadsheet. */
1077
1178
  groupBy?: string;
1078
1179
  /** Field name containing the ISO date string for calendar placement. Required when `layout: 'calendar'`. */
@@ -1110,6 +1211,8 @@ interface ActionConfig<TDoc extends Record<string, unknown> = Record<string, unk
1110
1211
  name: string;
1111
1212
  /** Button label displayed in the UI. */
1112
1213
  label: string;
1214
+ /** Optional custom label for the modal submit button (defaults to "Run" or "Confirm"). */
1215
+ submitLabel?: string;
1113
1216
  /** Lucide icon name for the button (e.g. `"UserCheck"`, `"CheckCircle"`). */
1114
1217
  icon?: string;
1115
1218
  /** Action placement: `'row'` (per-row), `'bulk'` (multi-row selection bar), or `'header'` (view header). Defaults to `'row'`. */
@@ -1203,6 +1306,8 @@ interface DefineViewOptions {
1203
1306
  actionOrder?: string[];
1204
1307
  /** KPI summary cards rendered in the hero row above the view. */
1205
1308
  metrics?: ViewMetric[];
1309
+ /** Custom component slots rendered around this operational view. */
1310
+ components?: ViewComponentSlots;
1206
1311
  /** Role-based access rules controlling who can see or use this view. */
1207
1312
  access?: AccessConfig;
1208
1313
  }
@@ -1635,9 +1740,31 @@ interface CollectionConfig<TDoc extends object = Record<string, unknown>> {
1635
1740
  urlPattern?: string;
1636
1741
  };
1637
1742
  /**
1638
- * Custom detail view layout configuration for the Admin UI.
1743
+ * Detail view layout configuration for the Admin UI.
1744
+ *
1745
+ * By default, collections are **Edit-First** (`detail: false`). Clicking a record in the
1746
+ * table or cards view navigates directly to the editing form with Live Preview.
1747
+ *
1748
+ * Set to `true` to enable the automatic read-only summary layout, or provide a `DetailSchema`
1749
+ * array using display helpers (`displaySection`, `displayField`, `displayTabs`, etc.) for a
1750
+ * custom operational dashboard layout.
1751
+ *
1752
+ * @default false
1753
+ * @example
1754
+ * ```ts
1755
+ * // Enable automatic summary detail view
1756
+ * detail: true
1757
+ *
1758
+ * // Or define a custom operational detail view
1759
+ * detail: [
1760
+ * displaySection("Customer Overview", [
1761
+ * displayField("name", { span: 8 }),
1762
+ * displayField("status", { span: 4, display: "badge" }),
1763
+ * ]),
1764
+ * ]
1765
+ * ```
1639
1766
  */
1640
- detail?: DetailSchema<TDoc> | false;
1767
+ detail?: DetailSchema<TDoc> | boolean;
1641
1768
  /**
1642
1769
  * Slug of the operational view to render by default when navigating to `/collections/:slug`.
1643
1770
  *
@@ -1763,9 +1890,17 @@ interface GlobalConfig<TDoc extends object = Record<string, unknown>> {
1763
1890
  */
1764
1891
  initialData?: Partial<TDoc>;
1765
1892
  /**
1766
- * Custom detail view layout configuration for the Admin UI.
1893
+ * Detail view layout configuration for the Admin UI.
1894
+ *
1895
+ * By default, globals are **Edit-First** (`detail: false`). Clicking the global in the
1896
+ * sidebar navigates directly to the editing form.
1897
+ *
1898
+ * Set to `true` to enable the automatic read-only summary layout, or provide a `DetailSchema`
1899
+ * array for a custom operational dashboard layout.
1900
+ *
1901
+ * @default false
1767
1902
  */
1768
- detail?: DetailSchema<TDoc> | false;
1903
+ detail?: DetailSchema<TDoc> | boolean;
1769
1904
  }
1770
1905
 
1771
1906
  /**
@@ -2106,6 +2241,12 @@ interface FieldAdminOnChangeHookArgs<TValue = unknown> {
2106
2241
  siblingData: Record<string, unknown>;
2107
2242
  /** Current values for the entire form. */
2108
2243
  data: Record<string, unknown>;
2244
+ /** The targeted record / document when available. */
2245
+ doc?: Record<string, unknown>;
2246
+ /** Array of targeted records for bulk action operations. */
2247
+ docs?: Record<string, unknown>[];
2248
+ /** Current authenticated user. */
2249
+ user?: unknown;
2109
2250
  /** Imperative setter for async or derived updates. */
2110
2251
  setValue: (value: unknown) => void;
2111
2252
  }
@@ -2118,10 +2259,18 @@ type FieldAdminHooks<TValue> = {
2118
2259
  };
2119
2260
  };
2120
2261
  interface FieldAdminOptionsHookArgs {
2262
+ /** Current field value in the form state (if set). */
2263
+ value?: unknown;
2121
2264
  /** Current values for sibling fields at the same nesting level. */
2122
2265
  siblingData: Record<string, unknown>;
2123
2266
  /** Current values for the entire form. */
2124
2267
  data: Record<string, unknown>;
2268
+ /** The targeted record / document when available. */
2269
+ doc?: Record<string, unknown>;
2270
+ /** Array of targeted records for bulk action operations. */
2271
+ docs?: Record<string, unknown>[];
2272
+ /** Current authenticated user. */
2273
+ user?: unknown;
2125
2274
  }
2126
2275
  type FieldAdminOptionsHookResult = Array<string | {
2127
2276
  label: string;
@@ -2955,4 +3104,4 @@ interface DyrectedConfig<TUser extends AuthenticatedUser = AuthenticatedUser> {
2955
3104
  }>;
2956
3105
  }
2957
3106
 
2958
- export { type RadioField as $, type AdminAuthConfig as A, type Block as B, type CollectionConfig as C, type DyrectedConfig as D, type DetailText as E, type Field as F, type GlobalConfig as G, type HookRequestContext as H, type DetailSchema as I, type ArrayField as J, type BlocksField as K, type LifecycleEventName as L, type BooleanField as M, type AuthConfig as N, type AccessPolicyResolver as O, type PublicAdminAuthConfig as P, type DateField as Q, type DateTimeField as R, type EmailField as S, type IconField as T, type ImageField as U, type JoinField as V, type WorkflowConfig as W, type JsonField as X, type MultiSelectField as Y, type NumberField as Z, type ObjectField as _, type DeclarativeHookExpression as a, type DynamicOptionItem as a$, type RelationshipField as a0, type RichTextField as a1, type RowField as a2, type SelectField as a3, type TextField as a4, type TextareaField as a5, type TimeField as a6, type UrlField as a7, type AccessConfig as a8, type AccessFunction as a9, type BooleanFormat as aA, type CharacterLimitFieldAdmin as aB, type CharacterLimitFieldConfig as aC, type CollectionAfterChangeHook as aD, type CollectionAfterDeleteHook as aE, type CollectionAfterReadHook as aF, type CollectionAfterReadHookEntry as aG, type CollectionAfterTransitionHook as aH, type CollectionBeforeChangeHook as aI, type CollectionBeforeChangeHookEntry as aJ, type CollectionBeforeDeleteHook as aK, type CollectionBeforeReadHook as aL, type CollectionBeforeReadHookEntry as aM, type CollectionBeforeTransitionHook as aN, type CollectionListComponentSlots as aO, type CountOperation as aP, type CustomAdminAuthProvider as aQ, type DatabaseAdapter as aR, type DateFieldAdmin as aS, type DateFormat as aT, type DefineActionOptions as aU, type DefineViewOptions as aV, type DetailSpan as aW, type DisplayTone as aX, type DisplayVariant as aY, type DistinctCountOperation as aZ, type DistinctValuesOperation as a_, type AccessFunctionArgs as aa, type AccessResult as ab, type AccessRule as ac, type ActionConfig as ad, type ActionContext as ae, type ActionType as af, type AdminAuthAccessResolution as ag, type AdminAuthClaimMapping as ah, type AdminAuthMember as ai, type AdminAuthProvider as aj, type AdminAuthProviderMembersConfig as ak, type AdminAuthProvisioningMode as al, type AdminAuthResolveAccessArgs as am, type AdminAuthResolvedIdentity as an, type AdminConfig as ao, type AdminDashboardComponentSlots as ap, type AdminIconName as aq, type AggregateArgs as ar, type AggregateCastType as as, type AggregateInput as at, type AggregateOperation as au, type AggregateResult as av, type BaseAdminAuthProvider as aw, type BaseFieldAdmin as ax, type BlockVariant as ay, type BooleanFieldAdmin as az, type AuthenticatedUser as b, type UploadConfig as b$, type DynamicOptionsConfig as b0, type DynamicOptionsResolver as b1, type DynamicOptionsResolverArgs as b2, type DyrectedLoggerConfig as b3, type DyrectedObservabilityConfig as b4, type EmailFieldAdmin as b5, type FieldAdminHooks as b6, type FieldAdminOnChangeHook as b7, type FieldAdminOnChangeHookArgs as b8, type FieldAdminOptionsHook as b9, LIFECYCLE_EVENT_NAMES as bA, type LifecycleEventHandler as bB, type LinkFormat as bC, type MetricColor as bD, type MultiSelectFieldAdmin as bE, type NamedAccessPolicy as bF, type NumberFieldAdmin as bG, type NumberFormat as bH, type NumberLimitFieldAdmin as bI, type NumberLimitFieldConfig as bJ, type NumericOperation as bK, type OIDCAdminAuthProvider as bL, type OptionFormat as bM, type PaginatedResult as bN, type PublicAdminAuthProvider as bO, type RadioFieldAdmin as bP, type RateLimitConfig as bQ, type ReadonlyDatabaseAdapter as bR, type RichTextFeature as bS, type RichTextFieldConfig as bT, type SelectFieldAdmin as bU, type StorageAdapter as bV, type TextFieldAdmin as bW, type TextFormat as bX, type TextareaFieldAdmin as bY, type TrustProxyConfig as bZ, type TypedField as b_, type FieldAdminOptionsHookArgs as ba, type FieldAdminOptionsHookResult as bb, type FieldAfterReadHook as bc, type FieldAfterReadHookArgs as bd, type FieldBase as be, type FieldBeforeChangeHook as bf, type FieldBeforeChangeHookArgs as bg, type FieldHook as bh, type FieldHooks as bi, type FieldType as bj, type FileData as bk, type GlobalAfterChangeHook as bl, type GlobalAfterReadHook as bm, type GlobalAfterReadHookEntry as bn, type GlobalBeforeChangeHook as bo, type GlobalBeforeChangeHookEntry as bp, type GlobalBeforeReadHook as bq, type GlobalBeforeReadHookEntry as br, type HeadingLevel as bs, type HookFunction as bt, type IconFieldAdmin as bu, type ImageService as bv, type InferAggregateResult as bw, type JoinFieldAdmin as bx, type JsonFieldAdmin as by, type JsonFormat as bz, type WorkflowTransition as c, type UrlFieldAdmin as c0, type UrlLinkValue as c1, type ViewActionFeatures as c2, type ViewConfig as c3, type ViewLayout as c4, type ViewMetric as c5, type ViewSubMetric as c6, type WordLimitFieldAdmin as c7, type WordLimitFieldConfig as c8, type WorkflowMetadata as c9, type WorkflowRole as ca, type WorkflowState as cb, type WorkflowTransitionContext as cc, defineAction as cd, defineView as ce, type LifecycleEvent as d, type BaseDocument as e, type DetailComputedOptions as f, type ComputedHandler as g, type DetailComputed as h, type DetailCustomOptions as i, type DetailCustom as j, type DetailDividerOptions as k, type DetailDivider as l, type DisplayFieldOptions as m, type DetailField as n, type DetailItem as o, type DetailGridOptions as p, type DetailGrid as q, type DetailRepeatOptions as r, type DetailRepeat as s, type DetailSectionOptions as t, type DetailSection as u, type DetailTabOptions as v, type DetailTab as w, type DetailTabsOptions as x, type DetailTabs as y, type DetailTextOptions as z };
3107
+ export { type RadioField as $, type AdminAuthConfig as A, type Block as B, type CollectionConfig as C, type DyrectedConfig as D, type DetailText as E, type Field as F, type GlobalConfig as G, type HookRequestContext as H, type DetailSchema as I, type ArrayField as J, type BlocksField as K, type LifecycleEventName as L, type BooleanField as M, type AuthConfig as N, type AccessPolicyResolver as O, type PublicAdminAuthConfig as P, type DateField as Q, type DateTimeField as R, type EmailField as S, type IconField as T, type ImageField as U, type JoinField as V, type WorkflowConfig as W, type JsonField as X, type MultiSelectField as Y, type NumberField as Z, type ObjectField as _, type DeclarativeHookExpression as a, type DistinctValuesOperation as a$, type RelationshipField as a0, type RichTextField as a1, type RowField as a2, type SelectField as a3, type TextField as a4, type TextareaField as a5, type TimeField as a6, type UrlField as a7, type AccessConfig as a8, type AccessFunction as a9, type BooleanFormat as aA, type CharacterLimitFieldAdmin as aB, type CharacterLimitFieldConfig as aC, type CollectionAfterChangeHook as aD, type CollectionAfterDeleteHook as aE, type CollectionAfterReadHook as aF, type CollectionAfterReadHookEntry as aG, type CollectionAfterTransitionHook as aH, type CollectionBeforeChangeHook as aI, type CollectionBeforeChangeHookEntry as aJ, type CollectionBeforeDeleteHook as aK, type CollectionBeforeReadHook as aL, type CollectionBeforeReadHookEntry as aM, type CollectionBeforeTransitionHook as aN, type CollectionListComponentSlots as aO, type CollectionViewComponentSlots as aP, type CountOperation as aQ, type CustomAdminAuthProvider as aR, type DatabaseAdapter as aS, type DateFieldAdmin as aT, type DateFormat as aU, type DefineActionOptions as aV, type DefineViewOptions as aW, type DetailSpan as aX, type DisplayTone as aY, type DisplayVariant as aZ, type DistinctCountOperation as a_, type AccessFunctionArgs as aa, type AccessResult as ab, type AccessRule as ac, type ActionConfig as ad, type ActionContext as ae, type ActionType as af, type AdminAuthAccessResolution as ag, type AdminAuthClaimMapping as ah, type AdminAuthMember as ai, type AdminAuthProvider as aj, type AdminAuthProviderMembersConfig as ak, type AdminAuthProvisioningMode as al, type AdminAuthResolveAccessArgs as am, type AdminAuthResolvedIdentity as an, type AdminConfig as ao, type AdminDashboardComponentSlots as ap, type AdminIconName as aq, type AggregateArgs as ar, type AggregateCastType as as, type AggregateInput as at, type AggregateOperation as au, type AggregateResult as av, type BaseAdminAuthProvider as aw, type BaseFieldAdmin as ax, type BlockVariant as ay, type BooleanFieldAdmin as az, type AuthenticatedUser as b, type TrustProxyConfig as b$, type DynamicOptionItem as b0, type DynamicOptionsConfig as b1, type DynamicOptionsResolver as b2, type DynamicOptionsResolverArgs as b3, type DyrectedLoggerConfig as b4, type DyrectedObservabilityConfig as b5, type EmailFieldAdmin as b6, type FieldAdminHooks as b7, type FieldAdminOnChangeHook as b8, type FieldAdminOnChangeHookArgs as b9, type JsonFormat as bA, LIFECYCLE_EVENT_NAMES as bB, type LifecycleEventHandler as bC, type LinkFormat as bD, type MetricColor as bE, type MultiSelectFieldAdmin as bF, type NamedAccessPolicy as bG, type NumberFieldAdmin as bH, type NumberFormat as bI, type NumberLimitFieldAdmin as bJ, type NumberLimitFieldConfig as bK, type NumericOperation as bL, type OIDCAdminAuthProvider as bM, type OptionFormat as bN, type PaginatedResult as bO, type PublicAdminAuthProvider as bP, type RadioFieldAdmin as bQ, type RateLimitConfig as bR, type ReadonlyDatabaseAdapter as bS, type RichTextFeature as bT, type RichTextFieldConfig as bU, type SelectFieldAdmin as bV, type SqlWhereResult as bW, type StorageAdapter as bX, type TextFieldAdmin as bY, type TextFormat as bZ, type TextareaFieldAdmin as b_, type FieldAdminOptionsHook as ba, type FieldAdminOptionsHookArgs as bb, type FieldAdminOptionsHookResult as bc, type FieldAfterReadHook as bd, type FieldAfterReadHookArgs as be, type FieldBase as bf, type FieldBeforeChangeHook as bg, type FieldBeforeChangeHookArgs as bh, type FieldHook as bi, type FieldHooks as bj, type FieldType as bk, type FileData as bl, type GlobalAfterChangeHook as bm, type GlobalAfterReadHook as bn, type GlobalAfterReadHookEntry as bo, type GlobalBeforeChangeHook as bp, type GlobalBeforeChangeHookEntry as bq, type GlobalBeforeReadHook as br, type GlobalBeforeReadHookEntry as bs, type HeadingLevel as bt, type HookFunction as bu, type IconFieldAdmin as bv, type ImageService as bw, type InferAggregateResult as bx, type JoinFieldAdmin as by, type JsonFieldAdmin as bz, type WorkflowTransition as c, type TypedField as c0, type UploadConfig as c1, type UrlFieldAdmin as c2, type UrlLinkValue as c3, type ViewActionFeatures as c4, type ViewComponentSlots as c5, type ViewConfig as c6, type ViewLayout as c7, type ViewMetric as c8, type ViewSubMetric as c9, type WhereClause as ca, type WhereOperator as cb, type WhereOperatorName as cc, type WordLimitFieldAdmin as cd, type WordLimitFieldConfig as ce, type WorkflowMetadata as cf, type WorkflowRole as cg, type WorkflowState as ch, type WorkflowTransitionContext as ci, defineAction as cj, defineView as ck, parseMongoWhere as cl, parseSqlWhere as cm, type LifecycleEvent as d, type BaseDocument as e, type DetailComputedOptions as f, type ComputedHandler as g, type DetailComputed as h, type DetailCustomOptions as i, type DetailCustom as j, type DetailDividerOptions as k, type DetailDivider as l, type DisplayFieldOptions as m, type DetailField as n, type DetailItem as o, type DetailGridOptions as p, type DetailGrid as q, type DetailRepeatOptions as r, type DetailRepeat as s, type DetailSectionOptions as t, type DetailSection as u, type DetailTabOptions as v, type DetailTab as w, type DetailTabsOptions as x, type DetailTabs as y, type DetailTextOptions as z };
@@ -162,12 +162,24 @@ interface AdminDashboardComponentSlots {
162
162
  beforeDashboard?: string[];
163
163
  afterDashboard?: string[];
164
164
  }
165
+ /** Ordered custom component keys rendered around an operational view's content. */
166
+ interface CollectionViewComponentSlots {
167
+ beforeViewHeader?: string[];
168
+ afterViewHeader?: string[];
169
+ beforeViewContent?: string[];
170
+ afterViewContent?: string[];
171
+ }
165
172
  /** Ordered custom component keys rendered around a collection's list content. */
166
173
  interface CollectionListComponentSlots {
167
174
  beforeList?: string[];
168
175
  beforeListTable?: string[];
169
176
  afterListTable?: string[];
170
177
  afterList?: string[];
178
+ beforeViewHeader?: string[];
179
+ afterViewHeader?: string[];
180
+ beforeViewContent?: string[];
181
+ afterViewContent?: string[];
182
+ collectionView?: CollectionViewComponentSlots;
171
183
  }
172
184
  /**
173
185
  * Branding and metadata options for the Dyrected Admin UI.
@@ -944,6 +956,95 @@ type InferAggregateResult<T extends AggregateInput> = {
944
956
  [K in keyof T]: any;
945
957
  };
946
958
 
959
+ /**
960
+ * Dyrected Where Clause DSL — shared query language across all database adapters.
961
+ *
962
+ * Adapters translate this DSL into their native format:
963
+ * - SQL adapters (SQLite, Postgres, MySQL): use parseSqlWhere()
964
+ * - MongoDB adapter: use parseMongoWhere()
965
+ * - Future adapters: implement their own translator against WhereClause
966
+ *
967
+ * Exhaustive operator handling is enforced at compile time via `assertNever`,
968
+ * so adding a new operator without handling it will produce a TypeScript error
969
+ * in every adapter translator.
970
+ */
971
+ type WhereOperatorName = 'equals' | 'not_equals' | 'in' | 'not_in' | 'gt' | 'greater_than' | 'gte' | 'greater_than_equal' | 'greater_than_or_equal' | 'lt' | 'less_than' | 'lte' | 'less_than_equal' | 'less_than_or_equal' | 'contains' | 'like' | 'starts_with' | 'exists';
972
+ type WhereOperator = {
973
+ equals: any;
974
+ } | {
975
+ not_equals: any;
976
+ } | {
977
+ in: any[];
978
+ } | {
979
+ not_in: any[];
980
+ } | {
981
+ gt: any;
982
+ } | {
983
+ greater_than: any;
984
+ } | {
985
+ gte: any;
986
+ } | {
987
+ greater_than_equal: any;
988
+ } | {
989
+ greater_than_or_equal: any;
990
+ } | {
991
+ lt: any;
992
+ } | {
993
+ less_than: any;
994
+ } | {
995
+ lte: any;
996
+ } | {
997
+ less_than_equal: any;
998
+ } | {
999
+ less_than_or_equal: any;
1000
+ } | {
1001
+ contains: string;
1002
+ } | {
1003
+ like: string;
1004
+ } | {
1005
+ starts_with: string;
1006
+ } | {
1007
+ exists: boolean;
1008
+ };
1009
+ /** Top-level where clause. Fields map to operator objects or shorthand scalar values. */
1010
+ type WhereClause = {
1011
+ [field: string]: WhereOperator | any;
1012
+ OR?: WhereClause[];
1013
+ or?: WhereClause[];
1014
+ AND?: WhereClause[];
1015
+ and?: WhereClause[];
1016
+ };
1017
+ interface SqlWhereResult {
1018
+ sql: string;
1019
+ params: any[];
1020
+ }
1021
+ /**
1022
+ * Translates a WhereClause into a parameterized SQL WHERE fragment.
1023
+ *
1024
+ * @param where The Dyrected where DSL object
1025
+ * @param getJsonField Returns the SQL expression for a JSON-stored field (dialect-specific):
1026
+ * SQLite: (f) => `json_extract(data, '$.${f}')`
1027
+ * Postgres: (f) => `data->>'${f}'`
1028
+ * MySQL: (f) => `JSON_UNQUOTE(JSON_EXTRACT(data, '$.${f}'))`
1029
+ * @param placeholder '?' for SQLite/MySQL, 'pg' for auto-incrementing Postgres $1/$2/…
1030
+ */
1031
+ declare function parseSqlWhere(where: WhereClause, getJsonField: (field: string) => string, placeholder?: '?' | 'pg',
1032
+ /**
1033
+ * SQL keyword used for `contains`/`starts_with`. Postgres `LIKE` is
1034
+ * case-sensitive, so the Postgres adapter defaults to `'ILIKE'` to keep substring
1035
+ * matching case-insensitive like SQLite and MySQL.
1036
+ */
1037
+ likeOperator?: 'LIKE' | 'ILIKE'): SqlWhereResult;
1038
+ /**
1039
+ * Translates a WhereClause into a MongoDB filter object.
1040
+ * Handles nested OR/AND via $or/$and, and all operators via $eq/$in/$gt etc.
1041
+ */
1042
+ declare function parseMongoWhere(where: WhereClause): Record<string, any>;
1043
+
1044
+ /**
1045
+ * Custom component slots rendered around an operational view's content.
1046
+ */
1047
+ type ViewComponentSlots = CollectionViewComponentSlots;
947
1048
  /**
948
1049
  * Supported layout engines for operational views in the Dyrected Admin UI:
949
1050
  * - `'table'`: The workhorse — column sorting, search, faceted filters, and bulk actions.
@@ -1072,7 +1173,7 @@ interface ViewConfig {
1072
1173
  /** Layout engine to render: `'table' | 'spreadsheet' | 'kanban' | 'calendar' | 'gantt' | 'cards'`. Defaults to `'table'`. */
1073
1174
  layout?: ViewLayout;
1074
1175
  /** Base query filter applied before user toolbar filters (e.g. `{ attending: { equals: true } }` or JEXL string). */
1075
- filter?: Record<string, any> | string;
1176
+ filter?: WhereClause | string;
1076
1177
  /** Field name used to organize records into kanban columns or collapsible grouped sections in table, cards, and spreadsheet. */
1077
1178
  groupBy?: string;
1078
1179
  /** Field name containing the ISO date string for calendar placement. Required when `layout: 'calendar'`. */
@@ -1110,6 +1211,8 @@ interface ActionConfig<TDoc extends Record<string, unknown> = Record<string, unk
1110
1211
  name: string;
1111
1212
  /** Button label displayed in the UI. */
1112
1213
  label: string;
1214
+ /** Optional custom label for the modal submit button (defaults to "Run" or "Confirm"). */
1215
+ submitLabel?: string;
1113
1216
  /** Lucide icon name for the button (e.g. `"UserCheck"`, `"CheckCircle"`). */
1114
1217
  icon?: string;
1115
1218
  /** Action placement: `'row'` (per-row), `'bulk'` (multi-row selection bar), or `'header'` (view header). Defaults to `'row'`. */
@@ -1203,6 +1306,8 @@ interface DefineViewOptions {
1203
1306
  actionOrder?: string[];
1204
1307
  /** KPI summary cards rendered in the hero row above the view. */
1205
1308
  metrics?: ViewMetric[];
1309
+ /** Custom component slots rendered around this operational view. */
1310
+ components?: ViewComponentSlots;
1206
1311
  /** Role-based access rules controlling who can see or use this view. */
1207
1312
  access?: AccessConfig;
1208
1313
  }
@@ -1635,9 +1740,31 @@ interface CollectionConfig<TDoc extends object = Record<string, unknown>> {
1635
1740
  urlPattern?: string;
1636
1741
  };
1637
1742
  /**
1638
- * Custom detail view layout configuration for the Admin UI.
1743
+ * Detail view layout configuration for the Admin UI.
1744
+ *
1745
+ * By default, collections are **Edit-First** (`detail: false`). Clicking a record in the
1746
+ * table or cards view navigates directly to the editing form with Live Preview.
1747
+ *
1748
+ * Set to `true` to enable the automatic read-only summary layout, or provide a `DetailSchema`
1749
+ * array using display helpers (`displaySection`, `displayField`, `displayTabs`, etc.) for a
1750
+ * custom operational dashboard layout.
1751
+ *
1752
+ * @default false
1753
+ * @example
1754
+ * ```ts
1755
+ * // Enable automatic summary detail view
1756
+ * detail: true
1757
+ *
1758
+ * // Or define a custom operational detail view
1759
+ * detail: [
1760
+ * displaySection("Customer Overview", [
1761
+ * displayField("name", { span: 8 }),
1762
+ * displayField("status", { span: 4, display: "badge" }),
1763
+ * ]),
1764
+ * ]
1765
+ * ```
1639
1766
  */
1640
- detail?: DetailSchema<TDoc> | false;
1767
+ detail?: DetailSchema<TDoc> | boolean;
1641
1768
  /**
1642
1769
  * Slug of the operational view to render by default when navigating to `/collections/:slug`.
1643
1770
  *
@@ -1763,9 +1890,17 @@ interface GlobalConfig<TDoc extends object = Record<string, unknown>> {
1763
1890
  */
1764
1891
  initialData?: Partial<TDoc>;
1765
1892
  /**
1766
- * Custom detail view layout configuration for the Admin UI.
1893
+ * Detail view layout configuration for the Admin UI.
1894
+ *
1895
+ * By default, globals are **Edit-First** (`detail: false`). Clicking the global in the
1896
+ * sidebar navigates directly to the editing form.
1897
+ *
1898
+ * Set to `true` to enable the automatic read-only summary layout, or provide a `DetailSchema`
1899
+ * array for a custom operational dashboard layout.
1900
+ *
1901
+ * @default false
1767
1902
  */
1768
- detail?: DetailSchema<TDoc> | false;
1903
+ detail?: DetailSchema<TDoc> | boolean;
1769
1904
  }
1770
1905
 
1771
1906
  /**
@@ -2106,6 +2241,12 @@ interface FieldAdminOnChangeHookArgs<TValue = unknown> {
2106
2241
  siblingData: Record<string, unknown>;
2107
2242
  /** Current values for the entire form. */
2108
2243
  data: Record<string, unknown>;
2244
+ /** The targeted record / document when available. */
2245
+ doc?: Record<string, unknown>;
2246
+ /** Array of targeted records for bulk action operations. */
2247
+ docs?: Record<string, unknown>[];
2248
+ /** Current authenticated user. */
2249
+ user?: unknown;
2109
2250
  /** Imperative setter for async or derived updates. */
2110
2251
  setValue: (value: unknown) => void;
2111
2252
  }
@@ -2118,10 +2259,18 @@ type FieldAdminHooks<TValue> = {
2118
2259
  };
2119
2260
  };
2120
2261
  interface FieldAdminOptionsHookArgs {
2262
+ /** Current field value in the form state (if set). */
2263
+ value?: unknown;
2121
2264
  /** Current values for sibling fields at the same nesting level. */
2122
2265
  siblingData: Record<string, unknown>;
2123
2266
  /** Current values for the entire form. */
2124
2267
  data: Record<string, unknown>;
2268
+ /** The targeted record / document when available. */
2269
+ doc?: Record<string, unknown>;
2270
+ /** Array of targeted records for bulk action operations. */
2271
+ docs?: Record<string, unknown>[];
2272
+ /** Current authenticated user. */
2273
+ user?: unknown;
2125
2274
  }
2126
2275
  type FieldAdminOptionsHookResult = Array<string | {
2127
2276
  label: string;
@@ -2955,4 +3104,4 @@ interface DyrectedConfig<TUser extends AuthenticatedUser = AuthenticatedUser> {
2955
3104
  }>;
2956
3105
  }
2957
3106
 
2958
- export { type RadioField as $, type AdminAuthConfig as A, type Block as B, type CollectionConfig as C, type DyrectedConfig as D, type DetailText as E, type Field as F, type GlobalConfig as G, type HookRequestContext as H, type DetailSchema as I, type ArrayField as J, type BlocksField as K, type LifecycleEventName as L, type BooleanField as M, type AuthConfig as N, type AccessPolicyResolver as O, type PublicAdminAuthConfig as P, type DateField as Q, type DateTimeField as R, type EmailField as S, type IconField as T, type ImageField as U, type JoinField as V, type WorkflowConfig as W, type JsonField as X, type MultiSelectField as Y, type NumberField as Z, type ObjectField as _, type DeclarativeHookExpression as a, type DynamicOptionItem as a$, type RelationshipField as a0, type RichTextField as a1, type RowField as a2, type SelectField as a3, type TextField as a4, type TextareaField as a5, type TimeField as a6, type UrlField as a7, type AccessConfig as a8, type AccessFunction as a9, type BooleanFormat as aA, type CharacterLimitFieldAdmin as aB, type CharacterLimitFieldConfig as aC, type CollectionAfterChangeHook as aD, type CollectionAfterDeleteHook as aE, type CollectionAfterReadHook as aF, type CollectionAfterReadHookEntry as aG, type CollectionAfterTransitionHook as aH, type CollectionBeforeChangeHook as aI, type CollectionBeforeChangeHookEntry as aJ, type CollectionBeforeDeleteHook as aK, type CollectionBeforeReadHook as aL, type CollectionBeforeReadHookEntry as aM, type CollectionBeforeTransitionHook as aN, type CollectionListComponentSlots as aO, type CountOperation as aP, type CustomAdminAuthProvider as aQ, type DatabaseAdapter as aR, type DateFieldAdmin as aS, type DateFormat as aT, type DefineActionOptions as aU, type DefineViewOptions as aV, type DetailSpan as aW, type DisplayTone as aX, type DisplayVariant as aY, type DistinctCountOperation as aZ, type DistinctValuesOperation as a_, type AccessFunctionArgs as aa, type AccessResult as ab, type AccessRule as ac, type ActionConfig as ad, type ActionContext as ae, type ActionType as af, type AdminAuthAccessResolution as ag, type AdminAuthClaimMapping as ah, type AdminAuthMember as ai, type AdminAuthProvider as aj, type AdminAuthProviderMembersConfig as ak, type AdminAuthProvisioningMode as al, type AdminAuthResolveAccessArgs as am, type AdminAuthResolvedIdentity as an, type AdminConfig as ao, type AdminDashboardComponentSlots as ap, type AdminIconName as aq, type AggregateArgs as ar, type AggregateCastType as as, type AggregateInput as at, type AggregateOperation as au, type AggregateResult as av, type BaseAdminAuthProvider as aw, type BaseFieldAdmin as ax, type BlockVariant as ay, type BooleanFieldAdmin as az, type AuthenticatedUser as b, type UploadConfig as b$, type DynamicOptionsConfig as b0, type DynamicOptionsResolver as b1, type DynamicOptionsResolverArgs as b2, type DyrectedLoggerConfig as b3, type DyrectedObservabilityConfig as b4, type EmailFieldAdmin as b5, type FieldAdminHooks as b6, type FieldAdminOnChangeHook as b7, type FieldAdminOnChangeHookArgs as b8, type FieldAdminOptionsHook as b9, LIFECYCLE_EVENT_NAMES as bA, type LifecycleEventHandler as bB, type LinkFormat as bC, type MetricColor as bD, type MultiSelectFieldAdmin as bE, type NamedAccessPolicy as bF, type NumberFieldAdmin as bG, type NumberFormat as bH, type NumberLimitFieldAdmin as bI, type NumberLimitFieldConfig as bJ, type NumericOperation as bK, type OIDCAdminAuthProvider as bL, type OptionFormat as bM, type PaginatedResult as bN, type PublicAdminAuthProvider as bO, type RadioFieldAdmin as bP, type RateLimitConfig as bQ, type ReadonlyDatabaseAdapter as bR, type RichTextFeature as bS, type RichTextFieldConfig as bT, type SelectFieldAdmin as bU, type StorageAdapter as bV, type TextFieldAdmin as bW, type TextFormat as bX, type TextareaFieldAdmin as bY, type TrustProxyConfig as bZ, type TypedField as b_, type FieldAdminOptionsHookArgs as ba, type FieldAdminOptionsHookResult as bb, type FieldAfterReadHook as bc, type FieldAfterReadHookArgs as bd, type FieldBase as be, type FieldBeforeChangeHook as bf, type FieldBeforeChangeHookArgs as bg, type FieldHook as bh, type FieldHooks as bi, type FieldType as bj, type FileData as bk, type GlobalAfterChangeHook as bl, type GlobalAfterReadHook as bm, type GlobalAfterReadHookEntry as bn, type GlobalBeforeChangeHook as bo, type GlobalBeforeChangeHookEntry as bp, type GlobalBeforeReadHook as bq, type GlobalBeforeReadHookEntry as br, type HeadingLevel as bs, type HookFunction as bt, type IconFieldAdmin as bu, type ImageService as bv, type InferAggregateResult as bw, type JoinFieldAdmin as bx, type JsonFieldAdmin as by, type JsonFormat as bz, type WorkflowTransition as c, type UrlFieldAdmin as c0, type UrlLinkValue as c1, type ViewActionFeatures as c2, type ViewConfig as c3, type ViewLayout as c4, type ViewMetric as c5, type ViewSubMetric as c6, type WordLimitFieldAdmin as c7, type WordLimitFieldConfig as c8, type WorkflowMetadata as c9, type WorkflowRole as ca, type WorkflowState as cb, type WorkflowTransitionContext as cc, defineAction as cd, defineView as ce, type LifecycleEvent as d, type BaseDocument as e, type DetailComputedOptions as f, type ComputedHandler as g, type DetailComputed as h, type DetailCustomOptions as i, type DetailCustom as j, type DetailDividerOptions as k, type DetailDivider as l, type DisplayFieldOptions as m, type DetailField as n, type DetailItem as o, type DetailGridOptions as p, type DetailGrid as q, type DetailRepeatOptions as r, type DetailRepeat as s, type DetailSectionOptions as t, type DetailSection as u, type DetailTabOptions as v, type DetailTab as w, type DetailTabsOptions as x, type DetailTabs as y, type DetailTextOptions as z };
3107
+ export { type RadioField as $, type AdminAuthConfig as A, type Block as B, type CollectionConfig as C, type DyrectedConfig as D, type DetailText as E, type Field as F, type GlobalConfig as G, type HookRequestContext as H, type DetailSchema as I, type ArrayField as J, type BlocksField as K, type LifecycleEventName as L, type BooleanField as M, type AuthConfig as N, type AccessPolicyResolver as O, type PublicAdminAuthConfig as P, type DateField as Q, type DateTimeField as R, type EmailField as S, type IconField as T, type ImageField as U, type JoinField as V, type WorkflowConfig as W, type JsonField as X, type MultiSelectField as Y, type NumberField as Z, type ObjectField as _, type DeclarativeHookExpression as a, type DistinctValuesOperation as a$, type RelationshipField as a0, type RichTextField as a1, type RowField as a2, type SelectField as a3, type TextField as a4, type TextareaField as a5, type TimeField as a6, type UrlField as a7, type AccessConfig as a8, type AccessFunction as a9, type BooleanFormat as aA, type CharacterLimitFieldAdmin as aB, type CharacterLimitFieldConfig as aC, type CollectionAfterChangeHook as aD, type CollectionAfterDeleteHook as aE, type CollectionAfterReadHook as aF, type CollectionAfterReadHookEntry as aG, type CollectionAfterTransitionHook as aH, type CollectionBeforeChangeHook as aI, type CollectionBeforeChangeHookEntry as aJ, type CollectionBeforeDeleteHook as aK, type CollectionBeforeReadHook as aL, type CollectionBeforeReadHookEntry as aM, type CollectionBeforeTransitionHook as aN, type CollectionListComponentSlots as aO, type CollectionViewComponentSlots as aP, type CountOperation as aQ, type CustomAdminAuthProvider as aR, type DatabaseAdapter as aS, type DateFieldAdmin as aT, type DateFormat as aU, type DefineActionOptions as aV, type DefineViewOptions as aW, type DetailSpan as aX, type DisplayTone as aY, type DisplayVariant as aZ, type DistinctCountOperation as a_, type AccessFunctionArgs as aa, type AccessResult as ab, type AccessRule as ac, type ActionConfig as ad, type ActionContext as ae, type ActionType as af, type AdminAuthAccessResolution as ag, type AdminAuthClaimMapping as ah, type AdminAuthMember as ai, type AdminAuthProvider as aj, type AdminAuthProviderMembersConfig as ak, type AdminAuthProvisioningMode as al, type AdminAuthResolveAccessArgs as am, type AdminAuthResolvedIdentity as an, type AdminConfig as ao, type AdminDashboardComponentSlots as ap, type AdminIconName as aq, type AggregateArgs as ar, type AggregateCastType as as, type AggregateInput as at, type AggregateOperation as au, type AggregateResult as av, type BaseAdminAuthProvider as aw, type BaseFieldAdmin as ax, type BlockVariant as ay, type BooleanFieldAdmin as az, type AuthenticatedUser as b, type TrustProxyConfig as b$, type DynamicOptionItem as b0, type DynamicOptionsConfig as b1, type DynamicOptionsResolver as b2, type DynamicOptionsResolverArgs as b3, type DyrectedLoggerConfig as b4, type DyrectedObservabilityConfig as b5, type EmailFieldAdmin as b6, type FieldAdminHooks as b7, type FieldAdminOnChangeHook as b8, type FieldAdminOnChangeHookArgs as b9, type JsonFormat as bA, LIFECYCLE_EVENT_NAMES as bB, type LifecycleEventHandler as bC, type LinkFormat as bD, type MetricColor as bE, type MultiSelectFieldAdmin as bF, type NamedAccessPolicy as bG, type NumberFieldAdmin as bH, type NumberFormat as bI, type NumberLimitFieldAdmin as bJ, type NumberLimitFieldConfig as bK, type NumericOperation as bL, type OIDCAdminAuthProvider as bM, type OptionFormat as bN, type PaginatedResult as bO, type PublicAdminAuthProvider as bP, type RadioFieldAdmin as bQ, type RateLimitConfig as bR, type ReadonlyDatabaseAdapter as bS, type RichTextFeature as bT, type RichTextFieldConfig as bU, type SelectFieldAdmin as bV, type SqlWhereResult as bW, type StorageAdapter as bX, type TextFieldAdmin as bY, type TextFormat as bZ, type TextareaFieldAdmin as b_, type FieldAdminOptionsHook as ba, type FieldAdminOptionsHookArgs as bb, type FieldAdminOptionsHookResult as bc, type FieldAfterReadHook as bd, type FieldAfterReadHookArgs as be, type FieldBase as bf, type FieldBeforeChangeHook as bg, type FieldBeforeChangeHookArgs as bh, type FieldHook as bi, type FieldHooks as bj, type FieldType as bk, type FileData as bl, type GlobalAfterChangeHook as bm, type GlobalAfterReadHook as bn, type GlobalAfterReadHookEntry as bo, type GlobalBeforeChangeHook as bp, type GlobalBeforeChangeHookEntry as bq, type GlobalBeforeReadHook as br, type GlobalBeforeReadHookEntry as bs, type HeadingLevel as bt, type HookFunction as bu, type IconFieldAdmin as bv, type ImageService as bw, type InferAggregateResult as bx, type JoinFieldAdmin as by, type JsonFieldAdmin as bz, type WorkflowTransition as c, type TypedField as c0, type UploadConfig as c1, type UrlFieldAdmin as c2, type UrlLinkValue as c3, type ViewActionFeatures as c4, type ViewComponentSlots as c5, type ViewConfig as c6, type ViewLayout as c7, type ViewMetric as c8, type ViewSubMetric as c9, type WhereClause as ca, type WhereOperator as cb, type WhereOperatorName as cc, type WordLimitFieldAdmin as cd, type WordLimitFieldConfig as ce, type WorkflowMetadata as cf, type WorkflowRole as cg, type WorkflowState as ch, type WorkflowTransitionContext as ci, defineAction as cj, defineView as ck, parseMongoWhere as cl, parseSqlWhere as cm, type LifecycleEvent as d, type BaseDocument as e, type DetailComputedOptions as f, type ComputedHandler as g, type DetailComputed as h, type DetailCustomOptions as i, type DetailCustom as j, type DetailDividerOptions as k, type DetailDivider as l, type DisplayFieldOptions as m, type DetailField as n, type DetailItem as o, type DetailGridOptions as p, type DetailGrid as q, type DetailRepeatOptions as r, type DetailRepeat as s, type DetailSectionOptions as t, type DetailSection as u, type DetailTabOptions as v, type DetailTab as w, type DetailTabsOptions as x, type DetailTabs as y, type DetailTextOptions as z };
@@ -2474,6 +2474,11 @@ function registerJexlHelpers(jexlInstance = import_jexl.default) {
2474
2474
  try {
2475
2475
  jexlInstance.addBinaryOp("and", 20, (left, right) => Boolean(left && right));
2476
2476
  jexlInstance.addBinaryOp("or", 10, (left, right) => Boolean(left || right));
2477
+ jexlInstance.addBinaryOp("in", 30, (left, right) => {
2478
+ if (Array.isArray(right)) return right.includes(left);
2479
+ if (typeof right === "string") return right.includes(String(left ?? ""));
2480
+ return false;
2481
+ });
2477
2482
  } catch {
2478
2483
  }
2479
2484
  }