@maykonpaulo/maestro-core 0.4.0 → 0.6.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 +69 -1
- package/dist/index.js +309 -0
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/dist/index.d.ts
CHANGED
|
@@ -1355,6 +1355,74 @@ declare function resolveConsumerProjections(consumers: ConsumerDeclaration[], me
|
|
|
1355
1355
|
declare function validateEntityDeclaration(input: unknown): SchemaValidationResult;
|
|
1356
1356
|
declare function validateConsumerDeclaration(input: unknown, entity?: EntityDeclaration): SchemaValidationResult;
|
|
1357
1357
|
|
|
1358
|
+
type DeclarativeFileFormat = 'yaml' | 'json';
|
|
1359
|
+
/**
|
|
1360
|
+
* Canonical shape of a declarative config file — structurally identical to `DeclarativeConfig`,
|
|
1361
|
+
* so it can be passed directly as `createMaestro({ declarations })`.
|
|
1362
|
+
* `entities` defaults to `[]` when the file omits it.
|
|
1363
|
+
*/
|
|
1364
|
+
interface DeclarativeFileConfig {
|
|
1365
|
+
entities: EntityDeclaration[];
|
|
1366
|
+
consumers?: ConsumerDeclaration[];
|
|
1367
|
+
}
|
|
1368
|
+
interface LoadDeclarativeConfigFromStringOptions {
|
|
1369
|
+
format: DeclarativeFileFormat;
|
|
1370
|
+
/** Required for `format: 'yaml'`. The core has no YAML runtime dependency — pass a parser (e.g. `{ parse: YAML.parse }` from the `yaml` package). */
|
|
1371
|
+
yamlParser?: YamlParser;
|
|
1372
|
+
/** Optional label (e.g. a file path) included in error messages to help pinpoint the source. */
|
|
1373
|
+
source?: string;
|
|
1374
|
+
}
|
|
1375
|
+
interface LoadDeclarativeConfigFromFileOptions {
|
|
1376
|
+
/** Overrides the format that would otherwise be detected from the file extension. */
|
|
1377
|
+
format?: DeclarativeFileFormat;
|
|
1378
|
+
yamlParser?: YamlParser;
|
|
1379
|
+
}
|
|
1380
|
+
/** Parses and validates a declarative config from textual content. Does not perform I/O. */
|
|
1381
|
+
declare function loadDeclarativeConfigFromString(content: string, options: LoadDeclarativeConfigFromStringOptions): DeclarativeFileConfig;
|
|
1382
|
+
/** Reads, parses and validates a declarative config from a file path. Format is detected from the extension unless overridden. */
|
|
1383
|
+
declare function loadDeclarativeConfigFromFile(filePath: string, options?: LoadDeclarativeConfigFromFileOptions): Promise<DeclarativeFileConfig>;
|
|
1384
|
+
|
|
1385
|
+
interface DeclarativeGeneratorOptions {
|
|
1386
|
+
/** Adds one minimal list/detail consumer per entity, derived from visible fields. Default: false. */
|
|
1387
|
+
includeConsumers?: boolean;
|
|
1388
|
+
/** Includes fields flagged as internal (hidden in metadata, or hidden: true in schema). Default: true. */
|
|
1389
|
+
includeInternalFields?: boolean;
|
|
1390
|
+
/** Sorts entities alphabetically by id and fields alphabetically by name for deterministic output. Default: true. */
|
|
1391
|
+
sort?: boolean;
|
|
1392
|
+
}
|
|
1393
|
+
/** Metadata-shaped input. Structurally compatible with `MaestroMetadata`, so it can be passed directly. */
|
|
1394
|
+
interface DeclarativeGeneratorMetadataInput {
|
|
1395
|
+
entities: EntityMetadata[];
|
|
1396
|
+
relations?: RelationMetadata[];
|
|
1397
|
+
operations?: OperationMetadata[];
|
|
1398
|
+
}
|
|
1399
|
+
/** Schema-shaped input, mirroring `MaestroConfig.entities` / `MaestroConfig.relations`. */
|
|
1400
|
+
interface DeclarativeGeneratorSchemaInput {
|
|
1401
|
+
entities: EntitySchema[];
|
|
1402
|
+
relations?: RelationSchema[];
|
|
1403
|
+
}
|
|
1404
|
+
/** Generates a `DeclarativeFileConfig` from already-built `EntityMetadata[]` (+ optional relations/operations). */
|
|
1405
|
+
declare function generateDeclarativeConfigFromMetadata(input: DeclarativeGeneratorMetadataInput, options?: DeclarativeGeneratorOptions): DeclarativeFileConfig;
|
|
1406
|
+
/** Generates a `DeclarativeFileConfig` from raw `EntitySchema[]` (+ optional relations), before metadata normalization. */
|
|
1407
|
+
declare function generateDeclarativeConfigFromSchema(input: DeclarativeGeneratorSchemaInput, options?: DeclarativeGeneratorOptions): DeclarativeFileConfig;
|
|
1408
|
+
|
|
1409
|
+
interface YamlSerializer {
|
|
1410
|
+
stringify(value: unknown): string;
|
|
1411
|
+
}
|
|
1412
|
+
|
|
1413
|
+
type DeclarativeSerializationFormat = 'yaml' | 'json';
|
|
1414
|
+
interface SerializeDeclarativeConfigOptions {
|
|
1415
|
+
format: DeclarativeSerializationFormat;
|
|
1416
|
+
/** Required for `format: 'yaml'`. The core has no YAML runtime dependency — pass a serializer (e.g. `{ stringify: YAML.stringify }` from the `yaml` package). */
|
|
1417
|
+
yamlSerializer?: YamlSerializer;
|
|
1418
|
+
}
|
|
1419
|
+
/** Serializes a declarative config to formatted, stable JSON. */
|
|
1420
|
+
declare function serializeDeclarativeConfigToJson(config: DeclarativeFileConfig): string;
|
|
1421
|
+
/** Serializes a declarative config to YAML using an injected serializer (the core has no bundled YAML dependency). */
|
|
1422
|
+
declare function serializeDeclarativeConfigToYaml(config: DeclarativeFileConfig, yamlSerializer: YamlSerializer): string;
|
|
1423
|
+
/** Serializes a declarative config to the requested textual format. */
|
|
1424
|
+
declare function serializeDeclarativeConfig(config: DeclarativeFileConfig, options: SerializeDeclarativeConfigOptions): string;
|
|
1425
|
+
|
|
1358
1426
|
declare const GOVERNANCE_EVENT_TYPES: {
|
|
1359
1427
|
readonly OPERATION_EXECUTED: "governance.operation.executed";
|
|
1360
1428
|
readonly AUTHORIZATION_DENIED: "governance.authorization.denied";
|
|
@@ -1428,4 +1496,4 @@ declare class DefaultGovernanceApi implements GovernanceApi {
|
|
|
1428
1496
|
getPolicyViolations(filter?: PolicyViolationFilter): Promise<PolicyViolation[]>;
|
|
1429
1497
|
}
|
|
1430
1498
|
|
|
1431
|
-
export { type Actor, type ActorType, type AuditEvent, type AuditFilter, type AuditLevel, type AuditRecordedPayload, AuditRecorder, type AuditRepository, type AuditTimeline, type AuthorizationContext, type AuthorizationDecision, type AuthorizationDeniedPayload, type AuthorizationProvider, type AuthorizationResult, type CompileDeclarationsOptions, type ConfigProvider, type ConfirmationApproval, type ConfirmationApprovedPayload, type ConfirmationDeclaration, ConfirmationEngine, type ConfirmationRejectedPayload, type ConfirmationRepository, type ConfirmationRequest, type ConfirmationRequestedPayload, type ConfirmationStatus, ConsoleLogger, ConsoleStructuredLogger, type ConsumerActionsConfig, type ConsumerDeclaration, type ConsumerDetailConfig, type ConsumerFormConfig, type ConsumerFormsConfig, type ConsumerListConfig, type ConsumerProjectionFields, type ConsumerProjectionOperations, type ContextAction, type ContextActionCondition, type ContextActionStyle, ContextualAuthorizationEngine, type CorrelationContext, type CorrelationId, type CreateMaestroFromIntrospectionOptions, CsvExportProvider, type CursorPagination, DEFAULT_CAPABILITIES, type DatasourceDeleteContext, type DatasourceFindContext, type DatasourceProvider, type DatasourceQueryContext, DatasourceRegistry, type DatasourceUpdateContext, type DatasourceWriteContext, type DeclarativeCompilationResult, type DeclarativeConfig, DefaultGovernanceApi, type DiffChange, type DiffChangeKind, DiffEngine, type DiffEngineOptions, type DiffSummary, type DomainEvent, type EntityCapabilities, type EntityDeclaration, type EntityDiffChange, type EntityDiffChangeKind, type EntityExportConfig, type EntityIntrospectionSchema, type EntityLabelConfig, type EntityMetadata, type EntitySchema, type EntitySourceConfig, type EnumOption, type EnumOptionDeclaration, ErrorCode, type EventBus, type EventHandler, type ExportConfig, type ExportFormat, type ExportOptions, type ExportProvider, type ExportResult, type FeatureFlag, type FeatureFlagProvider, type FieldDeclaration, 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, GOVERNANCE_EVENT_TYPES, type GeneratedConfig, type GovernanceApi, type GovernanceEventBus, type GovernanceEventType, type ImpactLevel, InMemoryAuditRepository, InMemoryConfigProvider, InMemoryConfirmationRepository, InMemoryDatasourceProvider, InMemoryEventBus, InMemoryFeatureFlagProvider, InMemoryGovernanceEventBus, InMemoryPolicyProvider, 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, MetadataRiskClassifier, type MetadataValue, type OffsetPagination, type OperationContext, type OperationDeclaration, type OperationDef, type OperationExecutedPayload, type OperationLogStatus, type OperationMetadata, OperationRegistry, type OperationResult, type OperationScope, type OperationalRisk, type PagePagination, type PaginationInput, type Permission, type PolicyContext, type PolicyDecision, PolicyEngine, type PolicyEvaluationResult, type PolicyProvider, type PolicyRule, type PolicyRuleResult, type PolicyTriggeredPayload, type PolicyViolation, type PolicyViolationFilter, type QueryInput, RbacEngine, type RbacPolicy, type RecordAuditInput, type RelationDeclaration, type RelationDiffChange, type RelationDiffChangeKind, type RelationDisplayConfig, type RelationEndpoint, type RelationIntrospectionSchema, type RelationMetadata, type RelationSchema, type RelationType, ReportGenerator, type RequestConfirmationInput, type ResolvedConsumerProjection, type ResourceRef, type RiskClassificationInput, type RiskClassifier, type Role, type SchemaValidationError, type SchemaValidationResult, type SearchConfig, type SearchInput, type SnapshotRepository, type SoftDeleteConfig, type SortDescriptor, type SortDirection, type StructuredLogEntry, type StructuredLogger, type YamlParser, compileDeclarations, createMaestro, createMaestroFromIntrospection, createMaestroHttpHandlers, detectDisplayField, generateAllConfigs, generateCorrelationId, generateEntityConfig, generateRelationConfig, humanizeFieldName, inferFieldType, isSearchCandidate, isSoftDeleteCandidate, isTimestampField, loadMaestroConfig, mergeIntrospectionWithOverrides, parseQueryInput, resolveConsumerProjections, tableNameToEntityId, tableNameToLabel, validateConsumerDeclaration, validateEntityDeclaration, validateMaestroConfig };
|
|
1499
|
+
export { type Actor, type ActorType, type AuditEvent, type AuditFilter, type AuditLevel, type AuditRecordedPayload, AuditRecorder, type AuditRepository, type AuditTimeline, type AuthorizationContext, type AuthorizationDecision, type AuthorizationDeniedPayload, type AuthorizationProvider, type AuthorizationResult, type CompileDeclarationsOptions, type ConfigProvider, type ConfirmationApproval, type ConfirmationApprovedPayload, type ConfirmationDeclaration, ConfirmationEngine, type ConfirmationRejectedPayload, type ConfirmationRepository, type ConfirmationRequest, type ConfirmationRequestedPayload, type ConfirmationStatus, ConsoleLogger, ConsoleStructuredLogger, type ConsumerActionsConfig, type ConsumerDeclaration, type ConsumerDetailConfig, type ConsumerFormConfig, type ConsumerFormsConfig, type ConsumerListConfig, type ConsumerProjectionFields, type ConsumerProjectionOperations, type ContextAction, type ContextActionCondition, type ContextActionStyle, ContextualAuthorizationEngine, type CorrelationContext, type CorrelationId, type CreateMaestroFromIntrospectionOptions, CsvExportProvider, type CursorPagination, DEFAULT_CAPABILITIES, type DatasourceDeleteContext, type DatasourceFindContext, type DatasourceProvider, type DatasourceQueryContext, DatasourceRegistry, type DatasourceUpdateContext, type DatasourceWriteContext, type DeclarativeCompilationResult, type DeclarativeConfig, type DeclarativeFileConfig, type DeclarativeFileFormat, type DeclarativeGeneratorMetadataInput, type DeclarativeGeneratorOptions, type DeclarativeGeneratorSchemaInput, type DeclarativeSerializationFormat, DefaultGovernanceApi, type DiffChange, type DiffChangeKind, DiffEngine, type DiffEngineOptions, type DiffSummary, type DomainEvent, type EntityCapabilities, type EntityDeclaration, type EntityDiffChange, type EntityDiffChangeKind, type EntityExportConfig, type EntityIntrospectionSchema, type EntityLabelConfig, type EntityMetadata, type EntitySchema, type EntitySourceConfig, type EnumOption, type EnumOptionDeclaration, ErrorCode, type EventBus, type EventHandler, type ExportConfig, type ExportFormat, type ExportOptions, type ExportProvider, type ExportResult, type FeatureFlag, type FeatureFlagProvider, type FieldDeclaration, 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, GOVERNANCE_EVENT_TYPES, type GeneratedConfig, type GovernanceApi, type GovernanceEventBus, type GovernanceEventType, type ImpactLevel, InMemoryAuditRepository, InMemoryConfigProvider, InMemoryConfirmationRepository, InMemoryDatasourceProvider, InMemoryEventBus, InMemoryFeatureFlagProvider, InMemoryGovernanceEventBus, InMemoryPolicyProvider, 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 LoadDeclarativeConfigFromFileOptions, type LoadDeclarativeConfigFromStringOptions, 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, MetadataRiskClassifier, type MetadataValue, type OffsetPagination, type OperationContext, type OperationDeclaration, type OperationDef, type OperationExecutedPayload, type OperationLogStatus, type OperationMetadata, OperationRegistry, type OperationResult, type OperationScope, type OperationalRisk, type PagePagination, type PaginationInput, type Permission, type PolicyContext, type PolicyDecision, PolicyEngine, type PolicyEvaluationResult, type PolicyProvider, type PolicyRule, type PolicyRuleResult, type PolicyTriggeredPayload, type PolicyViolation, type PolicyViolationFilter, type QueryInput, RbacEngine, type RbacPolicy, type RecordAuditInput, type RelationDeclaration, type RelationDiffChange, type RelationDiffChangeKind, type RelationDisplayConfig, type RelationEndpoint, type RelationIntrospectionSchema, type RelationMetadata, type RelationSchema, type RelationType, ReportGenerator, type RequestConfirmationInput, type ResolvedConsumerProjection, type ResourceRef, type RiskClassificationInput, type RiskClassifier, type Role, type SchemaValidationError, type SchemaValidationResult, type SearchConfig, type SearchInput, type SerializeDeclarativeConfigOptions, type SnapshotRepository, type SoftDeleteConfig, type SortDescriptor, type SortDirection, type StructuredLogEntry, type StructuredLogger, type YamlParser, type YamlSerializer, compileDeclarations, createMaestro, createMaestroFromIntrospection, createMaestroHttpHandlers, detectDisplayField, generateAllConfigs, generateCorrelationId, generateDeclarativeConfigFromMetadata, generateDeclarativeConfigFromSchema, generateEntityConfig, generateRelationConfig, humanizeFieldName, inferFieldType, isSearchCandidate, isSoftDeleteCandidate, isTimestampField, loadDeclarativeConfigFromFile, loadDeclarativeConfigFromString, loadMaestroConfig, mergeIntrospectionWithOverrides, parseQueryInput, resolveConsumerProjections, serializeDeclarativeConfig, serializeDeclarativeConfigToJson, serializeDeclarativeConfigToYaml, tableNameToEntityId, tableNameToLabel, validateConsumerDeclaration, validateEntityDeclaration, validateMaestroConfig };
|
package/dist/index.js
CHANGED
|
@@ -3292,6 +3292,308 @@ var InMemoryConfirmationRepository = class {
|
|
|
3292
3292
|
}
|
|
3293
3293
|
};
|
|
3294
3294
|
|
|
3295
|
+
// src/declarative/loader/DeclarativeFileLoader.ts
|
|
3296
|
+
import { readFile as readFile2 } from "fs/promises";
|
|
3297
|
+
import { extname as extname2 } from "path";
|
|
3298
|
+
var KNOWN_KEYS = /* @__PURE__ */ new Set(["entities", "consumers"]);
|
|
3299
|
+
function parseContent2(content, format, yamlParser, source) {
|
|
3300
|
+
const origin = source ? ` (${source})` : "";
|
|
3301
|
+
if (format === "yaml") {
|
|
3302
|
+
if (!yamlParser) {
|
|
3303
|
+
throw new MaestroError(
|
|
3304
|
+
"CONFIGURATION_ERROR" /* CONFIGURATION_ERROR */,
|
|
3305
|
+
`Cannot parse YAML declarative config${origin}: a "yamlParser" must be provided. The core has no bundled YAML dependency \u2014 install a YAML library (e.g. "yaml") and pass { yamlParser: { parse: YAML.parse } }.`
|
|
3306
|
+
);
|
|
3307
|
+
}
|
|
3308
|
+
try {
|
|
3309
|
+
return yamlParser.parse(content);
|
|
3310
|
+
} catch (cause) {
|
|
3311
|
+
throw new MaestroError(
|
|
3312
|
+
"CONFIGURATION_ERROR" /* CONFIGURATION_ERROR */,
|
|
3313
|
+
`Failed to parse YAML declarative config${origin}: ${cause.message}`,
|
|
3314
|
+
{ cause }
|
|
3315
|
+
);
|
|
3316
|
+
}
|
|
3317
|
+
}
|
|
3318
|
+
try {
|
|
3319
|
+
return JSON.parse(content);
|
|
3320
|
+
} catch (cause) {
|
|
3321
|
+
throw new MaestroError(
|
|
3322
|
+
"CONFIGURATION_ERROR" /* CONFIGURATION_ERROR */,
|
|
3323
|
+
`Failed to parse JSON declarative config${origin}: ${cause.message}`,
|
|
3324
|
+
{ cause }
|
|
3325
|
+
);
|
|
3326
|
+
}
|
|
3327
|
+
}
|
|
3328
|
+
function normalizeAndValidate(raw, source) {
|
|
3329
|
+
const origin = source ? ` in ${source}` : "";
|
|
3330
|
+
if (raw === null || raw === void 0) {
|
|
3331
|
+
return { entities: [] };
|
|
3332
|
+
}
|
|
3333
|
+
if (typeof raw !== "object" || Array.isArray(raw)) {
|
|
3334
|
+
throw new MaestroError(
|
|
3335
|
+
"CONFIGURATION_ERROR" /* CONFIGURATION_ERROR */,
|
|
3336
|
+
`Declarative config${origin} must be an object with optional "entities" and "consumers" arrays.`
|
|
3337
|
+
);
|
|
3338
|
+
}
|
|
3339
|
+
const obj = raw;
|
|
3340
|
+
const errors = [];
|
|
3341
|
+
for (const key of Object.keys(obj)) {
|
|
3342
|
+
if (!KNOWN_KEYS.has(key)) {
|
|
3343
|
+
errors.push({
|
|
3344
|
+
path: key,
|
|
3345
|
+
message: `Unknown declarative config key "${key}". Only "entities" and "consumers" are supported.`
|
|
3346
|
+
});
|
|
3347
|
+
}
|
|
3348
|
+
}
|
|
3349
|
+
let entities;
|
|
3350
|
+
if (obj["entities"] !== void 0) {
|
|
3351
|
+
if (!Array.isArray(obj["entities"])) {
|
|
3352
|
+
errors.push({ path: "entities", message: '"entities" must be an array of entity declarations.' });
|
|
3353
|
+
} else {
|
|
3354
|
+
entities = obj["entities"];
|
|
3355
|
+
entities.forEach((entity, index) => {
|
|
3356
|
+
const result = validateEntityDeclaration(entity);
|
|
3357
|
+
if (!result.valid) {
|
|
3358
|
+
for (const err of result.errors) {
|
|
3359
|
+
const path = err.path ? `entities[${index}].${err.path}` : `entities[${index}]`;
|
|
3360
|
+
errors.push({ path, message: err.message });
|
|
3361
|
+
}
|
|
3362
|
+
}
|
|
3363
|
+
});
|
|
3364
|
+
}
|
|
3365
|
+
}
|
|
3366
|
+
let consumers;
|
|
3367
|
+
if (obj["consumers"] !== void 0) {
|
|
3368
|
+
if (!Array.isArray(obj["consumers"])) {
|
|
3369
|
+
errors.push({ path: "consumers", message: '"consumers" must be an array of consumer declarations.' });
|
|
3370
|
+
} else {
|
|
3371
|
+
consumers = obj["consumers"];
|
|
3372
|
+
const entityByName = new Map((entities ?? []).map((entity) => [entity.entity, entity]));
|
|
3373
|
+
consumers.forEach((consumer, index) => {
|
|
3374
|
+
const relatedEntity = consumer && typeof consumer === "object" ? entityByName.get(consumer["entity"]) : void 0;
|
|
3375
|
+
const result = validateConsumerDeclaration(consumer, relatedEntity);
|
|
3376
|
+
if (!result.valid) {
|
|
3377
|
+
for (const err of result.errors) {
|
|
3378
|
+
const path = err.path ? `consumers[${index}].${err.path}` : `consumers[${index}]`;
|
|
3379
|
+
errors.push({ path, message: err.message });
|
|
3380
|
+
}
|
|
3381
|
+
}
|
|
3382
|
+
});
|
|
3383
|
+
}
|
|
3384
|
+
}
|
|
3385
|
+
if (errors.length > 0) {
|
|
3386
|
+
const details = errors.map((err) => `${err.path}: ${err.message}`).join("; ");
|
|
3387
|
+
throw new MaestroError(
|
|
3388
|
+
"VALIDATION_ERROR" /* VALIDATION_ERROR */,
|
|
3389
|
+
`Invalid declarative config${origin}: ${details}`,
|
|
3390
|
+
{ details: { errors } }
|
|
3391
|
+
);
|
|
3392
|
+
}
|
|
3393
|
+
return { entities: entities ?? [], consumers };
|
|
3394
|
+
}
|
|
3395
|
+
function loadDeclarativeConfigFromString(content, options) {
|
|
3396
|
+
const raw = parseContent2(content, options.format, options.yamlParser, options.source);
|
|
3397
|
+
return normalizeAndValidate(raw, options.source);
|
|
3398
|
+
}
|
|
3399
|
+
function detectFormatFromExtension(filePath) {
|
|
3400
|
+
const ext = extname2(filePath).toLowerCase();
|
|
3401
|
+
if (ext === ".yaml" || ext === ".yml") return "yaml";
|
|
3402
|
+
if (ext === ".json") return "json";
|
|
3403
|
+
throw new MaestroError(
|
|
3404
|
+
"CONFIGURATION_ERROR" /* CONFIGURATION_ERROR */,
|
|
3405
|
+
`Cannot detect declarative config format from file extension "${ext}" (${filePath}). Supported extensions: .yaml, .yml, .json. Pass { format } explicitly to override.`
|
|
3406
|
+
);
|
|
3407
|
+
}
|
|
3408
|
+
async function loadDeclarativeConfigFromFile(filePath, options = {}) {
|
|
3409
|
+
const format = options.format ?? detectFormatFromExtension(filePath);
|
|
3410
|
+
const content = await readFile2(filePath, "utf-8");
|
|
3411
|
+
return loadDeclarativeConfigFromString(content, { format, yamlParser: options.yamlParser, source: filePath });
|
|
3412
|
+
}
|
|
3413
|
+
|
|
3414
|
+
// src/declarative/generator/DeclarativeConfigGenerator.ts
|
|
3415
|
+
function sortByName(items) {
|
|
3416
|
+
return [...items].sort((a, b) => a.name.localeCompare(b.name));
|
|
3417
|
+
}
|
|
3418
|
+
function capabilitiesOverride(capabilities) {
|
|
3419
|
+
const overrides = {};
|
|
3420
|
+
let hasOverride = false;
|
|
3421
|
+
for (const key of Object.keys(DEFAULT_CAPABILITIES)) {
|
|
3422
|
+
if (capabilities[key] !== DEFAULT_CAPABILITIES[key]) {
|
|
3423
|
+
overrides[key] = capabilities[key];
|
|
3424
|
+
hasOverride = true;
|
|
3425
|
+
}
|
|
3426
|
+
}
|
|
3427
|
+
return hasOverride ? overrides : void 0;
|
|
3428
|
+
}
|
|
3429
|
+
function relationToDeclaration(rel) {
|
|
3430
|
+
return {
|
|
3431
|
+
id: rel.id,
|
|
3432
|
+
type: rel.type,
|
|
3433
|
+
fromField: rel.from.field,
|
|
3434
|
+
toEntity: rel.to.entity,
|
|
3435
|
+
toField: rel.to.field,
|
|
3436
|
+
label: rel.label,
|
|
3437
|
+
display: rel.display ? { tab: rel.display.tab, label: rel.display.label } : void 0
|
|
3438
|
+
};
|
|
3439
|
+
}
|
|
3440
|
+
function fieldMetadataToDeclaration(field, primaryKey) {
|
|
3441
|
+
const decl = { type: field.type };
|
|
3442
|
+
if (field.label) decl.label = field.label;
|
|
3443
|
+
if (field.required) decl.required = true;
|
|
3444
|
+
if (field.readonly) decl.readonly = true;
|
|
3445
|
+
if (field.name === primaryKey) decl.primary = true;
|
|
3446
|
+
if (field.sensitive) decl.sensitive = true;
|
|
3447
|
+
if (field.hidden) decl.visible = false;
|
|
3448
|
+
if (field.searchable) decl.searchable = true;
|
|
3449
|
+
if (field.sortable) decl.sortable = true;
|
|
3450
|
+
if (field.filterable) decl.filterable = true;
|
|
3451
|
+
if (field.exportable) decl.exportable = true;
|
|
3452
|
+
if (field.description) decl.description = field.description;
|
|
3453
|
+
if (field.enumOptions) decl.enumOptions = field.enumOptions;
|
|
3454
|
+
if (field.relationEntity) decl.relationEntity = field.relationEntity;
|
|
3455
|
+
return decl;
|
|
3456
|
+
}
|
|
3457
|
+
function fieldSchemaToDeclaration(field, primaryKey) {
|
|
3458
|
+
const decl = { type: field.type };
|
|
3459
|
+
if (field.label) decl.label = field.label;
|
|
3460
|
+
if (field.required) decl.required = true;
|
|
3461
|
+
if (field.readonly) decl.readonly = true;
|
|
3462
|
+
if (primaryKey && field.name === primaryKey) decl.primary = true;
|
|
3463
|
+
if (field.sensitive) decl.sensitive = true;
|
|
3464
|
+
if (field.hidden) decl.visible = false;
|
|
3465
|
+
if (field.searchable) decl.searchable = true;
|
|
3466
|
+
if (field.sortable) decl.sortable = true;
|
|
3467
|
+
if (field.filterable) decl.filterable = true;
|
|
3468
|
+
if (field.exportable) decl.exportable = true;
|
|
3469
|
+
if (field.description) decl.description = field.description;
|
|
3470
|
+
if (field.enumOptions) decl.enumOptions = field.enumOptions;
|
|
3471
|
+
if (field.relationEntity) decl.relationEntity = field.relationEntity;
|
|
3472
|
+
return decl;
|
|
3473
|
+
}
|
|
3474
|
+
function operationMetadataToDeclaration(op, entityId) {
|
|
3475
|
+
const key = op.id.startsWith(`${entityId}.`) ? op.id.slice(entityId.length + 1) : op.id;
|
|
3476
|
+
const declaration = { label: op.label };
|
|
3477
|
+
if (op.description) declaration.description = op.description;
|
|
3478
|
+
if (op.scope) declaration.scope = op.scope;
|
|
3479
|
+
if (op.requiresConfirmation) declaration.confirmation = { required: true };
|
|
3480
|
+
if (op.requiredPermission) declaration.permission = op.requiredPermission;
|
|
3481
|
+
return { key, declaration };
|
|
3482
|
+
}
|
|
3483
|
+
function entityMetadataToDeclaration(entity, relations, operations, options) {
|
|
3484
|
+
const sourceFields = options.includeInternalFields ? entity.fields : entity.fields.filter((f) => !f.hidden);
|
|
3485
|
+
const orderedFields = options.sort ? sortByName(sourceFields) : sourceFields;
|
|
3486
|
+
const fields = {};
|
|
3487
|
+
for (const field of orderedFields) {
|
|
3488
|
+
fields[field.name] = fieldMetadataToDeclaration(field, entity.primaryKey);
|
|
3489
|
+
}
|
|
3490
|
+
const orderedRelations = options.sort ? [...relations].sort((a, b) => a.id.localeCompare(b.id)) : relations;
|
|
3491
|
+
const orderedOperations = options.sort ? [...operations].sort((a, b) => a.id.localeCompare(b.id)) : operations;
|
|
3492
|
+
const operationsRecord = {};
|
|
3493
|
+
for (const op of orderedOperations) {
|
|
3494
|
+
const { key, declaration: declaration2 } = operationMetadataToDeclaration(op, entity.id);
|
|
3495
|
+
operationsRecord[key] = declaration2;
|
|
3496
|
+
}
|
|
3497
|
+
const declaration = {
|
|
3498
|
+
entity: entity.id,
|
|
3499
|
+
label: entity.label.singular,
|
|
3500
|
+
pluralLabel: entity.label.plural,
|
|
3501
|
+
fields
|
|
3502
|
+
};
|
|
3503
|
+
if (entity.description) declaration.description = entity.description;
|
|
3504
|
+
const capabilities = capabilitiesOverride(entity.capabilities);
|
|
3505
|
+
if (capabilities) declaration.capabilities = capabilities;
|
|
3506
|
+
if (orderedOperations.length > 0) declaration.operations = operationsRecord;
|
|
3507
|
+
if (orderedRelations.length > 0) {
|
|
3508
|
+
declaration.relationships = orderedRelations.map(relationToDeclaration);
|
|
3509
|
+
}
|
|
3510
|
+
return declaration;
|
|
3511
|
+
}
|
|
3512
|
+
function entitySchemaToDeclaration(entity, relations, options) {
|
|
3513
|
+
const sourceFields = options.includeInternalFields ? entity.fields : entity.fields.filter((f) => !f.hidden);
|
|
3514
|
+
const orderedFields = options.sort ? sortByName(sourceFields) : sourceFields;
|
|
3515
|
+
const fields = {};
|
|
3516
|
+
for (const field of orderedFields) {
|
|
3517
|
+
fields[field.name] = fieldSchemaToDeclaration(field, entity.source.primaryKey);
|
|
3518
|
+
}
|
|
3519
|
+
const orderedRelations = options.sort ? [...relations].sort((a, b) => a.id.localeCompare(b.id)) : relations;
|
|
3520
|
+
const declaration = {
|
|
3521
|
+
entity: entity.id,
|
|
3522
|
+
label: entity.label.singular,
|
|
3523
|
+
pluralLabel: entity.label.plural,
|
|
3524
|
+
fields
|
|
3525
|
+
};
|
|
3526
|
+
if (entity.description) declaration.description = entity.description;
|
|
3527
|
+
if (entity.capabilities) declaration.capabilities = entity.capabilities;
|
|
3528
|
+
if (orderedRelations.length > 0) {
|
|
3529
|
+
declaration.relationships = orderedRelations.map(relationToDeclaration);
|
|
3530
|
+
}
|
|
3531
|
+
return declaration;
|
|
3532
|
+
}
|
|
3533
|
+
function generateDefaultConsumerDeclaration(entity) {
|
|
3534
|
+
const visibleFieldNames = Object.entries(entity.fields).filter(([, field]) => field.visible !== false).map(([name]) => name);
|
|
3535
|
+
return {
|
|
3536
|
+
consumer: entity.entity,
|
|
3537
|
+
entity: entity.entity,
|
|
3538
|
+
list: { fields: visibleFieldNames },
|
|
3539
|
+
detail: { fields: visibleFieldNames }
|
|
3540
|
+
};
|
|
3541
|
+
}
|
|
3542
|
+
function generateDeclarativeConfigFromMetadata(input, options = {}) {
|
|
3543
|
+
const resolved = {
|
|
3544
|
+
includeInternalFields: options.includeInternalFields ?? true,
|
|
3545
|
+
sort: options.sort ?? true
|
|
3546
|
+
};
|
|
3547
|
+
const orderedEntities = resolved.sort ? [...input.entities].sort((a, b) => a.id.localeCompare(b.id)) : input.entities;
|
|
3548
|
+
const entities = orderedEntities.map(
|
|
3549
|
+
(entity) => entityMetadataToDeclaration(
|
|
3550
|
+
entity,
|
|
3551
|
+
(input.relations ?? []).filter((rel) => rel.from.entity === entity.id),
|
|
3552
|
+
(input.operations ?? []).filter((op) => op.entity === entity.id),
|
|
3553
|
+
resolved
|
|
3554
|
+
)
|
|
3555
|
+
);
|
|
3556
|
+
const consumers = options.includeConsumers ? entities.map(generateDefaultConsumerDeclaration) : void 0;
|
|
3557
|
+
return consumers ? { entities, consumers } : { entities };
|
|
3558
|
+
}
|
|
3559
|
+
function generateDeclarativeConfigFromSchema(input, options = {}) {
|
|
3560
|
+
const resolved = {
|
|
3561
|
+
includeInternalFields: options.includeInternalFields ?? true,
|
|
3562
|
+
sort: options.sort ?? true
|
|
3563
|
+
};
|
|
3564
|
+
const orderedEntities = resolved.sort ? [...input.entities].sort((a, b) => a.id.localeCompare(b.id)) : input.entities;
|
|
3565
|
+
const entities = orderedEntities.map(
|
|
3566
|
+
(entity) => entitySchemaToDeclaration(
|
|
3567
|
+
entity,
|
|
3568
|
+
(input.relations ?? []).filter((rel) => rel.from.entity === entity.id),
|
|
3569
|
+
resolved
|
|
3570
|
+
)
|
|
3571
|
+
);
|
|
3572
|
+
const consumers = options.includeConsumers ? entities.map(generateDefaultConsumerDeclaration) : void 0;
|
|
3573
|
+
return consumers ? { entities, consumers } : { entities };
|
|
3574
|
+
}
|
|
3575
|
+
|
|
3576
|
+
// src/declarative/generator/DeclarativeConfigSerializer.ts
|
|
3577
|
+
function serializeDeclarativeConfigToJson(config) {
|
|
3578
|
+
return `${JSON.stringify(config, null, 2)}
|
|
3579
|
+
`;
|
|
3580
|
+
}
|
|
3581
|
+
function serializeDeclarativeConfigToYaml(config, yamlSerializer) {
|
|
3582
|
+
return yamlSerializer.stringify(config);
|
|
3583
|
+
}
|
|
3584
|
+
function serializeDeclarativeConfig(config, options) {
|
|
3585
|
+
if (options.format === "json") {
|
|
3586
|
+
return serializeDeclarativeConfigToJson(config);
|
|
3587
|
+
}
|
|
3588
|
+
if (!options.yamlSerializer) {
|
|
3589
|
+
throw new MaestroError(
|
|
3590
|
+
"CONFIGURATION_ERROR" /* CONFIGURATION_ERROR */,
|
|
3591
|
+
'Cannot serialize declarative config to YAML: a "yamlSerializer" must be provided. The core has no bundled YAML dependency \u2014 install a YAML library (e.g. "yaml") and pass { yamlSerializer: { stringify: YAML.stringify } }.'
|
|
3592
|
+
);
|
|
3593
|
+
}
|
|
3594
|
+
return serializeDeclarativeConfigToYaml(config, options.yamlSerializer);
|
|
3595
|
+
}
|
|
3596
|
+
|
|
3295
3597
|
// src/governance/GovernanceEventType.ts
|
|
3296
3598
|
var GOVERNANCE_EVENT_TYPES = {
|
|
3297
3599
|
OPERATION_EXECUTED: "governance.operation.executed",
|
|
@@ -3395,6 +3697,8 @@ export {
|
|
|
3395
3697
|
detectDisplayField,
|
|
3396
3698
|
generateAllConfigs,
|
|
3397
3699
|
generateCorrelationId,
|
|
3700
|
+
generateDeclarativeConfigFromMetadata,
|
|
3701
|
+
generateDeclarativeConfigFromSchema,
|
|
3398
3702
|
generateEntityConfig,
|
|
3399
3703
|
generateRelationConfig,
|
|
3400
3704
|
humanizeFieldName,
|
|
@@ -3402,10 +3706,15 @@ export {
|
|
|
3402
3706
|
isSearchCandidate,
|
|
3403
3707
|
isSoftDeleteCandidate,
|
|
3404
3708
|
isTimestampField,
|
|
3709
|
+
loadDeclarativeConfigFromFile,
|
|
3710
|
+
loadDeclarativeConfigFromString,
|
|
3405
3711
|
loadMaestroConfig,
|
|
3406
3712
|
mergeIntrospectionWithOverrides,
|
|
3407
3713
|
parseQueryInput,
|
|
3408
3714
|
resolveConsumerProjections,
|
|
3715
|
+
serializeDeclarativeConfig,
|
|
3716
|
+
serializeDeclarativeConfigToJson,
|
|
3717
|
+
serializeDeclarativeConfigToYaml,
|
|
3409
3718
|
tableNameToEntityId,
|
|
3410
3719
|
tableNameToLabel,
|
|
3411
3720
|
validateConsumerDeclaration,
|