@notty/types 0.6.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -69,7 +69,7 @@ interface ThemeConfig {
69
69
  * Allowed media types for media field
70
70
  */
71
71
  type MediaType = 'images' | 'videos' | 'audios' | 'files';
72
- type FieldType = 'string' | 'text' | 'richtext' | 'integer' | 'bigint' | 'decimal' | 'boolean' | 'date' | 'datetime' | 'json' | 'enum' | 'relation' | 'component' | 'media';
72
+ type FieldType = 'string' | 'text' | 'richtext' | 'integer' | 'bigint' | 'decimal' | 'boolean' | 'date' | 'datetime' | 'json' | 'enum' | 'relation' | 'component' | 'dynamicZone' | 'media';
73
73
  interface ACmsField {
74
74
  type: FieldType;
75
75
  required?: boolean;
@@ -87,6 +87,7 @@ interface ACmsField {
87
87
  onDelete?: 'CASCADE' | 'SET NULL' | 'RESTRICT';
88
88
  component?: string;
89
89
  repeatable?: boolean;
90
+ components?: string[];
90
91
  allowedTypes?: MediaType[];
91
92
  multiple?: boolean;
92
93
  index?: boolean | 'unique' | 'fulltext';
@@ -96,9 +97,44 @@ interface ACmsField {
96
97
  onDelete?: 'CASCADE' | 'SET NULL' | 'RESTRICT' | 'NO ACTION';
97
98
  onUpdate?: 'CASCADE' | 'SET NULL' | 'RESTRICT' | 'NO ACTION';
98
99
  };
100
+ pluginOptions?: {
101
+ i18n?: {
102
+ localized: boolean;
103
+ };
104
+ };
99
105
  }
106
+ /**
107
+ * Component Schema - переиспользуемая схема для встраиваемых компонентов
108
+ * Компоненты группируются по категориям и идентифицируются как 'category.name'
109
+ */
110
+ interface ComponentSchema {
111
+ /**
112
+ * Уникальное имя в формате 'category.name'
113
+ * Примеры: 'shared.seo-meta', 'blocks.hero-section', 'ui.button'
114
+ */
115
+ uid: string;
116
+ /**
117
+ * Категория компонента (первая часть uid)
118
+ * Используется для группировки в UI
119
+ */
120
+ category: string;
121
+ info: {
122
+ displayName: string;
123
+ description?: string;
124
+ icon?: string;
125
+ };
126
+ /**
127
+ * Атрибуты компонента - те же типы полей, что и для ACmsSchema
128
+ * Компоненты могут содержать nested components, но не dynamicZone
129
+ */
130
+ attributes: Record<string, ACmsField>;
131
+ }
132
+ /**
133
+ * Content type schema kinds
134
+ */
135
+ type SchemaKind = 'collectionType' | 'singleType';
100
136
  interface ACmsSchema {
101
- kind: 'collectionType' | 'singleType';
137
+ kind: SchemaKind;
102
138
  info: {
103
139
  singularName: string;
104
140
  pluralName: string;
@@ -109,6 +145,11 @@ interface ACmsSchema {
109
145
  draftAndPublish?: boolean;
110
146
  timestamps?: boolean;
111
147
  softDelete?: boolean;
148
+ i18n?: {
149
+ enabled: boolean;
150
+ locales?: string[];
151
+ defaultLocale?: string;
152
+ };
112
153
  };
113
154
  attributes: Record<string, ACmsField>;
114
155
  indexes?: Array<{
@@ -118,7 +159,71 @@ interface ACmsSchema {
118
159
  }>;
119
160
  }
120
161
  /**
121
- * Пример схемы в универсальном формате
162
+ * Базовый тип для данных компонента при создании (без id)
163
+ */
164
+ interface ComponentDataInput {
165
+ [key: string]: unknown;
166
+ }
167
+ /**
168
+ * Базовый тип для данных компонента в ответе (с id)
169
+ */
170
+ interface ComponentData {
171
+ /**
172
+ * Optional id (may be absent for JSON-embedded storage)
173
+ */
174
+ id?: number;
175
+ [key: string]: unknown;
176
+ }
177
+ /**
178
+ * Элемент dynamic zone при создании - содержит тип компонента
179
+ */
180
+ interface DynamicZoneItemInput {
181
+ __component: string;
182
+ [key: string]: unknown;
183
+ }
184
+ /**
185
+ * Элемент dynamic zone в ответе - содержит id и тип компонента
186
+ */
187
+ interface DynamicZoneItem {
188
+ /**
189
+ * Optional id (may be absent for JSON-embedded storage)
190
+ */
191
+ id?: number;
192
+ __component: string;
193
+ [key: string]: unknown;
194
+ }
195
+ /**
196
+ * Данные поля component при создании
197
+ * Single: объект ComponentDataInput
198
+ * Repeatable: массив ComponentDataInput[]
199
+ */
200
+ type ComponentFieldInput = ComponentDataInput | ComponentDataInput[];
201
+ /**
202
+ * Данные поля component в ответе
203
+ * Single: объект ComponentData или null
204
+ * Repeatable: массив ComponentData[]
205
+ */
206
+ type ComponentFieldData = ComponentData | ComponentData[] | null;
207
+ /**
208
+ * Данные поля dynamicZone при создании
209
+ * Всегда массив элементов с __component
210
+ */
211
+ type DynamicZoneInput = DynamicZoneItemInput[];
212
+ /**
213
+ * Данные поля dynamicZone в ответе
214
+ * Всегда массив элементов с id и __component
215
+ */
216
+ type DynamicZoneData = DynamicZoneItem[];
217
+ /**
218
+ * Пример схемы компонента SEO Meta
219
+ */
220
+ declare const exampleComponentSchema: ComponentSchema;
221
+ /**
222
+ * Пример схемы блока для dynamic zone
223
+ */
224
+ declare const exampleBlockComponent: ComponentSchema;
225
+ /**
226
+ * Пример схемы в универсальном формате с компонентами и dynamic zone
122
227
  */
123
228
  declare const exampleSchema: ACmsSchema;
124
229
 
@@ -131,7 +236,7 @@ interface ValidationError {
131
236
  code: ValidationErrorCode;
132
237
  details?: unknown;
133
238
  }
134
- type ValidationErrorCode = 'MISSING_REQUIRED_FIELD' | 'INVALID_FIELD_TYPE' | 'INVALID_RELATION_TYPE' | 'DUPLICATE_FIELD_NAME' | 'INVALID_CONSTRAINT' | 'INVALID_ENUM_VALUES' | 'INVALID_RELATION_TARGET' | 'INVALID_RELATION_INVERSE' | 'MISSING_INFO' | 'EMPTY_ATTRIBUTES' | 'INVALID_MIN_MAX' | 'INVALID_LENGTH_CONSTRAINT' | 'INVALID_INDEX_TYPE' | 'INVALID_FOREIGN_KEY' | 'INVALID_INDEX_FIELDS';
239
+ type ValidationErrorCode = 'MISSING_REQUIRED_FIELD' | 'INVALID_FIELD_TYPE' | 'INVALID_RELATION_TYPE' | 'DUPLICATE_FIELD_NAME' | 'INVALID_CONSTRAINT' | 'INVALID_ENUM_VALUES' | 'INVALID_RELATION_TARGET' | 'INVALID_RELATION_INVERSE' | 'MISSING_INFO' | 'EMPTY_ATTRIBUTES' | 'INVALID_MIN_MAX' | 'INVALID_LENGTH_CONSTRAINT' | 'INVALID_INDEX_TYPE' | 'INVALID_FOREIGN_KEY' | 'INVALID_INDEX_FIELDS' | 'INVALID_LOCALE_CODE' | 'INVALID_DEFAULT_LOCALE' | 'INVALID_COMPONENT_NAME' | 'INVALID_COMPONENT_UID' | 'COMPONENT_NOT_FOUND' | 'COMPONENT_CIRCULAR_REFERENCE' | 'COMPONENT_NESTED_DYNAMIC_ZONE' | 'INVALID_DYNAMIC_ZONE_COMPONENTS' | 'DYNAMIC_ZONE_EMPTY_COMPONENTS' | 'DYNAMIC_ZONE_COMPONENT_NOT_FOUND' | 'INVALID_COMPONENT_DATA' | 'MISSING_COMPONENT_TYPE' | 'COMPONENT_MIN_ITEMS' | 'COMPONENT_MAX_ITEMS';
135
240
  interface ValidationResult {
136
241
  valid: boolean;
137
242
  errors: ValidationError[];
@@ -227,4 +332,1073 @@ interface RollbackResult {
227
332
  errors?: string[];
228
333
  }
229
334
 
230
- export { type ACmsField, type ACmsSchema, type ContentEntry, type FieldType, type MediaType, type Migration, type MigrationDatabaseConnection, type MigrationRecord, type MigrationResult, type MigrationStatus, type MySQLMigrationConnection, type Plugin, type PluginHooks, type PostgresMigrationConnection, type QueryOptions, type RollbackResult, type SQLiteMigrationConnection, SchemaValidationError, type Theme, type ThemeConfig, type User, type ValidationError, type ValidationErrorCode, type ValidationResult, exampleSchema };
335
+ /**
336
+ * Middleware Types
337
+ * Типы для системы middleware/хуков Notty CMS
338
+ */
339
+ /**
340
+ * Метаданные выполнения запроса для трассировки
341
+ */
342
+ interface RequestMeta {
343
+ /** Уникальный ID запроса (UUID) */
344
+ requestId: string;
345
+ /** ID трассировки (для распределённой трассировки) */
346
+ traceId?: string;
347
+ /** ID родительского span (для вложенных операций) */
348
+ parentSpanId?: string;
349
+ /** Timestamp начала запроса */
350
+ startTime: number;
351
+ }
352
+ /**
353
+ * Результат выполнения одного middleware с таймингами
354
+ */
355
+ interface MiddlewareTiming {
356
+ /** Имя middleware */
357
+ name: string;
358
+ /** Время начала (performance.now или Date.now) */
359
+ startTime: number;
360
+ /** Время окончания */
361
+ endTime: number;
362
+ /** Длительность в мс */
363
+ duration: number;
364
+ /** Была ли ошибка */
365
+ error?: boolean;
366
+ /** Был ли прерван (continue: false) */
367
+ aborted?: boolean;
368
+ }
369
+ /**
370
+ * Агрегированный результат выполнения цепочки middleware
371
+ */
372
+ interface MiddlewareChainResult<T = unknown> {
373
+ /** Результат выполнения */
374
+ result: T;
375
+ /** Тайминги по каждому middleware */
376
+ timings: MiddlewareTiming[];
377
+ /** Общее время выполнения цепочки */
378
+ totalDuration: number;
379
+ /** Количество выполненных middleware */
380
+ middlewaresExecuted: number;
381
+ /** ID запроса */
382
+ requestId: string;
383
+ /** Была ли ошибка */
384
+ hasError: boolean;
385
+ /** Была ли цепочка прервана */
386
+ wasAborted: boolean;
387
+ }
388
+ /**
389
+ * Унифицированный payload ошибки middleware
390
+ */
391
+ interface MiddlewareError {
392
+ /** Имя middleware где произошла ошибка */
393
+ middlewareName: string;
394
+ /** Тип middleware */
395
+ middlewareType: 'admin' | 'content' | 'system';
396
+ /** Сообщение ошибки */
397
+ message: string;
398
+ /** Стек ошибки (опционально, в dev mode) */
399
+ stack?: string;
400
+ /** Код ошибки (если есть) */
401
+ code?: string;
402
+ /** HTTP статус (если применимо) */
403
+ statusCode?: number;
404
+ /** Timestamp ошибки */
405
+ timestamp: Date;
406
+ /** Request ID */
407
+ requestId: string;
408
+ /** Дополнительные данные */
409
+ metadata?: Record<string, unknown>;
410
+ }
411
+ /**
412
+ * Callback для логирования/метрик
413
+ */
414
+ type MiddlewareObserver = {
415
+ /** Вызывается при завершении цепочки middleware */
416
+ onChainComplete?: (result: MiddlewareChainResult) => void;
417
+ /** Вызывается при ошибке в middleware */
418
+ onMiddlewareError?: (error: MiddlewareError) => void;
419
+ /** Вызывается при завершении одного middleware */
420
+ onMiddlewareComplete?: (timing: MiddlewareTiming, requestId: string) => void;
421
+ };
422
+ /**
423
+ * Базовый контекст запроса
424
+ */
425
+ interface MiddlewareBaseContext {
426
+ /** URL path */
427
+ path: string;
428
+ /** HTTP method */
429
+ method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS' | 'HEAD';
430
+ /** Request headers */
431
+ headers: Record<string, string | string[] | undefined>;
432
+ /** URL query parameters */
433
+ query: Record<string, string | string[] | undefined>;
434
+ /** Route parameters */
435
+ params: Record<string, string | undefined>;
436
+ /** Метаданные запроса (requestId, traceId, timings) */
437
+ meta?: RequestMeta;
438
+ }
439
+ /**
440
+ * Информация об аутентифицированном admin пользователе
441
+ */
442
+ interface AdminUserContext {
443
+ id: number;
444
+ username: string;
445
+ email: string;
446
+ role: string;
447
+ firstName?: string | null;
448
+ lastName?: string | null;
449
+ }
450
+ /**
451
+ * Информация об аутентифицированном content пользователе
452
+ */
453
+ interface ContentUserContext {
454
+ id: number;
455
+ username: string;
456
+ email: string;
457
+ role: string;
458
+ }
459
+ /**
460
+ * Контекст для Admin API middleware
461
+ */
462
+ interface AdminMiddlewareContext extends MiddlewareBaseContext {
463
+ /** Admin user (если аутентифицирован) */
464
+ adminUser: AdminUserContext | null;
465
+ /** Route name (e.g., "admin:users:list", "admin:users:create") */
466
+ routeName: string;
467
+ }
468
+ /**
469
+ * Контекст для Content API middleware
470
+ */
471
+ interface ContentMiddlewareContext extends MiddlewareBaseContext {
472
+ /** Content user (если аутентифицирован) */
473
+ user: ContentUserContext | null;
474
+ /** Admin user (если запрос от админа) */
475
+ adminUser: AdminUserContext | null;
476
+ /** Content type name */
477
+ contentType: string;
478
+ /** Operation type */
479
+ operation: ContentOperation;
480
+ /** Entry ID (для операций с конкретной записью) */
481
+ entryId?: string | number;
482
+ }
483
+ /**
484
+ * Контекст для System event middleware
485
+ */
486
+ interface SystemEventContext {
487
+ /** Event name */
488
+ event: SystemEvent;
489
+ /** Event timestamp */
490
+ timestamp: Date;
491
+ /** Event payload (varies by event type) */
492
+ payload: unknown;
493
+ }
494
+ /**
495
+ * Операции над контентом
496
+ */
497
+ type ContentOperation = 'create' | 'read' | 'update' | 'delete' | 'list' | 'publish' | 'unpublish' | 'bulk-update' | 'bulk-delete';
498
+ /**
499
+ * Системные события
500
+ */
501
+ type SystemEvent = 'app:start' | 'app:stop' | 'schema:create' | 'schema:update' | 'schema:delete' | 'schema:sync' | 'content:beforeCreate' | 'content:afterCreate' | 'content:beforeUpdate' | 'content:afterUpdate' | 'content:beforeDelete' | 'content:afterDelete' | 'content:beforeFind' | 'content:afterFind' | 'content:beforeFindMany' | 'content:afterFindMany' | 'content:beforeCount' | 'content:afterCount' | 'content:beforeQuery' | 'content:afterQuery' | 'content:beforeValidate' | 'content:afterValidate' | 'content:beforeSave' | 'content:afterSave' | 'content:beforePublish' | 'content:afterPublish' | 'content:beforeUnpublish' | 'content:afterUnpublish' | 'media:upload' | 'media:delete' | 'auth:beforeLogin' | 'auth:afterLogin' | 'auth:loginFailed' | 'auth:login' | 'auth:logout' | 'auth:register' | 'auth:tokenRefresh' | 'auth:passwordReset' | 'admin:beforeLogin' | 'admin:afterLogin' | 'admin:loginFailed' | 'admin:login' | 'admin:logout' | 'admin:tokenRefresh' | 'policy:beforeCheck' | 'policy:afterCheck';
502
+ /**
503
+ * Результат выполнения middleware
504
+ */
505
+ interface MiddlewareResult<T = unknown> {
506
+ /** Продолжить выполнение цепочки */
507
+ continue: boolean;
508
+ /** Модифицированные данные (для before* хуков) */
509
+ data?: T;
510
+ /** Ответ для клиента (если continue: false) */
511
+ response?: {
512
+ statusCode: number;
513
+ body: unknown;
514
+ headers?: Record<string, string>;
515
+ };
516
+ }
517
+ /**
518
+ * Admin API middleware handler
519
+ */
520
+ type AdminMiddlewareHandler<TInput = unknown, TOutput = unknown> = (ctx: AdminMiddlewareContext, input: TInput, next: () => Promise<TOutput>) => Promise<TOutput | MiddlewareResult<TOutput>>;
521
+ /**
522
+ * Content API middleware handler
523
+ */
524
+ type ContentMiddlewareHandler<TInput = unknown, TOutput = unknown> = (ctx: ContentMiddlewareContext, input: TInput, next: () => Promise<TOutput>) => Promise<TOutput | MiddlewareResult<TOutput>>;
525
+ /**
526
+ * System event handler
527
+ */
528
+ type SystemEventHandler<TPayload = unknown> = (ctx: SystemEventContext & {
529
+ payload: TPayload;
530
+ }) => Promise<void | {
531
+ payload: TPayload;
532
+ }>;
533
+ /**
534
+ * Определение middleware
535
+ */
536
+ interface MiddlewareDefinition<THandler = unknown> {
537
+ /** Уникальное имя middleware */
538
+ name: string;
539
+ /** Внутренний тип middleware (для loader) */
540
+ _type?: 'admin' | 'content' | 'system';
541
+ /** Описание */
542
+ description?: string;
543
+ /** Порядок выполнения (меньше = раньше, default: 100) */
544
+ order?: number;
545
+ /** Паттерн маршрута или массив паттернов (glob-like) */
546
+ routes?: string | string[];
547
+ /** HTTP методы (если не указано - все) */
548
+ methods?: Array<'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'>;
549
+ /** Content types (для content middleware) */
550
+ contentTypes?: string | string[];
551
+ /** Operations (для content middleware) */
552
+ operations?: ContentOperation | ContentOperation[];
553
+ /** Events (для system middleware) */
554
+ events?: SystemEvent | SystemEvent[];
555
+ /** Handler function */
556
+ handler: THandler;
557
+ /** Включен ли middleware */
558
+ enabled?: boolean;
559
+ }
560
+ /**
561
+ * Admin middleware definition
562
+ */
563
+ type AdminMiddleware<TInput = unknown, TOutput = unknown> = MiddlewareDefinition<AdminMiddlewareHandler<TInput, TOutput>>;
564
+ /**
565
+ * Content middleware definition
566
+ */
567
+ type ContentMiddleware<TInput = unknown, TOutput = unknown> = MiddlewareDefinition<ContentMiddlewareHandler<TInput, TOutput>>;
568
+ /**
569
+ * System event middleware definition
570
+ */
571
+ type SystemMiddleware<TPayload = unknown> = MiddlewareDefinition<SystemEventHandler<TPayload>>;
572
+ /**
573
+ * Конфигурация middleware для проекта
574
+ */
575
+ interface MiddlewareConfig {
576
+ /** Admin API middleware */
577
+ admin?: AdminMiddleware[];
578
+ /** Content API middleware */
579
+ content?: ContentMiddleware[];
580
+ /** System event handlers */
581
+ system?: SystemMiddleware[];
582
+ }
583
+ /**
584
+ * Фабрика для создания admin middleware
585
+ */
586
+ declare function defineAdminMiddleware<TInput = unknown, TOutput = unknown>(definition: AdminMiddleware<TInput, TOutput>): AdminMiddleware<TInput, TOutput>;
587
+ /**
588
+ * Фабрика для создания content middleware
589
+ */
590
+ declare function defineContentMiddleware<TInput = unknown, TOutput = unknown>(definition: ContentMiddleware<TInput, TOutput>): ContentMiddleware<TInput, TOutput>;
591
+ /**
592
+ * Фабрика для создания system middleware
593
+ */
594
+ declare function defineSystemMiddleware<TPayload = unknown>(definition: SystemMiddleware<TPayload>): SystemMiddleware<TPayload>;
595
+ /**
596
+ * Admin API routes с их типами input/output
597
+ */
598
+ interface AdminRouteMap {
599
+ 'admin:users:list': {
600
+ input: void;
601
+ output: {
602
+ success: boolean;
603
+ data: AdminUserContext[];
604
+ };
605
+ };
606
+ 'admin:users:get': {
607
+ input: {
608
+ id: number;
609
+ };
610
+ output: {
611
+ success: boolean;
612
+ data: AdminUserContext;
613
+ };
614
+ };
615
+ 'admin:users:create': {
616
+ input: {
617
+ username: string;
618
+ email: string;
619
+ password: string;
620
+ role?: string;
621
+ };
622
+ output: {
623
+ success: boolean;
624
+ data: AdminUserContext;
625
+ };
626
+ };
627
+ 'admin:users:update': {
628
+ input: {
629
+ id: number;
630
+ username?: string;
631
+ email?: string;
632
+ role?: string;
633
+ };
634
+ output: {
635
+ success: boolean;
636
+ data: AdminUserContext;
637
+ };
638
+ };
639
+ 'admin:users:delete': {
640
+ input: {
641
+ id: number;
642
+ };
643
+ output: {
644
+ success: boolean;
645
+ };
646
+ };
647
+ 'admin:auth:login': {
648
+ input: {
649
+ email: string;
650
+ password: string;
651
+ };
652
+ output: {
653
+ success: boolean;
654
+ token: string;
655
+ user: AdminUserContext;
656
+ };
657
+ };
658
+ 'admin:auth:me': {
659
+ input: void;
660
+ output: {
661
+ success: boolean;
662
+ data: AdminUserContext;
663
+ };
664
+ };
665
+ 'admin:auth:logout': {
666
+ input: void;
667
+ output: {
668
+ success: boolean;
669
+ message: string;
670
+ };
671
+ };
672
+ 'admin:auth:refresh': {
673
+ input: void;
674
+ output: {
675
+ success: boolean;
676
+ data: {
677
+ token: string;
678
+ user: AdminUserContext;
679
+ };
680
+ };
681
+ };
682
+ 'admin:settings:get': {
683
+ input: void;
684
+ output: {
685
+ success: boolean;
686
+ data: Record<string, unknown>;
687
+ };
688
+ };
689
+ 'admin:settings:update': {
690
+ input: Record<string, unknown>;
691
+ output: {
692
+ success: boolean;
693
+ data: Record<string, unknown>;
694
+ };
695
+ };
696
+ 'admin:settings:locales:list': {
697
+ input: void;
698
+ output: {
699
+ success: boolean;
700
+ data: unknown[];
701
+ };
702
+ };
703
+ 'admin:settings:locales:create': {
704
+ input: unknown;
705
+ output: {
706
+ success: boolean;
707
+ data: unknown;
708
+ };
709
+ };
710
+ 'admin:settings:locales:update': {
711
+ input: unknown;
712
+ output: {
713
+ success: boolean;
714
+ data: unknown;
715
+ };
716
+ };
717
+ 'admin:settings:locales:delete': {
718
+ input: {
719
+ code: string;
720
+ };
721
+ output: {
722
+ success: boolean;
723
+ };
724
+ };
725
+ 'admin:settings:locales:available': {
726
+ input: void;
727
+ output: {
728
+ success: boolean;
729
+ data: unknown[];
730
+ };
731
+ };
732
+ 'admin:config:get': {
733
+ input: void;
734
+ output: {
735
+ success: boolean;
736
+ data: Record<string, unknown>;
737
+ };
738
+ };
739
+ 'admin:config:update': {
740
+ input: Record<string, unknown>;
741
+ output: {
742
+ success: boolean;
743
+ data: Record<string, unknown>;
744
+ };
745
+ };
746
+ 'admin:config:reload': {
747
+ input: void;
748
+ output: {
749
+ success: boolean;
750
+ };
751
+ };
752
+ 'admin:config:import': {
753
+ input: unknown;
754
+ output: {
755
+ success: boolean;
756
+ data: Record<string, unknown>;
757
+ };
758
+ };
759
+ 'admin:config:export': {
760
+ input: void;
761
+ output: {
762
+ success: boolean;
763
+ data: Record<string, unknown>;
764
+ };
765
+ };
766
+ 'admin:config:schema': {
767
+ input: void;
768
+ output: {
769
+ success: boolean;
770
+ data: Record<string, unknown>;
771
+ };
772
+ };
773
+ 'admin:schemas:list': {
774
+ input: void;
775
+ output: {
776
+ success: boolean;
777
+ data: unknown[];
778
+ };
779
+ };
780
+ 'admin:schemas:get': {
781
+ input: {
782
+ name: string;
783
+ };
784
+ output: {
785
+ success: boolean;
786
+ data: unknown;
787
+ };
788
+ };
789
+ 'admin:schemas:create': {
790
+ input: unknown;
791
+ output: {
792
+ success: boolean;
793
+ data: unknown;
794
+ };
795
+ };
796
+ 'admin:schemas:update': {
797
+ input: {
798
+ name: string;
799
+ schema: unknown;
800
+ };
801
+ output: {
802
+ success: boolean;
803
+ data: unknown;
804
+ };
805
+ };
806
+ 'admin:schemas:delete': {
807
+ input: {
808
+ name: string;
809
+ };
810
+ output: {
811
+ success: boolean;
812
+ };
813
+ };
814
+ 'admin:roles:list': {
815
+ input: void;
816
+ output: {
817
+ success: boolean;
818
+ data: unknown[];
819
+ };
820
+ };
821
+ 'admin:roles:get': {
822
+ input: {
823
+ id: number;
824
+ };
825
+ output: {
826
+ success: boolean;
827
+ data: unknown;
828
+ };
829
+ };
830
+ 'admin:roles:create': {
831
+ input: unknown;
832
+ output: {
833
+ success: boolean;
834
+ data: unknown;
835
+ };
836
+ };
837
+ 'admin:roles:update': {
838
+ input: {
839
+ id: number;
840
+ data: unknown;
841
+ };
842
+ output: {
843
+ success: boolean;
844
+ data: unknown;
845
+ };
846
+ };
847
+ 'admin:roles:delete': {
848
+ input: {
849
+ id: number;
850
+ };
851
+ output: {
852
+ success: boolean;
853
+ };
854
+ };
855
+ 'admin:webhooks:list': {
856
+ input: void;
857
+ output: {
858
+ success: boolean;
859
+ data: unknown[];
860
+ };
861
+ };
862
+ 'admin:webhooks:get': {
863
+ input: {
864
+ id: number;
865
+ };
866
+ output: {
867
+ success: boolean;
868
+ data: unknown;
869
+ };
870
+ };
871
+ 'admin:webhooks:create': {
872
+ input: unknown;
873
+ output: {
874
+ success: boolean;
875
+ data: unknown;
876
+ };
877
+ };
878
+ 'admin:webhooks:update': {
879
+ input: {
880
+ id: number;
881
+ data: unknown;
882
+ };
883
+ output: {
884
+ success: boolean;
885
+ data: unknown;
886
+ };
887
+ };
888
+ 'admin:webhooks:delete': {
889
+ input: {
890
+ id: number;
891
+ };
892
+ output: {
893
+ success: boolean;
894
+ };
895
+ };
896
+ 'admin:media:list': {
897
+ input: void;
898
+ output: {
899
+ success: boolean;
900
+ data: unknown[];
901
+ };
902
+ };
903
+ 'admin:media:upload': {
904
+ input: unknown;
905
+ output: {
906
+ success: boolean;
907
+ data: unknown;
908
+ };
909
+ };
910
+ 'admin:media:delete': {
911
+ input: {
912
+ id: number;
913
+ };
914
+ output: {
915
+ success: boolean;
916
+ };
917
+ };
918
+ 'admin:components:list': {
919
+ input: void;
920
+ output: {
921
+ success: boolean;
922
+ data: unknown[];
923
+ };
924
+ };
925
+ 'admin:components:create': {
926
+ input: unknown;
927
+ output: {
928
+ success: boolean;
929
+ data: unknown;
930
+ };
931
+ };
932
+ 'admin:components:get': {
933
+ input: {
934
+ uid: string;
935
+ };
936
+ output: {
937
+ success: boolean;
938
+ data: unknown;
939
+ };
940
+ };
941
+ 'admin:components:update': {
942
+ input: {
943
+ uid: string;
944
+ data: unknown;
945
+ };
946
+ output: {
947
+ success: boolean;
948
+ data: unknown;
949
+ };
950
+ };
951
+ 'admin:components:delete': {
952
+ input: {
953
+ uid: string;
954
+ };
955
+ output: {
956
+ success: boolean;
957
+ };
958
+ };
959
+ }
960
+ /**
961
+ * Content API operations с их типами
962
+ */
963
+ interface ContentOperationMap {
964
+ create: {
965
+ input: Record<string, unknown>;
966
+ output: {
967
+ success: boolean;
968
+ data: unknown;
969
+ };
970
+ };
971
+ read: {
972
+ input: {
973
+ id: string | number;
974
+ };
975
+ output: {
976
+ success: boolean;
977
+ data: unknown;
978
+ };
979
+ };
980
+ update: {
981
+ input: {
982
+ id: string | number;
983
+ data: Record<string, unknown>;
984
+ };
985
+ output: {
986
+ success: boolean;
987
+ data: unknown;
988
+ };
989
+ };
990
+ delete: {
991
+ input: {
992
+ id: string | number;
993
+ };
994
+ output: {
995
+ success: boolean;
996
+ };
997
+ };
998
+ list: {
999
+ input: {
1000
+ page?: number;
1001
+ pageSize?: number;
1002
+ sort?: string[];
1003
+ filters?: Record<string, unknown>;
1004
+ };
1005
+ output: {
1006
+ success: boolean;
1007
+ data: unknown[];
1008
+ meta: {
1009
+ page: number;
1010
+ pageSize: number;
1011
+ total: number;
1012
+ totalPages: number;
1013
+ };
1014
+ };
1015
+ };
1016
+ publish: {
1017
+ input: {
1018
+ id: string | number;
1019
+ };
1020
+ output: {
1021
+ success: boolean;
1022
+ data: unknown;
1023
+ };
1024
+ };
1025
+ unpublish: {
1026
+ input: {
1027
+ id: string | number;
1028
+ };
1029
+ output: {
1030
+ success: boolean;
1031
+ data: unknown;
1032
+ };
1033
+ };
1034
+ 'bulk-update': {
1035
+ input: {
1036
+ ids: (string | number)[];
1037
+ data: Record<string, unknown>;
1038
+ };
1039
+ output: {
1040
+ success: boolean;
1041
+ updated: number;
1042
+ };
1043
+ };
1044
+ 'bulk-delete': {
1045
+ input: {
1046
+ ids: (string | number)[];
1047
+ };
1048
+ output: {
1049
+ success: boolean;
1050
+ deleted: number;
1051
+ };
1052
+ };
1053
+ }
1054
+ /**
1055
+ * System event payloads
1056
+ */
1057
+ interface SystemEventPayloadMap {
1058
+ 'app:start': {
1059
+ timestamp: Date;
1060
+ };
1061
+ 'app:stop': {
1062
+ timestamp: Date;
1063
+ };
1064
+ 'schema:create': {
1065
+ schemaName: string;
1066
+ schema: unknown;
1067
+ };
1068
+ 'schema:update': {
1069
+ schemaName: string;
1070
+ schema: unknown;
1071
+ previousSchema: unknown;
1072
+ };
1073
+ 'schema:delete': {
1074
+ schemaName: string;
1075
+ };
1076
+ 'schema:sync': {
1077
+ schemas: string[];
1078
+ };
1079
+ 'content:beforeCreate': {
1080
+ contentType: string;
1081
+ data: Record<string, unknown>;
1082
+ };
1083
+ 'content:afterCreate': {
1084
+ contentType: string;
1085
+ data: Record<string, unknown>;
1086
+ entry: unknown;
1087
+ };
1088
+ 'content:beforeUpdate': {
1089
+ contentType: string;
1090
+ id: string | number;
1091
+ data: Record<string, unknown>;
1092
+ previousEntry: unknown;
1093
+ };
1094
+ 'content:afterUpdate': {
1095
+ contentType: string;
1096
+ id: string | number;
1097
+ data: Record<string, unknown>;
1098
+ entry: unknown;
1099
+ };
1100
+ 'content:beforeDelete': {
1101
+ contentType: string;
1102
+ id: string | number;
1103
+ entry: unknown;
1104
+ };
1105
+ 'content:afterDelete': {
1106
+ contentType: string;
1107
+ id: string | number;
1108
+ };
1109
+ 'content:beforeFind': {
1110
+ contentType: string;
1111
+ id: string | number;
1112
+ options: {
1113
+ populate?: string | string[];
1114
+ locale?: string;
1115
+ };
1116
+ };
1117
+ 'content:afterFind': {
1118
+ contentType: string;
1119
+ id: string | number;
1120
+ entry: unknown;
1121
+ };
1122
+ 'content:beforeFindMany': {
1123
+ contentType: string;
1124
+ query: {
1125
+ limit?: number;
1126
+ offset?: number;
1127
+ sort?: string;
1128
+ sortOrder?: 'asc' | 'desc';
1129
+ filters?: Record<string, unknown>;
1130
+ published?: boolean;
1131
+ populate?: string | string[];
1132
+ search?: string;
1133
+ searchFields?: string[];
1134
+ locale?: string;
1135
+ };
1136
+ };
1137
+ 'content:afterFindMany': {
1138
+ contentType: string;
1139
+ query: Record<string, unknown>;
1140
+ result: {
1141
+ data: unknown[];
1142
+ total: number;
1143
+ };
1144
+ };
1145
+ 'content:beforeCount': {
1146
+ contentType: string;
1147
+ query: {
1148
+ filters?: Record<string, unknown>;
1149
+ groupBy?: string[];
1150
+ };
1151
+ };
1152
+ 'content:afterCount': {
1153
+ contentType: string;
1154
+ query: Record<string, unknown>;
1155
+ result: unknown;
1156
+ };
1157
+ 'content:beforeQuery': {
1158
+ contentType: string;
1159
+ /** Operation type: read (findOne), list (findMany), count, aggregate */
1160
+ operation: 'read' | 'list' | 'count' | 'aggregate';
1161
+ /** Query parameters (filters, sort, pagination, search, populate) */
1162
+ query: {
1163
+ id?: string | number;
1164
+ limit?: number;
1165
+ offset?: number;
1166
+ sort?: string;
1167
+ sortOrder?: 'asc' | 'desc';
1168
+ filters?: Record<string, unknown>;
1169
+ published?: boolean;
1170
+ populate?: string | string[];
1171
+ search?: string;
1172
+ searchFields?: string[];
1173
+ locale?: string;
1174
+ groupBy?: string[];
1175
+ aggregate?: Record<string, string>;
1176
+ having?: Record<string, unknown>;
1177
+ };
1178
+ };
1179
+ 'content:afterQuery': {
1180
+ contentType: string;
1181
+ /** Operation type */
1182
+ operation: 'read' | 'list' | 'count' | 'aggregate';
1183
+ /** Original query parameters */
1184
+ query: Record<string, unknown>;
1185
+ /** SQL metadata (for debugging/logging) */
1186
+ meta?: {
1187
+ sql?: string;
1188
+ params?: unknown[];
1189
+ duration?: number;
1190
+ };
1191
+ /** Query result */
1192
+ result: unknown;
1193
+ };
1194
+ 'content:beforeValidate': {
1195
+ contentType: string;
1196
+ operation: 'create' | 'update';
1197
+ data: Record<string, unknown>;
1198
+ id?: string | number;
1199
+ };
1200
+ 'content:afterValidate': {
1201
+ contentType: string;
1202
+ operation: 'create' | 'update';
1203
+ data: Record<string, unknown>;
1204
+ id?: string | number;
1205
+ isValid: boolean;
1206
+ errors?: Array<{
1207
+ field: string;
1208
+ message: string;
1209
+ }>;
1210
+ };
1211
+ 'content:beforeSave': {
1212
+ contentType: string;
1213
+ operation: 'create' | 'update';
1214
+ data: Record<string, unknown>;
1215
+ id?: string | number;
1216
+ previousEntry?: unknown;
1217
+ };
1218
+ 'content:afterSave': {
1219
+ contentType: string;
1220
+ operation: 'create' | 'update';
1221
+ data: Record<string, unknown>;
1222
+ entry: unknown;
1223
+ id: string | number;
1224
+ };
1225
+ 'content:beforePublish': {
1226
+ contentType: string;
1227
+ id: string | number;
1228
+ entry: unknown;
1229
+ };
1230
+ 'content:afterPublish': {
1231
+ contentType: string;
1232
+ id: string | number;
1233
+ entry: unknown;
1234
+ };
1235
+ 'content:beforeUnpublish': {
1236
+ contentType: string;
1237
+ id: string | number;
1238
+ entry: unknown;
1239
+ };
1240
+ 'content:afterUnpublish': {
1241
+ contentType: string;
1242
+ id: string | number;
1243
+ entry: unknown;
1244
+ };
1245
+ 'media:upload': {
1246
+ file: unknown;
1247
+ metadata: unknown;
1248
+ };
1249
+ 'media:delete': {
1250
+ id: number;
1251
+ file: unknown;
1252
+ };
1253
+ 'auth:beforeLogin': {
1254
+ identifier: string;
1255
+ ip?: string;
1256
+ userAgent?: string;
1257
+ provider?: string;
1258
+ };
1259
+ 'auth:afterLogin': {
1260
+ userId: number;
1261
+ email: string;
1262
+ username: string;
1263
+ role: string;
1264
+ ip?: string;
1265
+ userAgent?: string;
1266
+ provider?: string;
1267
+ };
1268
+ 'auth:loginFailed': {
1269
+ identifier: string;
1270
+ reason: 'invalid_credentials' | 'user_not_found' | 'user_blocked' | 'unknown';
1271
+ ip?: string;
1272
+ userAgent?: string;
1273
+ provider?: string;
1274
+ };
1275
+ 'auth:login': {
1276
+ userId: number;
1277
+ email: string;
1278
+ };
1279
+ 'auth:logout': {
1280
+ userId: number;
1281
+ ip?: string;
1282
+ userAgent?: string;
1283
+ };
1284
+ 'auth:register': {
1285
+ userId: number;
1286
+ email: string;
1287
+ username: string;
1288
+ ip?: string;
1289
+ userAgent?: string;
1290
+ };
1291
+ 'auth:tokenRefresh': {
1292
+ userId: number;
1293
+ ip?: string;
1294
+ userAgent?: string;
1295
+ };
1296
+ 'auth:passwordReset': {
1297
+ userId: number;
1298
+ email: string;
1299
+ stage: 'requested' | 'completed';
1300
+ ip?: string;
1301
+ userAgent?: string;
1302
+ };
1303
+ 'admin:beforeLogin': {
1304
+ identifier: string;
1305
+ ip?: string;
1306
+ userAgent?: string;
1307
+ };
1308
+ 'admin:afterLogin': {
1309
+ adminId: number;
1310
+ email: string;
1311
+ username: string;
1312
+ role: string;
1313
+ ip?: string;
1314
+ userAgent?: string;
1315
+ };
1316
+ 'admin:loginFailed': {
1317
+ identifier: string;
1318
+ reason: 'invalid_credentials' | 'user_not_found' | 'unknown';
1319
+ ip?: string;
1320
+ userAgent?: string;
1321
+ };
1322
+ 'admin:login': {
1323
+ adminId: number;
1324
+ email: string;
1325
+ };
1326
+ 'admin:logout': {
1327
+ adminId: number;
1328
+ ip?: string;
1329
+ userAgent?: string;
1330
+ };
1331
+ 'admin:tokenRefresh': {
1332
+ adminId: number;
1333
+ ip?: string;
1334
+ userAgent?: string;
1335
+ };
1336
+ 'policy:beforeCheck': {
1337
+ /** Content type being accessed */
1338
+ subject: string;
1339
+ /** Action being performed */
1340
+ action: 'create' | 'read' | 'update' | 'delete' | 'publish';
1341
+ /** Content user (if authenticated) */
1342
+ user: {
1343
+ id: number;
1344
+ username: string;
1345
+ email: string;
1346
+ role: string;
1347
+ } | null;
1348
+ /** Admin user (if request from admin) */
1349
+ adminUser: {
1350
+ id: number;
1351
+ username: string;
1352
+ email: string;
1353
+ role: string;
1354
+ } | null;
1355
+ /** User's role name */
1356
+ role: string;
1357
+ /** Effective permissions for this role (if available) */
1358
+ effectivePermissions?: Record<string, unknown>;
1359
+ /** Initial decision (can be modified by middleware) */
1360
+ decision: 'allow' | 'deny';
1361
+ };
1362
+ 'policy:afterCheck': {
1363
+ /** Content type being accessed */
1364
+ subject: string;
1365
+ /** Action being performed */
1366
+ action: 'create' | 'read' | 'update' | 'delete' | 'publish';
1367
+ /** Content user (if authenticated) */
1368
+ user: {
1369
+ id: number;
1370
+ username: string;
1371
+ email: string;
1372
+ role: string;
1373
+ } | null;
1374
+ /** Admin user (if request from admin) */
1375
+ adminUser: {
1376
+ id: number;
1377
+ username: string;
1378
+ email: string;
1379
+ role: string;
1380
+ } | null;
1381
+ /** User's role name */
1382
+ role: string;
1383
+ /** Final decision */
1384
+ decision: 'allow' | 'deny';
1385
+ /** Reason for the decision */
1386
+ reason?: string;
1387
+ /** Was decision overridden by middleware? */
1388
+ overridden?: boolean;
1389
+ };
1390
+ }
1391
+ /**
1392
+ * Типизированный system middleware handler
1393
+ */
1394
+ type TypedSystemEventHandler<E extends SystemEvent> = SystemEventHandler<SystemEventPayloadMap[E]>;
1395
+ /**
1396
+ * Типизированный admin middleware для конкретного route
1397
+ */
1398
+ type TypedAdminMiddleware<R extends keyof AdminRouteMap> = AdminMiddleware<AdminRouteMap[R]['input'], AdminRouteMap[R]['output']>;
1399
+ /**
1400
+ * Типизированный content middleware для конкретной операции
1401
+ */
1402
+ type TypedContentMiddleware<O extends ContentOperation> = ContentMiddleware<ContentOperationMap[O]['input'], ContentOperationMap[O]['output']>;
1403
+
1404
+ export { type ACmsField, type ACmsSchema, type AdminMiddleware, type AdminMiddlewareContext, type AdminMiddlewareHandler, type AdminRouteMap, type AdminUserContext, type ComponentData, type ComponentDataInput, type ComponentFieldData, type ComponentFieldInput, type ComponentSchema, type ContentEntry, type ContentMiddleware, type ContentMiddlewareContext, type ContentMiddlewareHandler, type ContentOperation, type ContentOperationMap, type ContentUserContext, type DynamicZoneData, type DynamicZoneInput, type DynamicZoneItem, type DynamicZoneItemInput, type FieldType, type MediaType, type MiddlewareBaseContext, type MiddlewareChainResult, type MiddlewareConfig, type MiddlewareDefinition, type MiddlewareError, type MiddlewareObserver, type MiddlewareResult, type MiddlewareTiming, type Migration, type MigrationDatabaseConnection, type MigrationRecord, type MigrationResult, type MigrationStatus, type MySQLMigrationConnection, type Plugin, type PluginHooks, type PostgresMigrationConnection, type QueryOptions, type RequestMeta, type RollbackResult, type SQLiteMigrationConnection, type SchemaKind, SchemaValidationError, type SystemEvent, type SystemEventContext, type SystemEventHandler, type SystemEventPayloadMap, type SystemMiddleware, type Theme, type ThemeConfig, type TypedAdminMiddleware, type TypedContentMiddleware, type TypedSystemEventHandler, type User, type ValidationError, type ValidationErrorCode, type ValidationResult, defineAdminMiddleware, defineContentMiddleware, defineSystemMiddleware, exampleBlockComponent, exampleComponentSchema, exampleSchema };