@notty/types 0.7.1 → 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.cjs +118 -2
- package/dist/index.d.cts +1179 -5
- package/dist/index.d.ts +1179 -5
- package/dist/index.js +113 -2
- package/package.json +1 -1
package/dist/index.d.cts
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:
|
|
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
|
-
|
|
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 };
|