@maykonpaulo/maestro-core 0.2.0 → 0.3.0-next.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/README.md +94 -67
- package/dist/index.d.ts +762 -1
- package/dist/index.js +2102 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -206,4 +206,765 @@ declare class InMemoryEventBus implements EventBus {
|
|
|
206
206
|
unsubscribe<TPayload>(eventType: string, handler: EventHandler<TPayload>): void;
|
|
207
207
|
}
|
|
208
208
|
|
|
209
|
-
|
|
209
|
+
type FilterOperator = 'equals' | 'notEquals' | 'contains' | 'startsWith' | 'endsWith' | 'in' | 'notIn' | 'gt' | 'gte' | 'lt' | 'lte' | 'between' | 'isNull' | 'isNotNull' | 'isTrue' | 'isFalse';
|
|
210
|
+
|
|
211
|
+
interface FilterDescriptor {
|
|
212
|
+
field: string;
|
|
213
|
+
operator: FilterOperator;
|
|
214
|
+
value?: unknown;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
type SortDirection = 'asc' | 'desc';
|
|
218
|
+
interface SortDescriptor {
|
|
219
|
+
field: string;
|
|
220
|
+
direction: SortDirection;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
interface PagePagination {
|
|
224
|
+
strategy: 'page';
|
|
225
|
+
page: number;
|
|
226
|
+
pageSize: number;
|
|
227
|
+
}
|
|
228
|
+
interface OffsetPagination {
|
|
229
|
+
strategy: 'offset';
|
|
230
|
+
offset: number;
|
|
231
|
+
limit: number;
|
|
232
|
+
}
|
|
233
|
+
interface CursorPagination {
|
|
234
|
+
strategy: 'cursor';
|
|
235
|
+
cursor?: string;
|
|
236
|
+
limit: number;
|
|
237
|
+
}
|
|
238
|
+
type PaginationInput = PagePagination | OffsetPagination | CursorPagination;
|
|
239
|
+
|
|
240
|
+
interface SearchInput {
|
|
241
|
+
term: string;
|
|
242
|
+
fields: string[];
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
interface QueryInput {
|
|
246
|
+
filters?: FilterDescriptor[];
|
|
247
|
+
sort?: SortDescriptor[];
|
|
248
|
+
pagination?: PaginationInput;
|
|
249
|
+
search?: SearchInput;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
interface ListResult<T = Record<string, unknown>> {
|
|
253
|
+
records: T[];
|
|
254
|
+
total: number;
|
|
255
|
+
page?: number;
|
|
256
|
+
pageSize?: number;
|
|
257
|
+
totalPages?: number;
|
|
258
|
+
nextCursor?: string;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
type FieldType = 'string' | 'text' | 'number' | 'integer' | 'decimal' | 'currency' | 'boolean' | 'date' | 'datetime' | 'time' | 'email' | 'phone' | 'url' | 'document' | 'uuid' | 'enum' | 'json' | 'relation' | 'array';
|
|
262
|
+
|
|
263
|
+
interface EnumOption {
|
|
264
|
+
value: string | number;
|
|
265
|
+
label: string;
|
|
266
|
+
}
|
|
267
|
+
interface FieldListConfig {
|
|
268
|
+
visible: boolean;
|
|
269
|
+
width?: number;
|
|
270
|
+
align?: 'left' | 'center' | 'right';
|
|
271
|
+
order?: number;
|
|
272
|
+
}
|
|
273
|
+
interface FieldDetailConfig {
|
|
274
|
+
visible: boolean;
|
|
275
|
+
group?: string;
|
|
276
|
+
order?: number;
|
|
277
|
+
}
|
|
278
|
+
interface FieldFormConfig {
|
|
279
|
+
creatable: boolean;
|
|
280
|
+
editable: boolean;
|
|
281
|
+
cloneable: boolean;
|
|
282
|
+
placeholder?: string;
|
|
283
|
+
helpText?: string;
|
|
284
|
+
section?: string;
|
|
285
|
+
order?: number;
|
|
286
|
+
}
|
|
287
|
+
interface FieldMetadata {
|
|
288
|
+
name: string;
|
|
289
|
+
label: string;
|
|
290
|
+
type: FieldType;
|
|
291
|
+
required: boolean;
|
|
292
|
+
readonly: boolean;
|
|
293
|
+
hidden: boolean;
|
|
294
|
+
sensitive: boolean;
|
|
295
|
+
searchable: boolean;
|
|
296
|
+
sortable: boolean;
|
|
297
|
+
filterable: boolean;
|
|
298
|
+
exportable: boolean;
|
|
299
|
+
filterOperators: FilterOperator[];
|
|
300
|
+
description?: string;
|
|
301
|
+
enumOptions?: EnumOption[];
|
|
302
|
+
relationEntity?: string;
|
|
303
|
+
mask?: string;
|
|
304
|
+
list: FieldListConfig;
|
|
305
|
+
detail: FieldDetailConfig;
|
|
306
|
+
form: FieldFormConfig;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
interface EntityCapabilities {
|
|
310
|
+
list: boolean;
|
|
311
|
+
detail: boolean;
|
|
312
|
+
create: boolean;
|
|
313
|
+
update: boolean;
|
|
314
|
+
clone: boolean;
|
|
315
|
+
delete: boolean;
|
|
316
|
+
softDelete: boolean;
|
|
317
|
+
export: boolean;
|
|
318
|
+
bulkActions: boolean;
|
|
319
|
+
}
|
|
320
|
+
declare const DEFAULT_CAPABILITIES: EntityCapabilities;
|
|
321
|
+
|
|
322
|
+
interface SoftDeleteConfig {
|
|
323
|
+
field: string;
|
|
324
|
+
activeValue: unknown;
|
|
325
|
+
inactiveValue: unknown;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
interface SearchConfig {
|
|
329
|
+
fields: string[];
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
type ContextActionCondition = 'always' | 'when-active' | 'when-inactive';
|
|
333
|
+
type ContextActionStyle = 'default' | 'warning' | 'danger';
|
|
334
|
+
interface ContextAction {
|
|
335
|
+
id: string;
|
|
336
|
+
label: string;
|
|
337
|
+
permission: string;
|
|
338
|
+
condition?: ContextActionCondition;
|
|
339
|
+
style?: ContextActionStyle;
|
|
340
|
+
operationId?: string;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
interface ExportConfig {
|
|
344
|
+
filename?: string;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
interface EntityMetadata {
|
|
348
|
+
id: string;
|
|
349
|
+
label: {
|
|
350
|
+
singular: string;
|
|
351
|
+
plural: string;
|
|
352
|
+
};
|
|
353
|
+
description?: string;
|
|
354
|
+
datasource: string;
|
|
355
|
+
table: string;
|
|
356
|
+
primaryKey: string;
|
|
357
|
+
displayField: string;
|
|
358
|
+
fields: FieldMetadata[];
|
|
359
|
+
capabilities: EntityCapabilities;
|
|
360
|
+
softDelete?: SoftDeleteConfig;
|
|
361
|
+
defaultSort?: SortDescriptor;
|
|
362
|
+
search?: SearchConfig;
|
|
363
|
+
relations: string[];
|
|
364
|
+
contextActions: ContextAction[];
|
|
365
|
+
bulkOperations: string[];
|
|
366
|
+
exportConfig?: ExportConfig;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
type RelationType = 'one-to-one' | 'one-to-many' | 'many-to-one' | 'many-to-many';
|
|
370
|
+
interface RelationEndpoint {
|
|
371
|
+
entity: string;
|
|
372
|
+
field: string;
|
|
373
|
+
}
|
|
374
|
+
interface RelationDisplayConfig {
|
|
375
|
+
tab: boolean;
|
|
376
|
+
label?: string;
|
|
377
|
+
}
|
|
378
|
+
interface RelationMetadata {
|
|
379
|
+
id: string;
|
|
380
|
+
type: RelationType;
|
|
381
|
+
from: RelationEndpoint;
|
|
382
|
+
to: RelationEndpoint;
|
|
383
|
+
label: string;
|
|
384
|
+
display?: RelationDisplayConfig;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
type OperationScope = 'global' | 'entity' | 'record' | 'bulk';
|
|
388
|
+
interface OperationMetadata {
|
|
389
|
+
id: string;
|
|
390
|
+
label: string;
|
|
391
|
+
description?: string;
|
|
392
|
+
entity?: string;
|
|
393
|
+
scope: OperationScope;
|
|
394
|
+
requiresConfirmation: boolean;
|
|
395
|
+
confirmationMessage?: string;
|
|
396
|
+
requiresTypedConfirmation: boolean;
|
|
397
|
+
requiredPermission?: string;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
interface MaestroMetadata {
|
|
401
|
+
entities: EntityMetadata[];
|
|
402
|
+
relations: RelationMetadata[];
|
|
403
|
+
operations: OperationMetadata[];
|
|
404
|
+
policies: RbacPolicy;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
interface DatasourceQueryContext {
|
|
408
|
+
table: string;
|
|
409
|
+
primaryKey: string;
|
|
410
|
+
filters?: FilterDescriptor[];
|
|
411
|
+
sort?: SortDescriptor[];
|
|
412
|
+
pagination?: PaginationInput;
|
|
413
|
+
search?: SearchInput;
|
|
414
|
+
}
|
|
415
|
+
interface DatasourceFindContext {
|
|
416
|
+
table: string;
|
|
417
|
+
primaryKey: string;
|
|
418
|
+
id: string;
|
|
419
|
+
}
|
|
420
|
+
interface DatasourceWriteContext {
|
|
421
|
+
table: string;
|
|
422
|
+
primaryKey: string;
|
|
423
|
+
data: Record<string, unknown>;
|
|
424
|
+
}
|
|
425
|
+
interface DatasourceUpdateContext {
|
|
426
|
+
table: string;
|
|
427
|
+
primaryKey: string;
|
|
428
|
+
id: string;
|
|
429
|
+
data: Record<string, unknown>;
|
|
430
|
+
}
|
|
431
|
+
interface DatasourceDeleteContext {
|
|
432
|
+
table: string;
|
|
433
|
+
primaryKey: string;
|
|
434
|
+
id: string;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
interface DatasourceProvider {
|
|
438
|
+
list(context: DatasourceQueryContext): Promise<ListResult<Record<string, unknown>>>;
|
|
439
|
+
findById(context: DatasourceFindContext): Promise<Record<string, unknown> | null>;
|
|
440
|
+
create(context: DatasourceWriteContext): Promise<Record<string, unknown>>;
|
|
441
|
+
update(context: DatasourceUpdateContext): Promise<Record<string, unknown>>;
|
|
442
|
+
delete(context: DatasourceDeleteContext): Promise<void>;
|
|
443
|
+
count(context: DatasourceQueryContext): Promise<number>;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
declare class DatasourceRegistry {
|
|
447
|
+
private readonly registry;
|
|
448
|
+
register(id: string, provider: DatasourceProvider): void;
|
|
449
|
+
get(id: string): DatasourceProvider;
|
|
450
|
+
has(id: string): boolean;
|
|
451
|
+
ids(): string[];
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
declare class InMemoryDatasourceProvider implements DatasourceProvider {
|
|
455
|
+
private readonly tables;
|
|
456
|
+
seed(table: string, records: Record<string, unknown>[], primaryKey?: string): void;
|
|
457
|
+
list(context: DatasourceQueryContext): Promise<ListResult<Record<string, unknown>>>;
|
|
458
|
+
findById(context: DatasourceFindContext): Promise<Record<string, unknown> | null>;
|
|
459
|
+
create(context: DatasourceWriteContext): Promise<Record<string, unknown>>;
|
|
460
|
+
update(context: DatasourceUpdateContext): Promise<Record<string, unknown>>;
|
|
461
|
+
delete(context: DatasourceDeleteContext): Promise<void>;
|
|
462
|
+
count(context: DatasourceQueryContext): Promise<number>;
|
|
463
|
+
private getStore;
|
|
464
|
+
private applyFilters;
|
|
465
|
+
private matchFilter;
|
|
466
|
+
private applySort;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
interface OperationContext<TInput = unknown> {
|
|
470
|
+
actor: Actor;
|
|
471
|
+
entityId?: string;
|
|
472
|
+
record?: Record<string, unknown>;
|
|
473
|
+
records?: Record<string, unknown>[];
|
|
474
|
+
input?: TInput;
|
|
475
|
+
correlationId?: string;
|
|
476
|
+
metadata?: Metadata;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
interface OperationResult<TOutput = unknown> {
|
|
480
|
+
success: boolean;
|
|
481
|
+
output?: TOutput;
|
|
482
|
+
message?: string;
|
|
483
|
+
error?: string;
|
|
484
|
+
metadata?: Metadata;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
interface OperationDef<TInput = unknown, TOutput = unknown> {
|
|
488
|
+
id: string;
|
|
489
|
+
label: string;
|
|
490
|
+
description?: string;
|
|
491
|
+
entity?: string;
|
|
492
|
+
scope: OperationScope;
|
|
493
|
+
requiresConfirmation?: boolean;
|
|
494
|
+
confirmationMessage?: string;
|
|
495
|
+
requiresTypedConfirmation?: boolean;
|
|
496
|
+
requiredPermission?: string;
|
|
497
|
+
execute: (context: OperationContext<TInput>) => Promise<OperationResult<TOutput>>;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
declare class OperationRegistry {
|
|
501
|
+
private readonly operations;
|
|
502
|
+
register(operation: OperationDef): void;
|
|
503
|
+
get(id: string): OperationDef;
|
|
504
|
+
find(id: string): OperationDef | undefined;
|
|
505
|
+
forEntity(entityId: string, scope?: OperationScope): OperationDef[];
|
|
506
|
+
all(): OperationDef[];
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
interface FieldSchemaListConfig {
|
|
510
|
+
visible?: boolean;
|
|
511
|
+
width?: number;
|
|
512
|
+
align?: 'left' | 'center' | 'right';
|
|
513
|
+
order?: number;
|
|
514
|
+
}
|
|
515
|
+
interface FieldSchemaDetailConfig {
|
|
516
|
+
visible?: boolean;
|
|
517
|
+
group?: string;
|
|
518
|
+
order?: number;
|
|
519
|
+
}
|
|
520
|
+
interface FieldSchemaFormConfig {
|
|
521
|
+
creatable?: boolean;
|
|
522
|
+
editable?: boolean;
|
|
523
|
+
cloneable?: boolean;
|
|
524
|
+
placeholder?: string;
|
|
525
|
+
helpText?: string;
|
|
526
|
+
section?: string;
|
|
527
|
+
order?: number;
|
|
528
|
+
}
|
|
529
|
+
interface FieldSchemaEnumOption {
|
|
530
|
+
value: string | number;
|
|
531
|
+
label: string;
|
|
532
|
+
}
|
|
533
|
+
interface FieldSchema {
|
|
534
|
+
name: string;
|
|
535
|
+
label: string;
|
|
536
|
+
type: FieldType;
|
|
537
|
+
required?: boolean;
|
|
538
|
+
readonly?: boolean;
|
|
539
|
+
hidden?: boolean;
|
|
540
|
+
sensitive?: boolean;
|
|
541
|
+
searchable?: boolean;
|
|
542
|
+
sortable?: boolean;
|
|
543
|
+
filterable?: boolean;
|
|
544
|
+
exportable?: boolean;
|
|
545
|
+
filterOperators?: FilterOperator[];
|
|
546
|
+
description?: string;
|
|
547
|
+
enumOptions?: FieldSchemaEnumOption[];
|
|
548
|
+
relationEntity?: string;
|
|
549
|
+
mask?: string;
|
|
550
|
+
list?: FieldSchemaListConfig;
|
|
551
|
+
detail?: FieldSchemaDetailConfig;
|
|
552
|
+
form?: FieldSchemaFormConfig;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
interface EntitySourceConfig {
|
|
556
|
+
datasource: string;
|
|
557
|
+
table: string;
|
|
558
|
+
primaryKey?: string;
|
|
559
|
+
}
|
|
560
|
+
interface EntityLabelConfig {
|
|
561
|
+
singular: string;
|
|
562
|
+
plural: string;
|
|
563
|
+
}
|
|
564
|
+
interface EntityExportConfig {
|
|
565
|
+
filename?: string;
|
|
566
|
+
}
|
|
567
|
+
interface EntitySchema {
|
|
568
|
+
id: string;
|
|
569
|
+
label: EntityLabelConfig;
|
|
570
|
+
description?: string;
|
|
571
|
+
source: EntitySourceConfig;
|
|
572
|
+
displayField?: string;
|
|
573
|
+
capabilities?: Partial<EntityCapabilities>;
|
|
574
|
+
softDelete?: SoftDeleteConfig;
|
|
575
|
+
defaultSort?: SortDescriptor;
|
|
576
|
+
search?: SearchConfig;
|
|
577
|
+
exportConfig?: EntityExportConfig;
|
|
578
|
+
fields: FieldSchema[];
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
interface RelationSchema {
|
|
582
|
+
id: string;
|
|
583
|
+
type: RelationType;
|
|
584
|
+
from: RelationEndpoint;
|
|
585
|
+
to: RelationEndpoint;
|
|
586
|
+
label: string;
|
|
587
|
+
display?: RelationDisplayConfig;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
interface MaestroConfig {
|
|
591
|
+
datasources: Record<string, DatasourceProvider>;
|
|
592
|
+
entities: EntitySchema[];
|
|
593
|
+
relations?: RelationSchema[];
|
|
594
|
+
operations?: OperationDef[];
|
|
595
|
+
policies?: RbacPolicy;
|
|
596
|
+
audit?: AuditRepository;
|
|
597
|
+
logger?: Logger;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
interface SchemaValidationError {
|
|
601
|
+
path: string;
|
|
602
|
+
message: string;
|
|
603
|
+
}
|
|
604
|
+
interface SchemaValidationResult {
|
|
605
|
+
valid: boolean;
|
|
606
|
+
errors: SchemaValidationError[];
|
|
607
|
+
}
|
|
608
|
+
declare function validateMaestroConfig(config: MaestroConfig): SchemaValidationResult;
|
|
609
|
+
|
|
610
|
+
declare class MetadataEngine {
|
|
611
|
+
normalize(config: MaestroConfig): MaestroMetadata;
|
|
612
|
+
private normalizeEntity;
|
|
613
|
+
private normalizeField;
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
type ExportFormat = 'csv' | 'json';
|
|
617
|
+
|
|
618
|
+
interface ExportResult {
|
|
619
|
+
format: ExportFormat;
|
|
620
|
+
data: string;
|
|
621
|
+
filename: string;
|
|
622
|
+
recordCount: number;
|
|
623
|
+
mimeType: string;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
declare class MaestroEngine {
|
|
627
|
+
private readonly metadata;
|
|
628
|
+
private readonly datasources;
|
|
629
|
+
private readonly operations;
|
|
630
|
+
private readonly audit?;
|
|
631
|
+
private readonly rbac;
|
|
632
|
+
constructor(metadata: MaestroMetadata, datasources: DatasourceRegistry, operations: OperationRegistry, audit?: AuditRecorder | undefined);
|
|
633
|
+
getMetadata(): MaestroMetadata;
|
|
634
|
+
list(entityId: string, query: QueryInput, actor: Actor): Promise<ListResult<Record<string, unknown>>>;
|
|
635
|
+
findById(entityId: string, id: string, actor: Actor): Promise<Record<string, unknown> | null>;
|
|
636
|
+
create(entityId: string, data: Record<string, unknown>, actor: Actor): Promise<Record<string, unknown>>;
|
|
637
|
+
update(entityId: string, id: string, data: Record<string, unknown>, actor: Actor): Promise<Record<string, unknown>>;
|
|
638
|
+
clone(entityId: string, id: string, actor: Actor): Promise<Record<string, unknown>>;
|
|
639
|
+
softDelete(entityId: string, id: string, actor: Actor): Promise<void>;
|
|
640
|
+
restore(entityId: string, id: string, actor: Actor): Promise<void>;
|
|
641
|
+
hardDelete(entityId: string, id: string, actor: Actor): Promise<void>;
|
|
642
|
+
export(entityId: string, query: QueryInput, actor: Actor, format?: ExportFormat): Promise<ExportResult>;
|
|
643
|
+
executeOperation(operationId: string, context: OperationContext, actor: Actor): Promise<OperationResult>;
|
|
644
|
+
private requireEntity;
|
|
645
|
+
private requireCapability;
|
|
646
|
+
private recordAudit;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
declare function createMaestro(config: MaestroConfig): MaestroEngine;
|
|
650
|
+
|
|
651
|
+
interface FieldIntrospectionSchema {
|
|
652
|
+
name: string;
|
|
653
|
+
nativeType: string;
|
|
654
|
+
type: FieldType;
|
|
655
|
+
nullable: boolean;
|
|
656
|
+
isPrimaryKey: boolean;
|
|
657
|
+
isUnique?: boolean;
|
|
658
|
+
isForeignKey?: boolean;
|
|
659
|
+
referencesTable?: string;
|
|
660
|
+
referencesField?: string;
|
|
661
|
+
defaultValue?: unknown;
|
|
662
|
+
maxLength?: number;
|
|
663
|
+
isIndexed?: boolean;
|
|
664
|
+
candidateForSearch?: boolean;
|
|
665
|
+
candidateForSoftDelete?: boolean;
|
|
666
|
+
isTimestamp?: boolean;
|
|
667
|
+
}
|
|
668
|
+
interface IndexIntrospectionSchema {
|
|
669
|
+
name?: string;
|
|
670
|
+
fields: string[];
|
|
671
|
+
isUnique: boolean;
|
|
672
|
+
}
|
|
673
|
+
interface EntityIntrospectionSchema {
|
|
674
|
+
table: string;
|
|
675
|
+
fields: FieldIntrospectionSchema[];
|
|
676
|
+
indices?: IndexIntrospectionSchema[];
|
|
677
|
+
}
|
|
678
|
+
interface RelationIntrospectionSchema {
|
|
679
|
+
id: string;
|
|
680
|
+
type: RelationType;
|
|
681
|
+
from: {
|
|
682
|
+
table: string;
|
|
683
|
+
field: string;
|
|
684
|
+
};
|
|
685
|
+
to: {
|
|
686
|
+
table: string;
|
|
687
|
+
field: string;
|
|
688
|
+
};
|
|
689
|
+
confidence: 'definite' | 'inferred';
|
|
690
|
+
}
|
|
691
|
+
interface IntrospectionResult {
|
|
692
|
+
entities: EntityIntrospectionSchema[];
|
|
693
|
+
relations: RelationIntrospectionSchema[];
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
interface IntrospectionProvider {
|
|
697
|
+
introspect(): Promise<IntrospectionResult>;
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
interface YamlParser {
|
|
701
|
+
parse(content: string): unknown;
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
interface FileSystemReader {
|
|
705
|
+
readFile(path: string): Promise<string>;
|
|
706
|
+
readDir(path: string): Promise<string[]>;
|
|
707
|
+
exists(path: string): Promise<boolean>;
|
|
708
|
+
}
|
|
709
|
+
interface MaestroFileLoaderOptions {
|
|
710
|
+
rootDir: string;
|
|
711
|
+
yamlParser?: YamlParser;
|
|
712
|
+
fileReader?: FileSystemReader;
|
|
713
|
+
}
|
|
714
|
+
interface LoadedConfig {
|
|
715
|
+
entities: EntitySchema[];
|
|
716
|
+
relations: RelationSchema[];
|
|
717
|
+
policies?: RbacPolicy;
|
|
718
|
+
}
|
|
719
|
+
declare function loadMaestroConfig(options: MaestroFileLoaderOptions): Promise<LoadedConfig>;
|
|
720
|
+
|
|
721
|
+
type MergeStrategy = 'extend' | 'override';
|
|
722
|
+
interface MergeIntrospectionOptions {
|
|
723
|
+
introspection: IntrospectionResult;
|
|
724
|
+
overrides: LoadedConfig;
|
|
725
|
+
datasources: Record<string, DatasourceProvider>;
|
|
726
|
+
defaultDatasource: string;
|
|
727
|
+
strategy?: MergeStrategy;
|
|
728
|
+
operations?: OperationDef[];
|
|
729
|
+
audit?: AuditRepository;
|
|
730
|
+
logger?: Logger;
|
|
731
|
+
}
|
|
732
|
+
declare function mergeIntrospectionWithOverrides(options: MergeIntrospectionOptions): MaestroConfig;
|
|
733
|
+
|
|
734
|
+
interface CreateMaestroFromIntrospectionOptions {
|
|
735
|
+
provider: IntrospectionProvider;
|
|
736
|
+
overrides?: LoadedConfig;
|
|
737
|
+
mergeStrategy?: MergeStrategy;
|
|
738
|
+
datasources?: Record<string, DatasourceProvider>;
|
|
739
|
+
defaultDatasource?: string;
|
|
740
|
+
policies?: RbacPolicy;
|
|
741
|
+
operations?: OperationDef[];
|
|
742
|
+
audit?: AuditRepository;
|
|
743
|
+
logger?: Logger;
|
|
744
|
+
}
|
|
745
|
+
declare function createMaestroFromIntrospection(options: CreateMaestroFromIntrospectionOptions): Promise<MaestroEngine>;
|
|
746
|
+
|
|
747
|
+
interface ExportOptions {
|
|
748
|
+
format: ExportFormat;
|
|
749
|
+
includeFields?: string[];
|
|
750
|
+
excludeFields?: string[];
|
|
751
|
+
dateFormat?: string;
|
|
752
|
+
bom?: boolean;
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
interface ExportProvider {
|
|
756
|
+
export(entity: EntityMetadata, records: Record<string, unknown>[], options: ExportOptions): ExportResult;
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
declare class CsvExportProvider implements ExportProvider {
|
|
760
|
+
export(entity: EntityMetadata, records: Record<string, unknown>[], options: ExportOptions): ExportResult;
|
|
761
|
+
private resolveFields;
|
|
762
|
+
private formatValue;
|
|
763
|
+
private formatDate;
|
|
764
|
+
private escapeCsvCell;
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
interface MaestroHttpRequest {
|
|
768
|
+
params: Record<string, string>;
|
|
769
|
+
query: Record<string, string | string[]>;
|
|
770
|
+
body: unknown;
|
|
771
|
+
headers: Record<string, string | string[] | undefined>;
|
|
772
|
+
method: string;
|
|
773
|
+
path: string;
|
|
774
|
+
}
|
|
775
|
+
interface MaestroHttpResponse {
|
|
776
|
+
status: number;
|
|
777
|
+
body: unknown;
|
|
778
|
+
headers?: Record<string, string>;
|
|
779
|
+
}
|
|
780
|
+
type MaestroHttpHandler = (request: MaestroHttpRequest) => Promise<MaestroHttpResponse>;
|
|
781
|
+
|
|
782
|
+
interface MaestroRequestContext {
|
|
783
|
+
actor: Actor;
|
|
784
|
+
correlationId?: string;
|
|
785
|
+
}
|
|
786
|
+
type MaestroActorResolver = (request: MaestroHttpRequest) => Promise<MaestroRequestContext>;
|
|
787
|
+
interface MaestroHttpOptions {
|
|
788
|
+
actorResolver: MaestroActorResolver;
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
interface MaestroHttpHandlers {
|
|
792
|
+
list: MaestroHttpHandler;
|
|
793
|
+
findById: MaestroHttpHandler;
|
|
794
|
+
create: MaestroHttpHandler;
|
|
795
|
+
update: MaestroHttpHandler;
|
|
796
|
+
clone: MaestroHttpHandler;
|
|
797
|
+
softDelete: MaestroHttpHandler;
|
|
798
|
+
restore: MaestroHttpHandler;
|
|
799
|
+
hardDelete: MaestroHttpHandler;
|
|
800
|
+
export: MaestroHttpHandler;
|
|
801
|
+
executeOperation: MaestroHttpHandler;
|
|
802
|
+
getMetadata: MaestroHttpHandler;
|
|
803
|
+
getEntityMetadata: MaestroHttpHandler;
|
|
804
|
+
health: MaestroHttpHandler;
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
declare function parseQueryInput(query: Record<string, string | string[]>): QueryInput;
|
|
808
|
+
|
|
809
|
+
declare function createMaestroHttpHandlers(engine: MaestroEngine, options: MaestroHttpOptions): MaestroHttpHandlers;
|
|
810
|
+
|
|
811
|
+
declare function inferFieldType(nativeType: string, fieldName: string): FieldType;
|
|
812
|
+
declare function isTimestampField(fieldName: string, fieldType: FieldType): boolean;
|
|
813
|
+
declare function isSoftDeleteCandidate(fieldName: string, fieldType: FieldType, nullable: boolean): boolean;
|
|
814
|
+
declare function isSearchCandidate(fieldName: string, fieldType: FieldType, isPrimaryKey: boolean): boolean;
|
|
815
|
+
declare function tableNameToEntityId(table: string): string;
|
|
816
|
+
declare function tableNameToLabel(table: string): {
|
|
817
|
+
singular: string;
|
|
818
|
+
plural: string;
|
|
819
|
+
};
|
|
820
|
+
declare function humanizeFieldName(name: string): string;
|
|
821
|
+
declare function detectDisplayField(fields: Array<{
|
|
822
|
+
name: string;
|
|
823
|
+
type: FieldType;
|
|
824
|
+
isPrimaryKey: boolean;
|
|
825
|
+
}>): string | undefined;
|
|
826
|
+
|
|
827
|
+
interface GeneratedConfig {
|
|
828
|
+
entities: Record<string, EntitySchema>;
|
|
829
|
+
relations: Record<string, RelationSchema>;
|
|
830
|
+
}
|
|
831
|
+
declare function generateEntityConfig(entity: EntityIntrospectionSchema, datasource: string): EntitySchema;
|
|
832
|
+
declare function generateRelationConfig(relation: RelationIntrospectionSchema, entityIdByTable: Map<string, string>): RelationSchema | null;
|
|
833
|
+
declare function generateAllConfigs(result: IntrospectionResult, datasource: string): GeneratedConfig;
|
|
834
|
+
|
|
835
|
+
type ImpactLevel = 'SAFE' | 'WARNING' | 'BREAKING';
|
|
836
|
+
type EntityDiffChangeKind = 'entity_added' | 'entity_removed' | 'entity_label_changed' | 'entity_primary_key_changed';
|
|
837
|
+
type FieldDiffChangeKind = 'field_added' | 'field_removed' | 'field_type_changed' | 'field_nullable_changed' | 'field_index_added' | 'field_index_removed' | 'field_metadata_changed';
|
|
838
|
+
type RelationDiffChangeKind = 'relation_added' | 'relation_removed' | 'relation_cardinality_changed' | 'relation_fields_changed';
|
|
839
|
+
type DiffChangeKind = EntityDiffChangeKind | FieldDiffChangeKind | RelationDiffChangeKind;
|
|
840
|
+
interface EntityDiffChange {
|
|
841
|
+
category: 'entity';
|
|
842
|
+
kind: EntityDiffChangeKind;
|
|
843
|
+
impact: ImpactLevel;
|
|
844
|
+
entityTable: string;
|
|
845
|
+
previous?: unknown;
|
|
846
|
+
current?: unknown;
|
|
847
|
+
}
|
|
848
|
+
interface FieldDiffChange {
|
|
849
|
+
category: 'field';
|
|
850
|
+
kind: FieldDiffChangeKind;
|
|
851
|
+
impact: ImpactLevel;
|
|
852
|
+
entityTable: string;
|
|
853
|
+
fieldName: string;
|
|
854
|
+
previous?: unknown;
|
|
855
|
+
current?: unknown;
|
|
856
|
+
}
|
|
857
|
+
interface RelationDiffChange {
|
|
858
|
+
category: 'relation';
|
|
859
|
+
kind: RelationDiffChangeKind;
|
|
860
|
+
impact: ImpactLevel;
|
|
861
|
+
relationId: string;
|
|
862
|
+
previous?: unknown;
|
|
863
|
+
current?: unknown;
|
|
864
|
+
}
|
|
865
|
+
type DiffChange = EntityDiffChange | FieldDiffChange | RelationDiffChange;
|
|
866
|
+
interface DiffSummary {
|
|
867
|
+
total: number;
|
|
868
|
+
safe: number;
|
|
869
|
+
warnings: number;
|
|
870
|
+
breaking: number;
|
|
871
|
+
}
|
|
872
|
+
interface IntrospectionDiff {
|
|
873
|
+
changes: DiffChange[];
|
|
874
|
+
summary: DiffSummary;
|
|
875
|
+
hasBreaking: boolean;
|
|
876
|
+
hasWarnings: boolean;
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
interface DiffEngineOptions {
|
|
880
|
+
/**
|
|
881
|
+
* Optional explicit label maps (table → label) for detecting label changes
|
|
882
|
+
* across two introspection snapshots. When omitted, labels are derived
|
|
883
|
+
* from table names via tableNameToLabel — making entity_label_changed
|
|
884
|
+
* only fire when the table name itself changes its derived label.
|
|
885
|
+
*/
|
|
886
|
+
previousEntityLabels?: Map<string, string>;
|
|
887
|
+
currentEntityLabels?: Map<string, string>;
|
|
888
|
+
}
|
|
889
|
+
declare class DiffEngine {
|
|
890
|
+
compare(previous: IntrospectionResult, current: IntrospectionResult, options?: DiffEngineOptions): IntrospectionDiff;
|
|
891
|
+
private compareFields;
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
interface IntrospectionReportStats {
|
|
895
|
+
entitiesDiscovered: number;
|
|
896
|
+
relationsDiscovered: number;
|
|
897
|
+
totalChanges: number;
|
|
898
|
+
safeChanges: number;
|
|
899
|
+
warnings: number;
|
|
900
|
+
breakingChanges: number;
|
|
901
|
+
}
|
|
902
|
+
interface IntrospectionReportChange {
|
|
903
|
+
impact: ImpactLevel;
|
|
904
|
+
description: string;
|
|
905
|
+
recommendation?: string;
|
|
906
|
+
}
|
|
907
|
+
interface IntrospectionReport {
|
|
908
|
+
completedAt: string;
|
|
909
|
+
stats: IntrospectionReportStats;
|
|
910
|
+
changes: IntrospectionReportChange[];
|
|
911
|
+
hasDiff: boolean;
|
|
912
|
+
text: string;
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
declare class ReportGenerator {
|
|
916
|
+
generate(result: IntrospectionResult, diff?: IntrospectionDiff): IntrospectionReport;
|
|
917
|
+
private describeChange;
|
|
918
|
+
private generateText;
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
interface IntrospectionSnapshot {
|
|
922
|
+
id: string;
|
|
923
|
+
timestamp: string;
|
|
924
|
+
result: IntrospectionResult;
|
|
925
|
+
label?: string;
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
interface SnapshotRepository {
|
|
929
|
+
save(snapshot: IntrospectionSnapshot): Promise<void>;
|
|
930
|
+
load(id: string): Promise<IntrospectionSnapshot | null>;
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
declare class InMemorySnapshotRepository implements SnapshotRepository {
|
|
934
|
+
private readonly store;
|
|
935
|
+
save(snapshot: IntrospectionSnapshot): Promise<void>;
|
|
936
|
+
load(id: string): Promise<IntrospectionSnapshot | null>;
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
interface IntrospectionRuntimeRunOptions {
|
|
940
|
+
provider: IntrospectionProvider;
|
|
941
|
+
overrides?: LoadedConfig;
|
|
942
|
+
mergeStrategy?: MergeStrategy;
|
|
943
|
+
datasources?: Record<string, DatasourceProvider>;
|
|
944
|
+
defaultDatasource?: string;
|
|
945
|
+
/** ID of a previously saved snapshot to diff against */
|
|
946
|
+
snapshotId?: string;
|
|
947
|
+
/** Whether to automatically save the new snapshot after running. Defaults to true when a repository is configured. */
|
|
948
|
+
saveSnapshot?: boolean;
|
|
949
|
+
operations?: OperationDef[];
|
|
950
|
+
audit?: AuditRepository;
|
|
951
|
+
logger?: Logger;
|
|
952
|
+
policies?: RbacPolicy;
|
|
953
|
+
}
|
|
954
|
+
interface IntrospectionRuntimeResult {
|
|
955
|
+
metadata: MaestroMetadata;
|
|
956
|
+
diff?: IntrospectionDiff;
|
|
957
|
+
report: IntrospectionReport;
|
|
958
|
+
snapshot: IntrospectionSnapshot;
|
|
959
|
+
}
|
|
960
|
+
declare class IntrospectionRuntime {
|
|
961
|
+
private readonly snapshotRepository?;
|
|
962
|
+
private lastProvider?;
|
|
963
|
+
constructor(snapshotRepository?: SnapshotRepository | undefined);
|
|
964
|
+
run(options: IntrospectionRuntimeRunOptions): Promise<IntrospectionRuntimeResult>;
|
|
965
|
+
saveSnapshot(snapshot: IntrospectionSnapshot): Promise<void>;
|
|
966
|
+
loadSnapshot(id: string): Promise<IntrospectionSnapshot | null>;
|
|
967
|
+
compareWithSnapshot(snapshotId: string, provider?: IntrospectionProvider): Promise<IntrospectionDiff | null>;
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
export { type Actor, type ActorType, type AuditEvent, type AuditFilter, type AuditLevel, AuditRecorder, type AuditRepository, type ConfigProvider, ConsoleLogger, type ContextAction, type ContextActionCondition, type ContextActionStyle, type CreateMaestroFromIntrospectionOptions, CsvExportProvider, type CursorPagination, DEFAULT_CAPABILITIES, type DatasourceDeleteContext, type DatasourceFindContext, type DatasourceProvider, type DatasourceQueryContext, DatasourceRegistry, type DatasourceUpdateContext, type DatasourceWriteContext, type DiffChange, type DiffChangeKind, DiffEngine, type DiffEngineOptions, type DiffSummary, type DomainEvent, type EntityCapabilities, type EntityDiffChange, type EntityDiffChangeKind, type EntityExportConfig, type EntityIntrospectionSchema, type EntityLabelConfig, type EntityMetadata, type EntitySchema, type EntitySourceConfig, type EnumOption, ErrorCode, type EventBus, type EventHandler, type ExportConfig, type ExportFormat, type ExportOptions, type ExportProvider, type ExportResult, type FeatureFlag, type FeatureFlagProvider, type FieldDetailConfig, type FieldDiffChange, type FieldDiffChangeKind, type FieldFormConfig, type FieldIntrospectionSchema, type FieldListConfig, type FieldMetadata, type FieldSchema, type FieldSchemaDetailConfig, type FieldSchemaEnumOption, type FieldSchemaFormConfig, type FieldSchemaListConfig, type FieldType, type FileSystemReader, type FilterDescriptor, type FilterOperator, type GeneratedConfig, type ImpactLevel, InMemoryAuditRepository, InMemoryConfigProvider, InMemoryDatasourceProvider, InMemoryEventBus, InMemoryFeatureFlagProvider, InMemorySnapshotRepository, type IndexIntrospectionSchema, type IntrospectionDiff, type IntrospectionProvider, type IntrospectionReport, type IntrospectionReportChange, type IntrospectionReportStats, type IntrospectionResult, IntrospectionRuntime, type IntrospectionRuntimeResult, type IntrospectionRuntimeRunOptions, type IntrospectionSnapshot, type ListResult, type LoadedConfig, type LogEntry, type LogLevel, type Logger, type MaestroActorResolver, type MaestroConfig, MaestroEngine, MaestroError, type MaestroFileLoaderOptions, type MaestroHttpHandler, type MaestroHttpHandlers, type MaestroHttpOptions, type MaestroHttpRequest, type MaestroHttpResponse, type MaestroMetadata, type MaestroRequestContext, type MergeIntrospectionOptions, type MergeStrategy, type Metadata, MetadataEngine, type MetadataValue, type OffsetPagination, type OperationContext, type OperationDef, type OperationMetadata, OperationRegistry, type OperationResult, type OperationScope, type PagePagination, type PaginationInput, type Permission, type QueryInput, RbacEngine, type RbacPolicy, type RecordAuditInput, type RelationDiffChange, type RelationDiffChangeKind, type RelationDisplayConfig, type RelationEndpoint, type RelationIntrospectionSchema, type RelationMetadata, type RelationSchema, type RelationType, ReportGenerator, type ResourceRef, type Role, type SchemaValidationError, type SchemaValidationResult, type SearchConfig, type SearchInput, type SnapshotRepository, type SoftDeleteConfig, type SortDescriptor, type SortDirection, type YamlParser, createMaestro, createMaestroFromIntrospection, createMaestroHttpHandlers, detectDisplayField, generateAllConfigs, generateEntityConfig, generateRelationConfig, humanizeFieldName, inferFieldType, isSearchCandidate, isSoftDeleteCandidate, isTimestampField, loadMaestroConfig, mergeIntrospectionWithOverrides, parseQueryInput, tableNameToEntityId, tableNameToLabel, validateMaestroConfig };
|