@gzl10/nexus-sdk 0.14.0 → 0.15.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.
@@ -443,6 +443,7 @@ function createMasterSelect(config) {
443
443
  const {
444
444
  label,
445
445
  master,
446
+ defaultValue,
446
447
  hint,
447
448
  required,
448
449
  nullable,
@@ -454,6 +455,7 @@ function createMasterSelect(config) {
454
455
  return {
455
456
  label,
456
457
  input: "select",
458
+ defaultValue,
457
459
  hint,
458
460
  required: required ?? false,
459
461
  db: {
@@ -505,6 +507,26 @@ function useTextareaField(config) {
505
507
  };
506
508
  }
507
509
 
510
+ // src/fields/code.ts
511
+ function useCodeField(config) {
512
+ const { label, hint, required, nullable, defaultValue, language, placeholder, meta, ...overrides } = config;
513
+ return {
514
+ label,
515
+ input: "code",
516
+ hint,
517
+ required: required ?? false,
518
+ defaultValue,
519
+ placeholder,
520
+ db: {
521
+ type: "text",
522
+ nullable: nullable ?? !required
523
+ },
524
+ ...language ? { inputProps: { language } } : {},
525
+ meta,
526
+ ...overrides
527
+ };
528
+ }
529
+
508
530
  // src/fields/json.ts
509
531
  function useJsonField(config) {
510
532
  const { label, hint, required, nullable, meta, ...overrides } = config;
@@ -717,6 +739,150 @@ function useTagsField(config) {
717
739
  };
718
740
  }
719
741
 
742
+ // src/fields/name.ts
743
+ function useNameField(config) {
744
+ const {
745
+ size = 100,
746
+ unique = false,
747
+ placeholder,
748
+ hint,
749
+ validation,
750
+ disabled,
751
+ meta,
752
+ ...overrides
753
+ } = config ?? {};
754
+ return {
755
+ label: { en: "Name", es: "Nombre" },
756
+ input: "text",
757
+ hint,
758
+ required: true,
759
+ disabled,
760
+ placeholder,
761
+ db: {
762
+ type: "string",
763
+ size,
764
+ nullable: false,
765
+ index: unique,
766
+ unique
767
+ },
768
+ validation: {
769
+ min: 1,
770
+ max: size,
771
+ ...validation
772
+ },
773
+ meta: {
774
+ sortable: true,
775
+ searchable: true,
776
+ ...meta
777
+ },
778
+ ...overrides
779
+ };
780
+ }
781
+
782
+ // src/fields/description.ts
783
+ function useDescriptionField(config) {
784
+ const {
785
+ mode = "textarea",
786
+ localized = false,
787
+ searchable,
788
+ nullable = true,
789
+ size = 255,
790
+ meta,
791
+ ...overrides
792
+ } = config ?? {};
793
+ const isLocalized = localized;
794
+ const input = isLocalized ? "text" : mode;
795
+ const db = isLocalized ? { type: "json", nullable } : mode === "text" ? { type: "string", size, nullable } : { type: "text", nullable };
796
+ return {
797
+ label: { en: "Description", es: "Descripci\xF3n" },
798
+ input,
799
+ db,
800
+ meta: {
801
+ ...searchable ? { searchable: true } : {},
802
+ ...meta
803
+ },
804
+ ...overrides
805
+ };
806
+ }
807
+
808
+ // src/fields/metadata.ts
809
+ function useMetadataField(config) {
810
+ const { hint, meta, ...overrides } = config ?? {};
811
+ return {
812
+ label: { en: "Metadata", es: "Metadatos" },
813
+ input: "json",
814
+ hint,
815
+ hidden: true,
816
+ db: { type: "json", nullable: true },
817
+ meta: {
818
+ exportable: false,
819
+ showInDisplay: false,
820
+ ...meta
821
+ },
822
+ ...overrides
823
+ };
824
+ }
825
+
826
+ // src/fields/enabled.ts
827
+ function useEnabledField(config) {
828
+ const { searchable, meta, ...overrides } = config ?? {};
829
+ return {
830
+ label: { en: "Enabled", es: "Habilitado" },
831
+ input: "switch",
832
+ defaultValue: true,
833
+ db: {
834
+ type: "boolean",
835
+ nullable: false,
836
+ default: true
837
+ },
838
+ meta: {
839
+ ...searchable ? { searchable: true } : {},
840
+ ...meta
841
+ },
842
+ ...overrides
843
+ };
844
+ }
845
+
846
+ // src/fields/public.ts
847
+ function usePublicField(config) {
848
+ const { hint, searchable, meta, ...overrides } = config;
849
+ return {
850
+ label: { en: "Public", es: "P\xFAblico" },
851
+ input: "switch",
852
+ hint,
853
+ defaultValue: false,
854
+ db: {
855
+ type: "boolean",
856
+ nullable: false,
857
+ default: false
858
+ },
859
+ meta: {
860
+ ...searchable ? { searchable: true } : {},
861
+ ...meta
862
+ },
863
+ ...overrides
864
+ };
865
+ }
866
+
867
+ // src/fields/expires-at.ts
868
+ function useExpiresAtField(config) {
869
+ const { required, nullable = true, meta, ...overrides } = config ?? {};
870
+ return {
871
+ label: { en: "Expires", es: "Expira" },
872
+ input: "datetime",
873
+ ...required ? { required: true } : {},
874
+ db: {
875
+ type: "datetime",
876
+ nullable
877
+ },
878
+ meta: {
879
+ sortable: true,
880
+ ...meta
881
+ },
882
+ ...overrides
883
+ };
884
+ }
885
+
720
886
  // src/fields/common.ts
721
887
  var idField = useIdField("ulid");
722
888
  var userIdField = {
@@ -799,6 +965,7 @@ export {
799
965
  useUrlField,
800
966
  useSelectField,
801
967
  useTextareaField,
968
+ useCodeField,
802
969
  useJsonField,
803
970
  useDatetimeField,
804
971
  useNumberField,
@@ -809,6 +976,12 @@ export {
809
976
  useCheckboxField,
810
977
  usePasswordField,
811
978
  useTagsField,
979
+ useNameField,
980
+ useDescriptionField,
981
+ useMetadataField,
982
+ useEnabledField,
983
+ usePublicField,
984
+ useExpiresAtField,
812
985
  idField,
813
986
  userIdField,
814
987
  isActiveField,
@@ -1,5 +1,5 @@
1
- import { L as LocalizedString, b as FieldDefinition } from '../field-D6eIbvjc.js';
2
- import { s as RolePermission, d as CollectionEntityDefinition, f as DagEntityDefinition, e as EventEntityDefinition } from '../entity-BnVQn6la.js';
1
+ import { L as LocalizedString, b as FieldDefinition } from '../field-KvvQ9oHe.js';
2
+ import { s as RolePermission, d as CollectionEntityDefinition, f as DagEntityDefinition, e as EventEntityDefinition } from '../entity-Bwf8yboo.js';
3
3
  import 'knex';
4
4
  import 'express';
5
5
  import 'pino';
@@ -17,7 +17,7 @@ import {
17
17
  useTextareaField,
18
18
  useUrlField,
19
19
  userIdField
20
- } from "../chunk-BFKHCXTE.js";
20
+ } from "../chunk-E7K3RKDO.js";
21
21
 
22
22
  // src/collection/helpers.ts
23
23
  var polymorphicCaslPermissions = {
@@ -1,6 +1,6 @@
1
1
  import { Knex } from 'knex';
2
2
  import { Request, Router, RequestHandler, Response } from 'express';
3
- import { L as LocalizedString, b as FieldDefinition, E as EntityIndex, F as FieldCondition } from './field-D6eIbvjc.js';
3
+ import { L as LocalizedString, b as FieldDefinition, E as EntityIndex, F as FieldCondition } from './field-KvvQ9oHe.js';
4
4
  import { Logger } from 'pino';
5
5
 
6
6
  /**
@@ -303,12 +303,33 @@ type FilterValue = string | number | boolean | null | unknown[] | FilterOperator
303
303
  interface EntityQuery {
304
304
  page?: number;
305
305
  limit?: number;
306
+ /** Override default max limit (default: 100). Useful for trees, exports, or entities needing larger pages */
307
+ maxLimit?: number;
306
308
  sort?: string;
307
309
  order?: 'asc' | 'desc';
308
310
  search?: string;
309
- /** Filters with optional operators */
311
+ /**
312
+ * Filters with optional operators.
313
+ * All field filters are combined with AND logic.
314
+ * Use `$or` key for OR logic between field groups:
315
+ * `{ tenant: 'acme', $or: [{ status: 'active' }, { role: 'admin' }] }`
316
+ * → tenant = 'acme' AND (status = 'active' OR role = 'admin')
317
+ */
310
318
  filters?: Record<string, unknown>;
311
319
  }
320
+ /**
321
+ * Type-safe query with filters restricted to known entity fields.
322
+ * Provides autocompletion for filter keys and FilterValue type checking.
323
+ *
324
+ * @example
325
+ * interface User { id: string; name: string; age: number; active: boolean }
326
+ * const query: TypedEntityQuery<User> = {
327
+ * filters: { name: { $contains: 'john' }, age: { $gte: 18 } }
328
+ * }
329
+ */
330
+ type TypedEntityQuery<T> = Omit<EntityQuery, 'filters'> & {
331
+ filters?: Partial<Record<keyof T & string, FilterValue>>;
332
+ };
312
333
  /**
313
334
  * Database adapter interface for normalized data access.
314
335
  *
@@ -906,6 +927,10 @@ interface PageDefinition {
906
927
  component?: string;
907
928
  /** Standalone pages render with full layout, not as tabs inside ModulePage */
908
929
  standalone?: boolean;
930
+ /** Route meta for the standalone page (auth, guest, permissions) */
931
+ meta?: Record<string, unknown>;
932
+ /** Layout for standalone pages: 'admin' (default, sidebar+header), 'public' (header+footer), 'centered' (minimal) */
933
+ layout?: 'admin' | 'public' | 'centered';
909
934
  }
910
935
  /**
911
936
  * Serializable page definition for API responses.
@@ -925,6 +950,8 @@ interface PageDefinitionDTO {
925
950
  widgets?: WidgetDefinition[];
926
951
  component?: string;
927
952
  standalone?: boolean;
953
+ meta?: Record<string, unknown>;
954
+ layout?: 'admin' | 'public' | 'centered';
928
955
  }
929
956
 
930
957
  /**
@@ -1069,7 +1096,7 @@ interface PluginSetupInfo {
1069
1096
  interface PluginManifest {
1070
1097
  /** Plugin npm package name */
1071
1098
  name: string;
1072
- /** Short code prefix for tables (3-4 uppercase chars) */
1099
+ /** Unique 3-char lowercase plugin identifier (e.g. 'tag', 'lnk', 'ait') */
1073
1100
  code: string;
1074
1101
  /** Display label (singular) */
1075
1102
  label: LocalizedString;
@@ -1077,6 +1104,8 @@ interface PluginManifest {
1077
1104
  labelPlural?: LocalizedString;
1078
1105
  /** Iconify MDI icon */
1079
1106
  icon?: string;
1107
+ /** Absolute path to plugin image file. Auto-detected from image.png if present. */
1108
+ image?: string;
1080
1109
  /** Category for sidebar grouping */
1081
1110
  category: Category;
1082
1111
  /** Plugin version following SemVer */
@@ -1087,7 +1116,7 @@ interface PluginManifest {
1087
1116
  modules: ModuleManifest[];
1088
1117
  /** Other plugin package names that must be loaded before this one */
1089
1118
  dependencies?: string[];
1090
- /** Other plugin package names that should be loaded before this one if present (soft dependency) */
1119
+ /** Other plugin package names that should be loaded before this one if present */
1091
1120
  optionalDependencies?: string[];
1092
1121
  /** Environment variables required or used by this plugin */
1093
1122
  envVars?: PluginEnvVar[];
@@ -1133,6 +1162,9 @@ interface RateLimitOptions {
1133
1162
  windowMs?: number;
1134
1163
  max?: number;
1135
1164
  message?: string;
1165
+ skipSuccessfulRequests?: boolean;
1166
+ skipFailedRequests?: boolean;
1167
+ keyGenerator?: (req: any) => string;
1136
1168
  }
1137
1169
  /**
1138
1170
  * Middleware factories available in module context.
@@ -1152,6 +1184,27 @@ interface EventEmitterLike {
1152
1184
  once: (event: string, listener: (...args: unknown[]) => void) => this;
1153
1185
  onAny?: (listener: (event: string, ...args: unknown[]) => void) => this;
1154
1186
  }
1187
+ /**
1188
+ * Semantic event API for cross-module communication.
1189
+ * Wraps the raw EventEmitter2 with explicit intent patterns.
1190
+ *
1191
+ * - notify: fire-and-forget, errors in listeners do not propagate
1192
+ * - query: request data from 0..N responders, returns flat array
1193
+ * - command: request action from 0..1 handler, returns first result
1194
+ */
1195
+ interface ContextEvents {
1196
+ /** Fire-and-forget. Errors in listeners are caught and logged, never thrown. */
1197
+ notify(event: string, payload?: unknown): void;
1198
+ /** Request data from 0..N listeners. Returns flat array of all responses. */
1199
+ query<T = unknown>(event: string, payload?: unknown): Promise<T[]>;
1200
+ /** Request action from 0..1 handler. Returns first defined response or undefined. */
1201
+ command<T = unknown>(event: string, payload?: unknown): Promise<T | undefined>;
1202
+ on(event: string, listener: (...args: unknown[]) => unknown): void;
1203
+ off(event: string, listener: (...args: unknown[]) => unknown): void;
1204
+ once(event: string, listener: (...args: unknown[]) => unknown): void;
1205
+ /** Subscribe to all events. Useful for cross-cutting concerns like webhooks and audit. */
1206
+ onAny(listener: (event: string, ...args: unknown[]) => void): void;
1207
+ }
1155
1208
  /**
1156
1209
  * Cryptographic utilities for password handling and symmetric encryption.
1157
1210
  */
@@ -1315,6 +1368,8 @@ interface PluginOpsContext {
1315
1368
  */
1316
1369
  interface DbContext {
1317
1370
  knex: Knex;
1371
+ /** Resolve table name with plugin prefix. Identity for core modules. */
1372
+ t: (name: string) => string;
1318
1373
  adapter: DatabaseAdapter;
1319
1374
  schema: SchemaAdapter;
1320
1375
  addTimestamps: (table: Knex.CreateTableBuilder, db: Knex) => void;
@@ -1376,6 +1431,8 @@ interface EngineContext {
1376
1431
  getSubjectForTable: (table: string) => string | undefined;
1377
1432
  hasModule: (name: string) => boolean;
1378
1433
  hasPlugin: (name: string) => boolean;
1434
+ getPluginByCode: (code: string) => PluginManifest | undefined;
1435
+ hasPluginByCode: (code: string) => boolean;
1379
1436
  }
1380
1437
  /**
1381
1438
  * Services registry namespace.
@@ -1413,6 +1470,8 @@ interface ModuleContext {
1413
1470
  engine: EngineContext;
1414
1471
  services: ServicesContext;
1415
1472
  adapters: AdaptersContext;
1473
+ /** Semantic event API for cross-module communication (notify/query/command). */
1474
+ events: ContextEvents;
1416
1475
  createRouter: () => Router;
1417
1476
  }
1418
1477
  /**
@@ -1703,14 +1762,10 @@ interface CollectionEntityDefinition extends BaseEntityDefinition {
1703
1762
  * Singleton entity - stores a single record in the shared single_records table.
1704
1763
  * When scopeField is set, operates in scoped mode (multiple records keyed by scope).
1705
1764
  */
1706
- interface SingleEntityDefinition {
1765
+ interface SingleEntityDefinition extends Pick<BaseEntityDefinition, 'label' | 'labelPlural' | 'icon' | 'fields' | 'casl' | 'public' | 'routePrefix' | 'order' | 'hidden' | 'hooks' | 'realtime'> {
1707
1766
  type: 'single' | 'config';
1708
1767
  /** Unique key in single_records table */
1709
1768
  key: string;
1710
- label: LocalizedString;
1711
- labelPlural?: LocalizedString;
1712
- icon?: string;
1713
- fields: Record<string, FieldDefinition>;
1714
1769
  /** Default values applied when the setting is first accessed */
1715
1770
  defaults?: Record<string, unknown>;
1716
1771
  /** Scope field name for multi-record mode (absorbed from ConfigEntityDefinition) */
@@ -1719,16 +1774,8 @@ interface SingleEntityDefinition {
1719
1774
  timestamps?: boolean;
1720
1775
  /** Enable audit fields (created_by, updated_by) */
1721
1776
  audit?: boolean;
1722
- casl?: EntityCaslConfig;
1723
- /** If true, all endpoints are publicly accessible without authentication (default-deny) */
1724
- public?: boolean;
1725
- routePrefix?: string;
1726
- actions?: EntityAction[];
1727
- /** Lifecycle hooks factory. Called with ModuleContext at service creation time. */
1728
- hooks?: (ctx: ModuleContext) => EntityServiceHooks;
1729
- order?: number;
1730
- /** Real-time mode: 'live' (push), 'sync' (bidirectional), or false (default) */
1731
- realtime?: RealtimeMode;
1777
+ /** Custom actions */
1778
+ actions?: ActionDefinition[];
1732
1779
  }
1733
1780
  /**
1734
1781
  * Seed data configuration for reference/tree/dag entities.
@@ -1862,6 +1909,8 @@ interface ComputedEntityDefinition {
1862
1909
  realtime?: RealtimeMode;
1863
1910
  /** Auto-refresh interval in ms. Frontend polls data at this rate when the entity tab is active. */
1864
1911
  refreshInterval?: number;
1912
+ /** Pre-compute cache on startup. Useful for expensive computed entities. */
1913
+ warmCache?: boolean;
1865
1914
  }
1866
1915
  /**
1867
1916
  * View entity - read-only database view or projection.
@@ -1902,4 +1951,4 @@ type TempEntityDefinition = Omit<CollectionEntityDefinition, 'type'> & {
1902
1951
  */
1903
1952
  type EntityDefinition = CollectionEntityDefinition | SingleEntityDefinition | ExternalEntityDefinition | VirtualEntityDefinition | ComputedEntityDefinition | ViewEntityDefinition | ReferenceEntityDefinition | TreeEntityDefinition | DagEntityDefinition | EventEntityDefinition;
1904
1953
 
1905
- export { type ExternalEntityDefinition as $, type AbilityLike as A, type BatchProgressEvent as B, type ConfirmConfig as C, type DisplayMode as D, type EntityType as E, type ForbiddenErrorInstance as F, type SchemaColumnInfo as G, type SchemaColumnBuilder as H, type SchemaTableBuilder as I, type SchemaForeignKeyBuilder as J, type SchemaAlterTableBuilder as K, type SchemaAdapter as L, type ModuleAbilities as M, type ModuleRequirements as N, type ActionDefinition as O, type PostActionPipeline as P, type PostAction as Q, type RealtimeMode as R, type SingleEntityDefinition as S, type TreeEntityDefinition as T, type ConfirmationType as U, type ViewEntityDefinition as V, type EntityAction as W, type SeedConfig as X, type ReferenceEntityDefinition as Y, type RetentionPolicy as Z, type TempRetentionPolicy as _, type Category as a, type PluginConfigField as a$, type VirtualEntityDefinition as a0, type ConfigEntityDefinition as a1, type TempEntityDefinition as a2, type SharedEntityProperties as a3, type BaseEntityService as a4, type CollectionEntityService as a5, type TempEntityService as a6, type EventEntityService as a7, type SingleEntityService as a8, type ConfigEntityService as a9, type ContextSocket as aA, type ContextEventsHub as aB, type ContextHelpers as aC, type EntityHandler as aD, type EntityController as aE, type CoreContext as aF, type DbContext as aG, type RuntimeContext as aH, type ConfigContext as aI, type EngineContext as aJ, type ServicesContext as aK, type AdaptersContext as aL, type ModuleContext as aM, type HttpMethod as aN, type RouteParameterDefinition as aO, type RouteResponseDefinition as aP, type CustomRouteDefinition as aQ, type CacheOptions as aR, type CacheStats as aS, type ManagedCache as aT, type ScopedCacheManager as aU, type CacheManagerContract as aV, type CategoryMeta as aW, type ActionInjection as aX, type ModuleManifest as aY, type AppManifest as aZ, type PluginEnvVar as a_, type ReferenceEntityService as aa, type ViewEntityService as ab, type ComputedEntityService as ac, type ExternalEntityService as ad, type VirtualEntityService as ae, type TreeNode as af, type TreeEntityService as ag, type DagEntityService as ah, type ActionEntityService as ai, type EntityServiceHooks as aj, type CreateEntityServiceOptions as ak, type BaseRolesService as al, type BaseUsersService as am, type SendMailOptions as an, type SendMailResult as ao, type BaseMailService as ap, type LoggerReporter as aq, type CoreServices as ar, type ValidationSchema as as, type ValidateSchemas as at, type RateLimitOptions as au, type ModuleMiddlewares as av, type EventEmitterLike as aw, type ContextCrypto as ax, type SocketIOServer as ay, type SocketIOBroadcastOperator as az, type PageDefinitionDTO as b, type PluginConfigSchema as b0, type PluginSetupInfo as b1, type PluginManifest as b2, type RegisterPluginOptions as b3, CATEGORIES as b4, CATEGORY_ORDER as b5, type PageType as b6, type WidgetLayout as b7, type WidgetDefinition as b8, type PageDefinition as b9, DEFAULT_TENANT_ID as ba, entityRoom as bb, type EntityChangePayload as bc, type EntityRealtimeEvents as bd, type EntityRealtimeEmits as be, type BridgeTarget as bf, type BridgeRule as bg, type EntityDefinition as c, type CollectionEntityDefinition as d, type EventEntityDefinition as e, type DagEntityDefinition as f, type ComputedEntityDefinition as g, type SSEHelper as h, type SSESender as i, type SSEOptions as j, type BatchLogEntry as k, type BaseAuthRequest as l, type BaseUser as m, type PaginationParams as n, type PaginationParamsWithOffset as o, type PaginatedResult as p, type ValidationDetail as q, type CaslAction as r, type RolePermission as s, type EntityCaslConfig as t, type ForbiddenErrorConstructor as u, type AuthRequest as v, type FilterOperators as w, type FilterValue as x, type EntityQuery as y, type DatabaseAdapter as z };
1954
+ export { type RetentionPolicy as $, type ActionDefinition as A, type BatchProgressEvent as B, type ConfirmConfig as C, type DisplayMode as D, type EntityType as E, type ForbiddenErrorInstance as F, type EntityQuery as G, type TypedEntityQuery as H, type DatabaseAdapter as I, type SchemaColumnInfo as J, type SchemaColumnBuilder as K, type SchemaTableBuilder as L, type ModuleContext as M, type SchemaForeignKeyBuilder as N, type SchemaAlterTableBuilder as O, type PostActionPipeline as P, type SchemaAdapter as Q, type RealtimeMode as R, type SingleEntityDefinition as S, type TreeEntityDefinition as T, type ModuleRequirements as U, type ViewEntityDefinition as V, type PostAction as W, type ConfirmationType as X, type EntityAction as Y, type SeedConfig as Z, type ReferenceEntityDefinition as _, type Category as a, type AppManifest as a$, type TempRetentionPolicy as a0, type ExternalEntityDefinition as a1, type VirtualEntityDefinition as a2, type ConfigEntityDefinition as a3, type TempEntityDefinition as a4, type SharedEntityProperties as a5, type BaseEntityService as a6, type CollectionEntityService as a7, type TempEntityService as a8, type EventEntityService as a9, type ContextCrypto as aA, type SocketIOServer as aB, type SocketIOBroadcastOperator as aC, type ContextSocket as aD, type ContextEventsHub as aE, type ContextHelpers as aF, type EntityHandler as aG, type EntityController as aH, type CoreContext as aI, type DbContext as aJ, type RuntimeContext as aK, type ConfigContext as aL, type EngineContext as aM, type ServicesContext as aN, type AdaptersContext as aO, type HttpMethod as aP, type RouteParameterDefinition as aQ, type RouteResponseDefinition as aR, type CustomRouteDefinition as aS, type CacheOptions as aT, type CacheStats as aU, type ManagedCache as aV, type ScopedCacheManager as aW, type CacheManagerContract as aX, type CategoryMeta as aY, type ActionInjection as aZ, type ModuleManifest as a_, type SingleEntityService as aa, type ConfigEntityService as ab, type ReferenceEntityService as ac, type ViewEntityService as ad, type ComputedEntityService as ae, type ExternalEntityService as af, type VirtualEntityService as ag, type TreeNode as ah, type TreeEntityService as ai, type DagEntityService as aj, type ActionEntityService as ak, type EntityServiceHooks as al, type CreateEntityServiceOptions as am, type BaseRolesService as an, type BaseUsersService as ao, type SendMailOptions as ap, type SendMailResult as aq, type BaseMailService as ar, type LoggerReporter as as, type CoreServices as at, type ValidationSchema as au, type ValidateSchemas as av, type RateLimitOptions as aw, type ModuleMiddlewares as ax, type EventEmitterLike as ay, type ContextEvents as az, type PageDefinitionDTO as b, type PluginEnvVar as b0, type PluginConfigField as b1, type PluginConfigSchema as b2, type PluginSetupInfo as b3, type PluginManifest as b4, type RegisterPluginOptions as b5, CATEGORIES as b6, CATEGORY_ORDER as b7, type PageType as b8, type WidgetLayout as b9, type WidgetDefinition as ba, type PageDefinition as bb, DEFAULT_TENANT_ID as bc, entityRoom as bd, type EntityChangePayload as be, type EntityRealtimeEvents as bf, type EntityRealtimeEmits as bg, type BridgeTarget as bh, type BridgeRule as bi, type EntityDefinition as c, type CollectionEntityDefinition as d, type EventEntityDefinition as e, type DagEntityDefinition as f, type ComputedEntityDefinition as g, type SSEHelper as h, type SSESender as i, type SSEOptions as j, type BatchLogEntry as k, type BaseAuthRequest as l, type BaseUser as m, type PaginationParams as n, type PaginationParamsWithOffset as o, type PaginatedResult as p, type ValidationDetail as q, type CaslAction as r, type RolePermission as s, type EntityCaslConfig as t, type AbilityLike as u, type ForbiddenErrorConstructor as v, type ModuleAbilities as w, type AuthRequest as x, type FilterOperators as y, type FilterValue as z };
@@ -9,10 +9,12 @@
9
9
  * // Simple string (backward compatible)
10
10
  * label: 'Users'
11
11
  *
12
- * // Multi-language object
12
+ * // Multi-language object (en is required as fallback)
13
13
  * label: { en: 'Users', es: 'Usuarios' }
14
14
  */
15
- type LocalizedString = string | Record<string, string>;
15
+ type LocalizedString = string | ({
16
+ en: string;
17
+ } & Record<string, string>);
16
18
  /**
17
19
  * Auth provider information for dynamic login buttons.
18
20
  * Plugins register this info so the UI can render buttons without knowing provider details.
@@ -278,6 +280,16 @@ interface FieldMeta {
278
280
  showInDisplay?: boolean;
279
281
  /** Show in forms. Use 'create'/'edit' for conditional display. Default: true */
280
282
  showInForm?: boolean | 'create' | 'edit';
283
+ /**
284
+ * Action key to call when a switch/checkbox is toggled instead of doing a direct field update.
285
+ * The action must be a row-scope action with no `input` fields.
286
+ * String: same action regardless of new value.
287
+ * Object: different action per new value (true/false).
288
+ */
289
+ toggleAction?: string | {
290
+ true?: string;
291
+ false?: string;
292
+ };
281
293
  }
282
294
  /**
283
295
  * Serializable field condition for dynamic visibility/required/disabled.
@@ -1,4 +1,4 @@
1
- import { b as FieldDefinition } from '../field-D6eIbvjc.js';
1
+ import { b as FieldDefinition } from '../field-KvvQ9oHe.js';
2
2
  import { MasterType } from '../masters/index.js';
3
3
 
4
4
  /**
@@ -699,6 +699,8 @@ interface MasterSelectConfig {
699
699
  };
700
700
  /** Master route slug (e.g. 'timezones', 'currencies', 'social-networks') */
701
701
  master: MasterType;
702
+ /** Default value */
703
+ defaultValue?: string;
702
704
  /** Help text shown below the input */
703
705
  hint?: string | {
704
706
  en: string;
@@ -833,6 +835,58 @@ interface TextareaFieldConfig {
833
835
  */
834
836
  declare function useTextareaField(config: TextareaFieldConfig & FieldOverrides): FieldDefinition;
835
837
 
838
+ /**
839
+ * Code Field Factory
840
+ *
841
+ * Creates code editor fields (YAML, JSON, JavaScript, etc.) with common configuration.
842
+ */
843
+
844
+ /**
845
+ * Configuration for code editor fields.
846
+ */
847
+ interface CodeFieldConfig {
848
+ /** Field label (localized) */
849
+ label: string | {
850
+ en: string;
851
+ es?: string;
852
+ };
853
+ /** Help text shown below the input */
854
+ hint?: string | {
855
+ en: string;
856
+ es?: string;
857
+ };
858
+ /** Is field required? (default: false) */
859
+ required?: boolean;
860
+ /** DB nullable (default: true) */
861
+ nullable?: boolean;
862
+ /** Default value */
863
+ defaultValue?: string;
864
+ /** Code language for syntax highlighting (e.g. 'yaml', 'json', 'javascript') */
865
+ language?: string;
866
+ /** Placeholder text */
867
+ placeholder?: string;
868
+ /** Metadata overrides */
869
+ meta?: FieldDefinition['meta'];
870
+ }
871
+ /**
872
+ * Create a code editor field with syntax highlighting.
873
+ *
874
+ * @example
875
+ * ```typescript
876
+ * compose_yaml: useCodeField({
877
+ * label: { en: 'Compose YAML', es: 'YAML de Compose' },
878
+ * required: true,
879
+ * language: 'yaml'
880
+ * })
881
+ *
882
+ * config_json: useCodeField({
883
+ * label: { en: 'Configuration', es: 'Configuración' },
884
+ * language: 'json'
885
+ * })
886
+ * ```
887
+ */
888
+ declare function useCodeField(config: CodeFieldConfig & FieldOverrides): FieldDefinition;
889
+
836
890
  /**
837
891
  * JSON Field Factory
838
892
  *
@@ -1325,9 +1379,215 @@ interface TagsFieldConfig {
1325
1379
  declare function useTagsField(config: TagsFieldConfig & FieldOverrides): FieldDefinition;
1326
1380
 
1327
1381
  /**
1328
- * Common Field Definitions
1382
+ * Name Field Factory
1383
+ *
1384
+ * Creates standard name text fields with sortable/searchable defaults.
1385
+ */
1386
+
1387
+ interface NameFieldConfig extends FieldOverrides {
1388
+ /** Max string size (default: 100) */
1389
+ size?: number;
1390
+ /** Unique constraint — also enables index (default: false) */
1391
+ unique?: boolean;
1392
+ /** Placeholder text */
1393
+ placeholder?: string | {
1394
+ en: string;
1395
+ es?: string;
1396
+ };
1397
+ /** Help text shown below the input */
1398
+ hint?: string | {
1399
+ en: string;
1400
+ es?: string;
1401
+ };
1402
+ /** Custom validation rules (merged with auto-generated min/max) */
1403
+ validation?: FieldDefinition['validation'];
1404
+ /** Disabled field (default: false) */
1405
+ disabled?: boolean;
1406
+ /** Metadata overrides (merged with sortable+searchable defaults) */
1407
+ meta?: FieldDefinition['meta'];
1408
+ }
1409
+ /**
1410
+ * Create a name field with standard defaults.
1411
+ *
1412
+ * Defaults: label Name/Nombre, required, nullable:false, size:100,
1413
+ * meta: sortable+searchable, validation: min:1 max:size.
1414
+ *
1415
+ * @example
1416
+ * ```typescript
1417
+ * // Default name field
1418
+ * name: useNameField()
1419
+ *
1420
+ * // Large unique name
1421
+ * name: useNameField({ size: 255, unique: true })
1422
+ *
1423
+ * // Role name with pattern
1424
+ * name: useNameField({ size: 50, unique: true, disabled: true, validation: { pattern: '^[A-Z_]+$' } })
1425
+ * ```
1426
+ */
1427
+ declare function useNameField(config?: NameFieldConfig): FieldDefinition;
1428
+
1429
+ /**
1430
+ * Description Field Factory
1431
+ *
1432
+ * Creates description fields in textarea, text, or localized (json) mode.
1433
+ */
1434
+
1435
+ interface DescriptionFieldConfig extends FieldOverrides {
1436
+ /** Input mode (default: 'textarea') */
1437
+ mode?: 'textarea' | 'text';
1438
+ /** Store as JSON for localized content (default: false). Forces input to 'text' */
1439
+ localized?: boolean;
1440
+ /** Enable searchable meta (default: false) */
1441
+ searchable?: boolean;
1442
+ /** DB nullable (default: true) */
1443
+ nullable?: boolean;
1444
+ /** String size for text mode (default: 255). Ignored in textarea/localized mode */
1445
+ size?: number;
1446
+ /** Metadata overrides */
1447
+ meta?: FieldDefinition['meta'];
1448
+ }
1449
+ /**
1450
+ * Create a description field with standard defaults.
1451
+ *
1452
+ * @example
1453
+ * ```typescript
1454
+ * // Default textarea
1455
+ * description: useDescriptionField()
1456
+ *
1457
+ * // Searchable textarea
1458
+ * description: useDescriptionField({ searchable: true })
1459
+ *
1460
+ * // Localized (stored as JSON)
1461
+ * description: useDescriptionField({ localized: true })
1462
+ *
1463
+ * // Single-line text with custom size
1464
+ * description: useDescriptionField({ mode: 'text', size: 500 })
1465
+ * ```
1466
+ */
1467
+ declare function useDescriptionField(config?: DescriptionFieldConfig): FieldDefinition;
1468
+
1469
+ /**
1470
+ * Metadata Field Factory
1471
+ *
1472
+ * Creates hidden JSON metadata fields for extensibility.
1473
+ */
1474
+
1475
+ interface MetadataFieldConfig extends FieldOverrides {
1476
+ /** Help text shown below the input */
1477
+ hint?: string | {
1478
+ en: string;
1479
+ es?: string;
1480
+ };
1481
+ /** Metadata overrides (merged with exportable:false, showInDisplay:false) */
1482
+ meta?: FieldDefinition['meta'];
1483
+ }
1484
+ /**
1485
+ * Create a metadata JSON field with standard hidden defaults.
1486
+ *
1487
+ * @example
1488
+ * ```typescript
1489
+ * // Standard hidden metadata
1490
+ * metadata: useMetadataField()
1491
+ *
1492
+ * // With hint for forms
1493
+ * metadata: useMetadataField({ hint: 'Additional driver configuration' })
1494
+ * ```
1495
+ */
1496
+ declare function useMetadataField(config?: MetadataFieldConfig): FieldDefinition;
1497
+
1498
+ /**
1499
+ * Enabled Field Factory
1500
+ *
1501
+ * Creates boolean switch fields for enabling/disabling functionality.
1502
+ */
1503
+
1504
+ interface EnabledFieldConfig extends FieldOverrides {
1505
+ /** Enable searchable meta (default: false) */
1506
+ searchable?: boolean;
1507
+ /** Metadata overrides */
1508
+ meta?: FieldDefinition['meta'];
1509
+ }
1510
+ /**
1511
+ * Create an enabled/disabled switch field with default true.
1512
+ *
1513
+ * Semantics: operational toggle (on/off). For record state use isActiveField preset.
1514
+ *
1515
+ * @example
1516
+ * ```typescript
1517
+ * enabled: useEnabledField()
1518
+ * is_enabled: useEnabledField({ searchable: true })
1519
+ * ```
1520
+ */
1521
+ declare function useEnabledField(config?: EnabledFieldConfig): FieldDefinition;
1522
+
1523
+ /**
1524
+ * Public Field Factory
1525
+ *
1526
+ * Creates boolean switch fields for public/private visibility.
1527
+ */
1528
+
1529
+ interface PublicFieldConfig extends FieldOverrides {
1530
+ /** Help text explaining what "public" means for this entity (required) */
1531
+ hint: string | {
1532
+ en: string;
1533
+ es?: string;
1534
+ };
1535
+ /** Enable searchable meta (default: false) */
1536
+ searchable?: boolean;
1537
+ /** Metadata overrides */
1538
+ meta?: FieldDefinition['meta'];
1539
+ }
1540
+ /**
1541
+ * Create a public/private switch field with default false.
1542
+ *
1543
+ * hint is required because "public" means different things per entity.
1544
+ *
1545
+ * @example
1546
+ * ```typescript
1547
+ * is_public: usePublicField({
1548
+ * hint: { en: 'Allow unauthenticated access', es: 'Permitir acceso sin autenticación' }
1549
+ * })
1550
+ *
1551
+ * is_public: usePublicField({
1552
+ * hint: { en: 'Visible to all users', es: 'Visible para todos' },
1553
+ * searchable: true
1554
+ * })
1555
+ * ```
1556
+ */
1557
+ declare function usePublicField(config: PublicFieldConfig): FieldDefinition;
1558
+
1559
+ /**
1560
+ * Expires At Field Factory
1561
+ *
1562
+ * Creates datetime fields for expiration/TTL patterns.
1563
+ */
1564
+
1565
+ interface ExpiresAtFieldConfig extends FieldOverrides {
1566
+ /** Is field required? (default: false) */
1567
+ required?: boolean;
1568
+ /** DB nullable (default: true) */
1569
+ nullable?: boolean;
1570
+ /** Metadata overrides (merged with sortable default) */
1571
+ meta?: FieldDefinition['meta'];
1572
+ }
1573
+ /**
1574
+ * Create an expiration datetime field.
1575
+ *
1576
+ * @example
1577
+ * ```typescript
1578
+ * // Optional expiration (PATs, notifications)
1579
+ * expires_at: useExpiresAtField()
1580
+ *
1581
+ * // Required expiration (refresh tokens)
1582
+ * expires_at: useExpiresAtField({ required: true, nullable: false })
1583
+ * ```
1584
+ */
1585
+ declare function useExpiresAtField(config?: ExpiresAtFieldConfig): FieldDefinition;
1586
+
1587
+ /**
1588
+ * Field Presets
1329
1589
  *
1330
- * Pre-configured field definitions for common use cases.
1590
+ * Ready-to-use FieldDefinition constants for common use cases.
1331
1591
  * These fields have their `name` assigned from the key when used.
1332
1592
  */
1333
1593
 
@@ -1351,7 +1611,7 @@ declare const isActiveField: FieldDefinition;
1351
1611
  declare const orderField: FieldDefinition;
1352
1612
 
1353
1613
  /**
1354
- * Pre-configured field sets for common entity patterns.
1614
+ * Preset Sets — groups of related field presets for common entity patterns.
1355
1615
  * Use with spread operator or composeFields().
1356
1616
  *
1357
1617
  * @example
@@ -1367,4 +1627,4 @@ declare const auditFields: Record<string, FieldDefinition>;
1367
1627
  /** deleted_at for soft-delete pattern */
1368
1628
  declare const softDeleteFields: Record<string, FieldDefinition>;
1369
1629
 
1370
- export { type CheckboxFieldConfig, type ColorFieldConfig, type DatetimeFieldConfig, type EmailFieldConfig, type FieldOverrides, type FileFieldConfig, type FileSize, type IconFieldConfig, type IdFieldConfig, type IdType, type ImageFieldConfig, type JsonFieldConfig, type LocalizedFieldConfig, type MasterSelectConfig, type MultiFileFieldConfig, type MultiImageFieldConfig, type NumberFieldConfig, type PasswordFieldConfig, type PatternIdConfig, type RelationSelectConfig, type SelectOption, type StaticSelectConfig, type SwitchFieldConfig, type TagsFieldConfig, type TextFieldConfig, type TextUniqueFieldConfig, type TextareaFieldConfig, type UrlFieldConfig, auditFields, idField, isActiveField, orderField, parseFileSize, softDeleteFields, timestampFields, useCheckboxField, useColorField, useDatetimeField, useEmailField, useFileField, useIconField, useIdField, useImageField, useJsonField, useLocalizedField, useMultiFileField, useMultiImageField, useNumberField, usePasswordField, useSelectField, useSwitchField, useTagsField, useTextField, useTextUniqueField, useTextareaField, useUrlField, userIdField };
1630
+ export { type CheckboxFieldConfig, type CodeFieldConfig, type ColorFieldConfig, type DatetimeFieldConfig, type DescriptionFieldConfig, type EmailFieldConfig, type EnabledFieldConfig, type ExpiresAtFieldConfig, type FieldOverrides, type FileFieldConfig, type FileSize, type IconFieldConfig, type IdFieldConfig, type IdType, type ImageFieldConfig, type JsonFieldConfig, type LocalizedFieldConfig, type MasterSelectConfig, type MetadataFieldConfig, type MultiFileFieldConfig, type MultiImageFieldConfig, type NameFieldConfig, type NumberFieldConfig, type PasswordFieldConfig, type PatternIdConfig, type PublicFieldConfig, type RelationSelectConfig, type SelectOption, type StaticSelectConfig, type SwitchFieldConfig, type TagsFieldConfig, type TextFieldConfig, type TextUniqueFieldConfig, type TextareaFieldConfig, type UrlFieldConfig, auditFields, idField, isActiveField, orderField, parseFileSize, softDeleteFields, timestampFields, useCheckboxField, useCodeField, useColorField, useDatetimeField, useDescriptionField, useEmailField, useEnabledField, useExpiresAtField, useFileField, useIconField, useIdField, useImageField, useJsonField, useLocalizedField, useMetadataField, useMultiFileField, useMultiImageField, useNameField, useNumberField, usePasswordField, usePublicField, useSelectField, useSwitchField, useTagsField, useTextField, useTextUniqueField, useTextareaField, useUrlField, userIdField };
@@ -7,19 +7,26 @@ import {
7
7
  softDeleteFields,
8
8
  timestampFields,
9
9
  useCheckboxField,
10
+ useCodeField,
10
11
  useColorField,
11
12
  useDatetimeField,
13
+ useDescriptionField,
12
14
  useEmailField,
15
+ useEnabledField,
16
+ useExpiresAtField,
13
17
  useFileField,
14
18
  useIconField,
15
19
  useIdField,
16
20
  useImageField,
17
21
  useJsonField,
18
22
  useLocalizedField,
23
+ useMetadataField,
19
24
  useMultiFileField,
20
25
  useMultiImageField,
26
+ useNameField,
21
27
  useNumberField,
22
28
  usePasswordField,
29
+ usePublicField,
23
30
  useSelectField,
24
31
  useSwitchField,
25
32
  useTagsField,
@@ -28,7 +35,7 @@ import {
28
35
  useTextareaField,
29
36
  useUrlField,
30
37
  userIdField
31
- } from "../chunk-BFKHCXTE.js";
38
+ } from "../chunk-E7K3RKDO.js";
32
39
  export {
33
40
  auditFields,
34
41
  idField,
@@ -38,19 +45,26 @@ export {
38
45
  softDeleteFields,
39
46
  timestampFields,
40
47
  useCheckboxField,
48
+ useCodeField,
41
49
  useColorField,
42
50
  useDatetimeField,
51
+ useDescriptionField,
43
52
  useEmailField,
53
+ useEnabledField,
54
+ useExpiresAtField,
44
55
  useFileField,
45
56
  useIconField,
46
57
  useIdField,
47
58
  useImageField,
48
59
  useJsonField,
49
60
  useLocalizedField,
61
+ useMetadataField,
50
62
  useMultiFileField,
51
63
  useMultiImageField,
64
+ useNameField,
52
65
  useNumberField,
53
66
  usePasswordField,
67
+ usePublicField,
54
68
  useSelectField,
55
69
  useSwitchField,
56
70
  useTagsField,
package/dist/index.d.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  import { Knex } from 'knex';
2
2
  export { Knex } from 'knex';
3
+ import { Request, Response } from 'express';
3
4
  export { CookieOptions, NextFunction, Request, RequestHandler, Response, Router } from 'express';
4
- import { C as ConfirmConfig, P as PostActionPipeline, E as EntityType, D as DisplayMode, R as RealtimeMode, a as Category, b as PageDefinitionDTO, c as EntityDefinition, d as CollectionEntityDefinition, e as EventEntityDefinition, V as ViewEntityDefinition, T as TreeEntityDefinition, f as DagEntityDefinition, S as SingleEntityDefinition, g as ComputedEntityDefinition } from './entity-BnVQn6la.js';
5
- export { A as AbilityLike, O as ActionDefinition, ai as ActionEntityService, aX as ActionInjection, aL as AdaptersContext, aZ as AppManifest, v as AuthRequest, l as BaseAuthRequest, a4 as BaseEntityService, ap as BaseMailService, al as BaseRolesService, m as BaseUser, am as BaseUsersService, k as BatchLogEntry, B as BatchProgressEvent, bg as BridgeRule, bf as BridgeTarget, b4 as CATEGORIES, b5 as CATEGORY_ORDER, aV as CacheManagerContract, aR as CacheOptions, aS as CacheStats, r as CaslAction, aW as CategoryMeta, a5 as CollectionEntityService, ac as ComputedEntityService, aI as ConfigContext, a1 as ConfigEntityDefinition, a9 as ConfigEntityService, U as ConfirmationType, ax as ContextCrypto, aB as ContextEventsHub, aC as ContextHelpers, aA as ContextSocket, aF as CoreContext, ar as CoreServices, ak as CreateEntityServiceOptions, aQ as CustomRouteDefinition, ba as DEFAULT_TENANT_ID, ah as DagEntityService, z as DatabaseAdapter, aG as DbContext, aJ as EngineContext, W as EntityAction, t as EntityCaslConfig, bc as EntityChangePayload, aE as EntityController, aD as EntityHandler, y as EntityQuery, be as EntityRealtimeEmits, bd as EntityRealtimeEvents, aj as EntityServiceHooks, aw as EventEmitterLike, a7 as EventEntityService, $ as ExternalEntityDefinition, ad as ExternalEntityService, w as FilterOperators, x as FilterValue, u as ForbiddenErrorConstructor, F as ForbiddenErrorInstance, aN as HttpMethod, aq as LoggerReporter, aT as ManagedCache, M as ModuleAbilities, aM as ModuleContext, aY as ModuleManifest, av as ModuleMiddlewares, N as ModuleRequirements, b9 as PageDefinition, b6 as PageType, p as PaginatedResult, n as PaginationParams, o as PaginationParamsWithOffset, a$ as PluginConfigField, b0 as PluginConfigSchema, a_ as PluginEnvVar, b2 as PluginManifest, b1 as PluginSetupInfo, Q as PostAction, au as RateLimitOptions, Y as ReferenceEntityDefinition, aa as ReferenceEntityService, b3 as RegisterPluginOptions, Z as RetentionPolicy, s as RolePermission, aO as RouteParameterDefinition, aP as RouteResponseDefinition, aH as RuntimeContext, h as SSEHelper, j as SSEOptions, i as SSESender, L as SchemaAdapter, K as SchemaAlterTableBuilder, H as SchemaColumnBuilder, G as SchemaColumnInfo, J as SchemaForeignKeyBuilder, I as SchemaTableBuilder, aU as ScopedCacheManager, X as SeedConfig, an as SendMailOptions, ao as SendMailResult, aK as ServicesContext, a3 as SharedEntityProperties, a8 as SingleEntityService, az as SocketIOBroadcastOperator, ay as SocketIOServer, a2 as TempEntityDefinition, a6 as TempEntityService, _ as TempRetentionPolicy, ag as TreeEntityService, af as TreeNode, at as ValidateSchemas, q as ValidationDetail, as as ValidationSchema, ab as ViewEntityService, a0 as VirtualEntityDefinition, ae as VirtualEntityService, b8 as WidgetDefinition, b7 as WidgetLayout, bb as entityRoom } from './entity-BnVQn6la.js';
6
- import { L as LocalizedString, I as InputType, F as FieldCondition, a as FieldMeta, b as FieldDefinition } from './field-D6eIbvjc.js';
7
- export { A as AuthProviderInfo, c as AuthProviderService, C as ConditionalBoolean, D as DbType, E as EntityIndex, d as FieldDbConfig, h as FieldOptions, e as FieldRelation, i as FieldStorageConfig, f as FieldValidationConfig, g as getCountLabel, j as refOptions, r as resolveLocalized } from './field-D6eIbvjc.js';
5
+ import { C as ConfirmConfig, P as PostActionPipeline, E as EntityType, D as DisplayMode, R as RealtimeMode, a as Category, b as PageDefinitionDTO, c as EntityDefinition, d as CollectionEntityDefinition, e as EventEntityDefinition, V as ViewEntityDefinition, T as TreeEntityDefinition, f as DagEntityDefinition, S as SingleEntityDefinition, g as ComputedEntityDefinition, A as ActionDefinition, M as ModuleContext } from './entity-Bwf8yboo.js';
6
+ export { u as AbilityLike, ak as ActionEntityService, aZ as ActionInjection, aO as AdaptersContext, a$ as AppManifest, x as AuthRequest, l as BaseAuthRequest, a6 as BaseEntityService, ar as BaseMailService, an as BaseRolesService, m as BaseUser, ao as BaseUsersService, k as BatchLogEntry, B as BatchProgressEvent, bi as BridgeRule, bh as BridgeTarget, b6 as CATEGORIES, b7 as CATEGORY_ORDER, aX as CacheManagerContract, aT as CacheOptions, aU as CacheStats, r as CaslAction, aY as CategoryMeta, a7 as CollectionEntityService, ae as ComputedEntityService, aL as ConfigContext, a3 as ConfigEntityDefinition, ab as ConfigEntityService, X as ConfirmationType, aA as ContextCrypto, az as ContextEvents, aE as ContextEventsHub, aF as ContextHelpers, aD as ContextSocket, aI as CoreContext, at as CoreServices, am as CreateEntityServiceOptions, aS as CustomRouteDefinition, bc as DEFAULT_TENANT_ID, aj as DagEntityService, I as DatabaseAdapter, aJ as DbContext, aM as EngineContext, Y as EntityAction, t as EntityCaslConfig, be as EntityChangePayload, aH as EntityController, aG as EntityHandler, G as EntityQuery, bg as EntityRealtimeEmits, bf as EntityRealtimeEvents, al as EntityServiceHooks, ay as EventEmitterLike, a9 as EventEntityService, a1 as ExternalEntityDefinition, af as ExternalEntityService, y as FilterOperators, z as FilterValue, v as ForbiddenErrorConstructor, F as ForbiddenErrorInstance, aP as HttpMethod, as as LoggerReporter, aV as ManagedCache, w as ModuleAbilities, a_ as ModuleManifest, ax as ModuleMiddlewares, U as ModuleRequirements, bb as PageDefinition, b8 as PageType, p as PaginatedResult, n as PaginationParams, o as PaginationParamsWithOffset, b1 as PluginConfigField, b2 as PluginConfigSchema, b0 as PluginEnvVar, b4 as PluginManifest, b3 as PluginSetupInfo, W as PostAction, aw as RateLimitOptions, _ as ReferenceEntityDefinition, ac as ReferenceEntityService, b5 as RegisterPluginOptions, $ as RetentionPolicy, s as RolePermission, aQ as RouteParameterDefinition, aR as RouteResponseDefinition, aK as RuntimeContext, h as SSEHelper, j as SSEOptions, i as SSESender, Q as SchemaAdapter, O as SchemaAlterTableBuilder, K as SchemaColumnBuilder, J as SchemaColumnInfo, N as SchemaForeignKeyBuilder, L as SchemaTableBuilder, aW as ScopedCacheManager, Z as SeedConfig, ap as SendMailOptions, aq as SendMailResult, aN as ServicesContext, a5 as SharedEntityProperties, aa as SingleEntityService, aC as SocketIOBroadcastOperator, aB as SocketIOServer, a4 as TempEntityDefinition, a8 as TempEntityService, a0 as TempRetentionPolicy, ai as TreeEntityService, ah as TreeNode, H as TypedEntityQuery, av as ValidateSchemas, q as ValidationDetail, au as ValidationSchema, ad as ViewEntityService, a2 as VirtualEntityDefinition, ag as VirtualEntityService, ba as WidgetDefinition, b9 as WidgetLayout, bd as entityRoom } from './entity-Bwf8yboo.js';
7
+ import { L as LocalizedString, I as InputType, F as FieldCondition, a as FieldMeta, b as FieldDefinition } from './field-KvvQ9oHe.js';
8
+ export { A as AuthProviderInfo, c as AuthProviderService, C as ConditionalBoolean, D as DbType, E as EntityIndex, d as FieldDbConfig, h as FieldOptions, e as FieldRelation, i as FieldStorageConfig, f as FieldValidationConfig, g as getCountLabel, j as refOptions, r as resolveLocalized } from './field-KvvQ9oHe.js';
8
9
  import 'pino';
9
10
 
10
11
  /** Webhook configuration record */
@@ -249,6 +250,8 @@ interface PluginDTO {
249
250
  label: LocalizedString;
250
251
  labelPlural?: LocalizedString;
251
252
  icon?: string;
253
+ /** URL to plugin image (served by backend) */
254
+ image?: string;
252
255
  category?: Category;
253
256
  version: string;
254
257
  description: LocalizedString;
@@ -309,6 +312,68 @@ interface CombinedManifestDTO {
309
312
  /** Current tenant ID for this server instance */
310
313
  tenantId: string;
311
314
  }
315
+ /**
316
+ * Public capabilities response.
317
+ *
318
+ * Exposed without authentication so clients can discover
319
+ * which plugins are available before the user logs in.
320
+ *
321
+ * @remarks
322
+ * Returned by `GET /system/capabilities` (public, no auth required).
323
+ * The `plugins` array contains 3-char plugin codes (e.g. `'ntf'`, `'cpl'`).
324
+ * Extensible — future fields (locales, feature flags) can be added
325
+ * without breaking changes.
326
+ *
327
+ * @example
328
+ * ```json
329
+ * { "version": "0.14.0", "plugins": ["ntf", "cpl", "cht", "sch"] }
330
+ * ```
331
+ */
332
+ interface CapabilitiesDTO {
333
+ /** Backend package version (semver) */
334
+ version: string;
335
+ /** 3-char codes of registered plugins */
336
+ plugins: string[];
337
+ }
338
+
339
+ /** Status of a ticket as seen by the end user */
340
+ type TicketStatus = 'pending' | 'in_progress' | 'resolved' | 'rejected';
341
+ /** Data submitted by a user to create a new ticket */
342
+ interface TicketSubmission {
343
+ title: string;
344
+ description: string;
345
+ category?: string;
346
+ priority?: string;
347
+ submitter?: string;
348
+ }
349
+ /** Ticket as returned to the submitter (simplified view) */
350
+ interface TicketItem {
351
+ id: string;
352
+ title: string;
353
+ status: TicketStatus;
354
+ category: string;
355
+ created_at: string;
356
+ updated_at: string;
357
+ }
358
+ /** Result of a successful ticket submission */
359
+ interface TicketResult {
360
+ id: string;
361
+ status: TicketStatus;
362
+ }
363
+ /**
364
+ * Generic ticket provider interface.
365
+ * Plugins implement this to bridge Nexus with an external task tracker.
366
+ */
367
+ interface TicketProvider {
368
+ /** Submit a new ticket */
369
+ submit(data: TicketSubmission): Promise<TicketResult>;
370
+ /** List tickets for a specific submitter */
371
+ list(submitter: string): Promise<TicketItem[]>;
372
+ /** Verify the connection to the external service */
373
+ testConnection(): Promise<boolean>;
374
+ /** Whether the provider is currently available */
375
+ isAvailable(): boolean;
376
+ }
312
377
 
313
378
  /**
314
379
  * Type guards and utilities for EntityDefinitions
@@ -577,7 +642,7 @@ declare function assertAllowedDomain(email: string, allowedDomainsJson: string |
577
642
  * Official Nexus plugins maintained by the core team.
578
643
  * Used by the backend to populate the plugin store.
579
644
  */
580
- declare const OFFICIAL_PLUGINS: readonly ["@gzl10/nexus-plugin-ai", "@gzl10/nexus-plugin-baserow", "@gzl10/nexus-plugin-charts", "@gzl10/nexus-plugin-cms", "@gzl10/nexus-plugin-docker", "@gzl10/nexus-plugin-dropbox", "@gzl10/nexus-plugin-github-auth", "@gzl10/nexus-plugin-google-auth", "@gzl10/nexus-plugin-google-drive", "@gzl10/nexus-plugin-headscale", "@gzl10/nexus-plugin-links", "@gzl10/nexus-plugin-microsoft-auth", "@gzl10/nexus-plugin-n8n", "@gzl10/nexus-plugin-notion", "@gzl10/nexus-plugin-oidc-server", "@gzl10/nexus-plugin-opnsense", "@gzl10/nexus-plugin-pocketid", "@gzl10/nexus-plugin-prisma", "@gzl10/nexus-plugin-tags", "@gzl10/nexus-plugin-uptime"];
645
+ declare const OFFICIAL_PLUGINS: readonly ["@gzl10/nexus-plugin-ai", "@gzl10/nexus-plugin-auth-providers", "@gzl10/nexus-plugin-baserow", "@gzl10/nexus-plugin-charts", "@gzl10/nexus-plugin-cms", "@gzl10/nexus-plugin-compliance", "@gzl10/nexus-plugin-docker", "@gzl10/nexus-plugin-dropbox", "@gzl10/nexus-plugin-google-drive", "@gzl10/nexus-plugin-headscale", "@gzl10/nexus-plugin-importer", "@gzl10/nexus-plugin-links", "@gzl10/nexus-plugin-n8n", "@gzl10/nexus-plugin-notifications", "@gzl10/nexus-plugin-notion", "@gzl10/nexus-plugin-oidc-server", "@gzl10/nexus-plugin-opnsense", "@gzl10/nexus-plugin-plane", "@gzl10/nexus-plugin-prisma", "@gzl10/nexus-plugin-remote", "@gzl10/nexus-plugin-schedules", "@gzl10/nexus-plugin-scim", "@gzl10/nexus-plugin-tags", "@gzl10/nexus-plugin-uptime", "@gzl10/nexus-plugin-webhooks"];
581
646
  type OfficialPluginName = typeof OFFICIAL_PLUGINS[number];
582
647
 
583
648
  /**
@@ -605,6 +670,27 @@ declare function assertNever(value: never, message?: string): never;
605
670
  * )
606
671
  */
607
672
  declare function composeFields(...fieldSets: Record<string, FieldDefinition>[]): Record<string, FieldDefinition>;
673
+ /**
674
+ * Define an action with typed input and output.
675
+ * Provides type safety for the handler while returning a standard ActionDefinition
676
+ * that is assignable to ActionDefinition[] arrays.
677
+ *
678
+ * @example
679
+ * interface SendEmailInput { to: string; subject: string; body: string }
680
+ * interface SendEmailOutput { messageId: string }
681
+ *
682
+ * const sendEmail = defineAction<SendEmailInput, SendEmailOutput>({
683
+ * key: 'send-email',
684
+ * label: 'Send Email',
685
+ * handler: async (ctx, input) => {
686
+ * // input is typed as SendEmailInput
687
+ * return { messageId: '123' }
688
+ * }
689
+ * })
690
+ */
691
+ declare function defineAction<TInput = unknown, TOutput = unknown>(action: Omit<ActionDefinition, 'handler'> & {
692
+ handler?: (ctx: ModuleContext, input: TInput, req?: Request, res?: Response) => Promise<TOutput>;
693
+ }): ActionDefinition;
608
694
 
609
695
  interface ValidationError {
610
696
  field: string;
@@ -638,4 +724,4 @@ type KnexCreateTableBuilder = Knex.CreateTableBuilder;
638
724
  type KnexAlterTableBuilder = Knex.AlterTableBuilder;
639
725
  type KnexTransaction = Knex.Transaction;
640
726
 
641
- export { type ActionDefinitionDTO, type AuthorizationParams, Category, CollectionEntityDefinition, type CombinedManifestDTO, ComputedEntityDefinition, ConfirmConfig, type CreateWebhookInput, type CreateWebhookResponse, DagEntityDefinition, DisplayMode, type DomainFilterOptions, type DomainFilterResult, EntityDefinition, type EntityDefinitionDTO, EntityType, EventEntityDefinition, FieldCondition, FieldDefinition, type FieldDefinitionDTO, FieldMeta, type IdTokenClaims, InputType, type KnexAlterTableBuilder, type KnexCreateTableBuilder, type KnexTransaction, LocalizedString, type ManifestDTO, type ModuleDTO, type NonPersistentEntityDefinition, OFFICIAL_PLUGINS, type OfficialPluginName, type OidcClient, type OidcDiscoveryDocument, type OidcState, type OidcTokens, type OidcUserInfo, PageDefinitionDTO, type PersistentEntityDefinition, type PluginActionResult, type PluginDTO, type PluginSetupInfoDTO, type PluginStateDTO, PostActionPipeline, RealtimeMode, type SessionResult, SingleEntityDefinition, type StateManager, type TokenExchangeParams, type TokenValidationConfig, TreeEntityDefinition, type UpdateWebhookInput, type ValidationError, type ValidationResult, ViewEntityDefinition, type Webhook, type WebhookDelivery, assertAllowedDomain, assertNever, checkAllowedDomain, composeFields, createOidcClient, createStateManager, getEntityName, getEntitySubject, getOidcClient, hasTable, isPersistentEntity, isSingletonEntity, validateEntityDefinition };
727
+ export { ActionDefinition, type ActionDefinitionDTO, type AuthorizationParams, type CapabilitiesDTO, Category, CollectionEntityDefinition, type CombinedManifestDTO, ComputedEntityDefinition, ConfirmConfig, type CreateWebhookInput, type CreateWebhookResponse, DagEntityDefinition, DisplayMode, type DomainFilterOptions, type DomainFilterResult, EntityDefinition, type EntityDefinitionDTO, EntityType, EventEntityDefinition, FieldCondition, FieldDefinition, type FieldDefinitionDTO, FieldMeta, type IdTokenClaims, InputType, type KnexAlterTableBuilder, type KnexCreateTableBuilder, type KnexTransaction, LocalizedString, type ManifestDTO, ModuleContext, type ModuleDTO, type NonPersistentEntityDefinition, OFFICIAL_PLUGINS, type OfficialPluginName, type OidcClient, type OidcDiscoveryDocument, type OidcState, type OidcTokens, type OidcUserInfo, PageDefinitionDTO, type PersistentEntityDefinition, type PluginActionResult, type PluginDTO, type PluginSetupInfoDTO, type PluginStateDTO, PostActionPipeline, RealtimeMode, type SessionResult, SingleEntityDefinition, type StateManager, type TicketItem, type TicketProvider, type TicketResult, type TicketStatus, type TicketSubmission, type TokenExchangeParams, type TokenValidationConfig, TreeEntityDefinition, type UpdateWebhookInput, type ValidationError, type ValidationResult, ViewEntityDefinition, type Webhook, type WebhookDelivery, assertAllowedDomain, assertNever, checkAllowedDomain, composeFields, createOidcClient, createStateManager, defineAction, getEntityName, getEntitySubject, getOidcClient, hasTable, isPersistentEntity, isSingletonEntity, validateEntityDefinition };
package/dist/index.js CHANGED
@@ -229,25 +229,30 @@ function assertAllowedDomain(email, allowedDomainsJson, errorClass = Error) {
229
229
  // src/plugins/official-plugins.ts
230
230
  var OFFICIAL_PLUGINS = [
231
231
  "@gzl10/nexus-plugin-ai",
232
+ "@gzl10/nexus-plugin-auth-providers",
232
233
  "@gzl10/nexus-plugin-baserow",
233
234
  "@gzl10/nexus-plugin-charts",
234
235
  "@gzl10/nexus-plugin-cms",
236
+ "@gzl10/nexus-plugin-compliance",
235
237
  "@gzl10/nexus-plugin-docker",
236
238
  "@gzl10/nexus-plugin-dropbox",
237
- "@gzl10/nexus-plugin-github-auth",
238
- "@gzl10/nexus-plugin-google-auth",
239
239
  "@gzl10/nexus-plugin-google-drive",
240
240
  "@gzl10/nexus-plugin-headscale",
241
+ "@gzl10/nexus-plugin-importer",
241
242
  "@gzl10/nexus-plugin-links",
242
- "@gzl10/nexus-plugin-microsoft-auth",
243
243
  "@gzl10/nexus-plugin-n8n",
244
+ "@gzl10/nexus-plugin-notifications",
244
245
  "@gzl10/nexus-plugin-notion",
245
246
  "@gzl10/nexus-plugin-oidc-server",
246
247
  "@gzl10/nexus-plugin-opnsense",
247
- "@gzl10/nexus-plugin-pocketid",
248
+ "@gzl10/nexus-plugin-plane",
248
249
  "@gzl10/nexus-plugin-prisma",
250
+ "@gzl10/nexus-plugin-remote",
251
+ "@gzl10/nexus-plugin-schedules",
252
+ "@gzl10/nexus-plugin-scim",
249
253
  "@gzl10/nexus-plugin-tags",
250
- "@gzl10/nexus-plugin-uptime"
254
+ "@gzl10/nexus-plugin-uptime",
255
+ "@gzl10/nexus-plugin-webhooks"
251
256
  ];
252
257
 
253
258
  // src/utils.ts
@@ -258,6 +263,9 @@ function assertNever(value, message) {
258
263
  function composeFields(...fieldSets) {
259
264
  return Object.assign({}, ...fieldSets);
260
265
  }
266
+ function defineAction(action) {
267
+ return action;
268
+ }
261
269
 
262
270
  // src/validation.ts
263
271
  var NO_TABLE_TYPES = /* @__PURE__ */ new Set(["computed"]);
@@ -309,6 +317,7 @@ export {
309
317
  composeFields,
310
318
  createOidcClient,
311
319
  createStateManager,
320
+ defineAction,
312
321
  entityRoom,
313
322
  getCountLabel,
314
323
  getEntityName,
@@ -9,9 +9,5 @@
9
9
  type MasterType = string;
10
10
  /** Predefined master type slugs included with Nexus */
11
11
  declare const PREDEFINED_MASTER_TYPES: readonly ["currencies", "languages", "timezones", "social-networks", "genders", "marital-statuses", "education-levels", "industries", "company-types", "units", "product-categories", "phone-prefixes", "document-types"];
12
- /** @deprecated Use MasterType instead */
13
- type MasterSlug = string;
14
- /** @deprecated Use PREDEFINED_MASTER_TYPES instead */
15
- declare const MASTER_SLUGS: readonly ["currencies", "languages", "timezones", "social-networks", "genders", "marital-statuses", "education-levels", "industries", "company-types", "units", "product-categories", "phone-prefixes", "document-types"];
16
12
 
17
- export { MASTER_SLUGS, type MasterSlug, type MasterType, PREDEFINED_MASTER_TYPES };
13
+ export { type MasterType, PREDEFINED_MASTER_TYPES };
@@ -14,8 +14,6 @@ var PREDEFINED_MASTER_TYPES = [
14
14
  "phone-prefixes",
15
15
  "document-types"
16
16
  ];
17
- var MASTER_SLUGS = PREDEFINED_MASTER_TYPES;
18
17
  export {
19
- MASTER_SLUGS,
20
18
  PREDEFINED_MASTER_TYPES
21
19
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gzl10/nexus-sdk",
3
- "version": "0.14.0",
3
+ "version": "0.15.0",
4
4
  "description": "SDK types for creating Nexus plugins and modules",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -37,7 +37,7 @@
37
37
  "module"
38
38
  ],
39
39
  "dependencies": {
40
- "jose": "^5.0.0",
40
+ "jose": "^6.0.0",
41
41
  "ofetch": "^1.4.0"
42
42
  },
43
43
  "author": "Gonzalo Díez <gonzalo@gzl10.com>",
@@ -59,8 +59,7 @@
59
59
  "@types/express": "^5.0.2",
60
60
  "express": "^5.0.1",
61
61
  "knex": "^3.1.0",
62
- "pino": "^9.6.0",
63
- "tsup": "^8.4.0"
62
+ "pino": "^9.6.0"
64
63
  },
65
64
  "peerDependencies": {
66
65
  "express": "^5.0.1",