@maykonpaulo/maestro-core 0.2.0 → 0.2.1
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 +29 -6
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -77,11 +77,34 @@ Todas as exportações estão documentadas em `src/index.ts`. Importe apenas pel
|
|
|
77
77
|
import { ... } from '@maykonpaulo/maestro-core';
|
|
78
78
|
```
|
|
79
79
|
|
|
80
|
-
##
|
|
80
|
+
## Extensão com adapters próprios
|
|
81
81
|
|
|
82
|
-
|
|
83
|
-
- **Sem provider remoto de feature flags** — `InMemoryFeatureFlagProvider` não suporta avaliação por actor com regras complexas.
|
|
84
|
-
- **Sem adapter de logging externo** — `ConsoleLogger` escreve em `console.*`. Para produção, implementar um adapter que envie para seu stack de observabilidade.
|
|
85
|
-
- **Sem autenticação** — o `RbacEngine` avalia autorização com base no `Actor` recebido. Autenticação é responsabilidade do consumer.
|
|
82
|
+
O Maestro expõe contratos bem definidos para cada módulo. Implemente a interface correspondente para integrar com qualquer banco, serviço ou infraestrutura:
|
|
86
83
|
|
|
87
|
-
|
|
84
|
+
| Interface | Implementar quando quiser... |
|
|
85
|
+
|----------------------|-------------------------------------------------------|
|
|
86
|
+
| `AuditRepository` | Persistir eventos de auditoria em banco de dados |
|
|
87
|
+
| `FeatureFlagProvider`| Gerenciar flags via banco, Redis ou serviço externo |
|
|
88
|
+
| `ConfigProvider` | Carregar configurações de variáveis de ambiente ou DB |
|
|
89
|
+
| `EventBus` | Publicar eventos em filas (RabbitMQ, SQS, etc.) |
|
|
90
|
+
| `Logger` | Enviar logs para Pino, Winston, Datadog, etc. |
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
import type { AuditRepository, AuditEvent, AuditFilter } from '@maykonpaulo/maestro-core';
|
|
94
|
+
import { AuditRecorder } from '@maykonpaulo/maestro-core';
|
|
95
|
+
|
|
96
|
+
// Sua implementação concreta — qualquer banco, qualquer ORM
|
|
97
|
+
class PrismaAuditRepository implements AuditRepository {
|
|
98
|
+
async record(event: AuditEvent): Promise<void> {
|
|
99
|
+
await db.auditEvent.create({ data: event });
|
|
100
|
+
}
|
|
101
|
+
async list(filter?: AuditFilter): Promise<AuditEvent[]> {
|
|
102
|
+
return db.auditEvent.findMany({ where: filter });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Injeta no AuditRecorder — o core não sabe nem se importa com o banco
|
|
107
|
+
const audit = new AuditRecorder(new PrismaAuditRepository());
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
As implementações `InMemory*` incluídas no pacote são funcionais para testes e desenvolvimento local.
|
package/dist/index.js
CHANGED
|
@@ -52,6 +52,7 @@ var ConsoleLogger = class {
|
|
|
52
52
|
log(level, entry) {
|
|
53
53
|
if (LOG_LEVEL_PRIORITY[level] < LOG_LEVEL_PRIORITY[this.minLevel]) return;
|
|
54
54
|
const output = {
|
|
55
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
55
56
|
level,
|
|
56
57
|
message: entry.message,
|
|
57
58
|
...entry.correlationId && { correlationId: entry.correlationId },
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors/ErrorCode.ts","../src/errors/MaestroError.ts","../src/logging/LogLevel.ts","../src/logging/ConsoleLogger.ts","../src/audit/InMemoryAuditRepository.ts","../src/audit/AuditRecorder.ts","../src/rbac/RbacEngine.ts","../src/feature-flags/InMemoryFeatureFlagProvider.ts","../src/config/InMemoryConfigProvider.ts","../src/events/InMemoryEventBus.ts"],"sourcesContent":["export enum ErrorCode {\n VALIDATION_ERROR = 'VALIDATION_ERROR',\n PERMISSION_DENIED = 'PERMISSION_DENIED',\n NOT_FOUND = 'NOT_FOUND',\n CONFLICT = 'CONFLICT',\n INTERNAL_ERROR = 'INTERNAL_ERROR',\n CONFIGURATION_ERROR = 'CONFIGURATION_ERROR',\n}\n","import type { Metadata } from '../types/index.js';\nimport type { ErrorCode } from './ErrorCode.js';\n\nexport class MaestroError extends Error {\n readonly code: ErrorCode;\n readonly details?: Metadata;\n override readonly cause?: unknown;\n\n constructor(\n code: ErrorCode,\n message: string,\n options?: { details?: Metadata; cause?: unknown },\n ) {\n super(message, { cause: options?.cause });\n this.code = code;\n this.details = options?.details;\n this.cause = options?.cause;\n this.name = 'MaestroError';\n }\n}\n","export type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\nexport const LOG_LEVEL_PRIORITY: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n};\n","import type { Logger, LogEntry } from './Logger.js';\nimport type { LogLevel } from './LogLevel.js';\nimport { LOG_LEVEL_PRIORITY } from './LogLevel.js';\n\nexport class ConsoleLogger implements Logger {\n constructor(private readonly minLevel: LogLevel = 'info') {}\n\n debug(entry: LogEntry): void {\n this.log('debug', entry);\n }\n\n info(entry: LogEntry): void {\n this.log('info', entry);\n }\n\n warn(entry: LogEntry): void {\n this.log('warn', entry);\n }\n\n error(entry: LogEntry): void {\n this.log('error', entry);\n }\n\n private log(level: LogLevel, entry: LogEntry): void {\n if (LOG_LEVEL_PRIORITY[level] < LOG_LEVEL_PRIORITY[this.minLevel]) return;\n\n const output = {\n level,\n message: entry.message,\n ...(entry.correlationId && { correlationId: entry.correlationId }),\n ...(entry.metadata && { metadata: entry.metadata }),\n ...(entry.error !== undefined && { error: this.serializeError(entry.error) }),\n };\n\n const consoleFn = level === 'error' ? console.error\n : level === 'warn' ? console.warn\n : level === 'debug' ? console.debug\n : console.info;\n\n consoleFn(JSON.stringify(output));\n }\n\n private serializeError(error: unknown): unknown {\n if (error instanceof Error) {\n return { name: error.name, message: error.message };\n }\n return error;\n }\n}\n","import type { AuditRepository, AuditFilter } from './AuditRepository.js';\nimport type { AuditEvent } from './AuditEvent.js';\n\nexport class InMemoryAuditRepository implements AuditRepository {\n private readonly store = new Map<string, AuditEvent>();\n\n async record(event: AuditEvent): Promise<void> {\n this.store.set(event.id, event);\n }\n\n async list(filter?: AuditFilter): Promise<AuditEvent[]> {\n let events = Array.from(this.store.values());\n\n if (!filter) return events;\n\n if (filter.actorId !== undefined) {\n events = events.filter((e) => e.actor.id === filter.actorId);\n }\n if (filter.action !== undefined) {\n events = events.filter((e) => e.action === filter.action);\n }\n if (filter.resourceType !== undefined) {\n events = events.filter((e) => e.resource?.type === filter.resourceType);\n }\n if (filter.resourceId !== undefined) {\n events = events.filter((e) => e.resource?.id === filter.resourceId);\n }\n if (filter.level !== undefined) {\n events = events.filter((e) => e.level === filter.level);\n }\n if (filter.from !== undefined) {\n const from = filter.from;\n events = events.filter((e) => e.timestamp >= from);\n }\n if (filter.to !== undefined) {\n const to = filter.to;\n events = events.filter((e) => e.timestamp <= to);\n }\n if (filter.correlationId !== undefined) {\n events = events.filter((e) => e.correlationId === filter.correlationId);\n }\n\n return events;\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport type { AuditRepository } from './AuditRepository.js';\nimport type { AuditEvent } from './AuditEvent.js';\nimport type { AuditLevel } from './AuditLevel.js';\nimport type { Actor, ResourceRef, Metadata } from '../types/index.js';\n\nexport interface RecordAuditInput {\n action: string;\n actor: Actor;\n level?: AuditLevel;\n resource?: ResourceRef;\n before?: Metadata;\n after?: Metadata;\n metadata?: Metadata;\n correlationId?: string;\n requestId?: string;\n ip?: string;\n userAgent?: string;\n}\n\nexport class AuditRecorder {\n constructor(private readonly repository: AuditRepository) {}\n\n async record(input: RecordAuditInput): Promise<AuditEvent> {\n const event: AuditEvent = {\n id: randomUUID(),\n timestamp: new Date(),\n action: input.action,\n actor: input.actor,\n level: input.level ?? 'info',\n resource: input.resource,\n before: input.before,\n after: input.after,\n metadata: input.metadata,\n correlationId: input.correlationId,\n requestId: input.requestId,\n ip: input.ip,\n userAgent: input.userAgent,\n };\n\n await this.repository.record(event);\n return event;\n }\n}\n","import type { Actor } from '../types/index.js';\nimport type { RbacPolicy } from './RbacPolicy.js';\n\nexport class RbacEngine {\n constructor(private readonly policy: RbacPolicy) {}\n\n can(actor: Actor, permission: string): boolean {\n const permissions = this.resolvePermissions(actor);\n return permissions.some((p) => this.matchesPattern(p, permission));\n }\n\n private resolvePermissions(actor: Actor): string[] {\n const direct = actor.permissions ?? [];\n const fromRoles = (actor.roles ?? []).flatMap((roleName) => {\n const role = this.policy.roles[roleName];\n return role?.permissions ?? [];\n });\n return [...direct, ...fromRoles];\n }\n\n private matchesPattern(pattern: string, target: string): boolean {\n if (pattern === '*') return true;\n if (pattern === target) return true;\n if (pattern.endsWith('.*')) {\n const prefix = pattern.slice(0, -2);\n return target === prefix || target.startsWith(`${prefix}.`);\n }\n return false;\n }\n}\n","import type { FeatureFlagProvider } from './FeatureFlagProvider.js';\nimport type { FeatureFlag } from './FeatureFlag.js';\nimport type { Actor } from '../types/index.js';\n\nexport class InMemoryFeatureFlagProvider implements FeatureFlagProvider {\n private readonly flags = new Map<string, FeatureFlag>();\n\n constructor(flags: FeatureFlag[] = []) {\n for (const flag of flags) {\n this.flags.set(flag.key, flag);\n }\n }\n\n async isEnabled(key: string, _actor?: Actor): Promise<boolean> {\n return this.flags.get(key)?.enabled ?? false;\n }\n\n get(key: string): FeatureFlag | undefined {\n return this.flags.get(key);\n }\n\n set(flag: FeatureFlag): void {\n this.flags.set(flag.key, flag);\n }\n\n list(): FeatureFlag[] {\n return Array.from(this.flags.values());\n }\n}\n","import type { ConfigProvider } from './ConfigProvider.js';\nimport type { MetadataValue } from '../types/index.js';\n\nexport class InMemoryConfigProvider implements ConfigProvider {\n private readonly store = new Map<string, MetadataValue>();\n\n constructor(initial: Record<string, MetadataValue> = {}) {\n for (const [key, value] of Object.entries(initial)) {\n this.store.set(key, value);\n }\n }\n\n get<T extends MetadataValue>(key: string): T | undefined {\n return this.store.get(key) as T | undefined;\n }\n\n set<T extends MetadataValue>(key: string, value: T): void {\n this.store.set(key, value);\n }\n\n has(key: string): boolean {\n return this.store.has(key);\n }\n\n getOrDefault<T extends MetadataValue>(key: string, defaultValue: T): T {\n const value = this.store.get(key);\n return value !== undefined ? (value as T) : defaultValue;\n }\n}\n","import type { EventBus, EventHandler } from './EventBus.js';\nimport type { DomainEvent } from './DomainEvent.js';\n\nexport class InMemoryEventBus implements EventBus {\n private readonly handlers = new Map<string, Set<EventHandler>>();\n\n async publish<TPayload>(event: DomainEvent<TPayload>): Promise<void> {\n const set = this.handlers.get(event.type);\n if (!set) return;\n\n const promises = Array.from(set).map((handler) =>\n Promise.resolve(handler(event as DomainEvent<unknown>)),\n );\n await Promise.all(promises);\n }\n\n subscribe<TPayload>(eventType: string, handler: EventHandler<TPayload>): void {\n if (!this.handlers.has(eventType)) {\n this.handlers.set(eventType, new Set());\n }\n this.handlers.get(eventType)!.add(handler as EventHandler);\n }\n\n unsubscribe<TPayload>(eventType: string, handler: EventHandler<TPayload>): void {\n this.handlers.get(eventType)?.delete(handler as EventHandler);\n }\n}\n"],"mappings":"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","names":["ErrorCode"]}
|
|
1
|
+
{"version":3,"sources":["../src/errors/ErrorCode.ts","../src/errors/MaestroError.ts","../src/logging/LogLevel.ts","../src/logging/ConsoleLogger.ts","../src/audit/InMemoryAuditRepository.ts","../src/audit/AuditRecorder.ts","../src/rbac/RbacEngine.ts","../src/feature-flags/InMemoryFeatureFlagProvider.ts","../src/config/InMemoryConfigProvider.ts","../src/events/InMemoryEventBus.ts"],"sourcesContent":["export enum ErrorCode {\n VALIDATION_ERROR = 'VALIDATION_ERROR',\n PERMISSION_DENIED = 'PERMISSION_DENIED',\n NOT_FOUND = 'NOT_FOUND',\n CONFLICT = 'CONFLICT',\n INTERNAL_ERROR = 'INTERNAL_ERROR',\n CONFIGURATION_ERROR = 'CONFIGURATION_ERROR',\n}\n","import type { Metadata } from '../types/index.js';\nimport type { ErrorCode } from './ErrorCode.js';\n\nexport class MaestroError extends Error {\n readonly code: ErrorCode;\n readonly details?: Metadata;\n override readonly cause?: unknown;\n\n constructor(\n code: ErrorCode,\n message: string,\n options?: { details?: Metadata; cause?: unknown },\n ) {\n super(message, { cause: options?.cause });\n this.code = code;\n this.details = options?.details;\n this.cause = options?.cause;\n this.name = 'MaestroError';\n }\n}\n","export type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\nexport const LOG_LEVEL_PRIORITY: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n};\n","import type { Logger, LogEntry } from './Logger.js';\nimport type { LogLevel } from './LogLevel.js';\nimport { LOG_LEVEL_PRIORITY } from './LogLevel.js';\n\nexport class ConsoleLogger implements Logger {\n constructor(private readonly minLevel: LogLevel = 'info') {}\n\n debug(entry: LogEntry): void {\n this.log('debug', entry);\n }\n\n info(entry: LogEntry): void {\n this.log('info', entry);\n }\n\n warn(entry: LogEntry): void {\n this.log('warn', entry);\n }\n\n error(entry: LogEntry): void {\n this.log('error', entry);\n }\n\n private log(level: LogLevel, entry: LogEntry): void {\n if (LOG_LEVEL_PRIORITY[level] < LOG_LEVEL_PRIORITY[this.minLevel]) return;\n\n const output = {\n timestamp: new Date().toISOString(),\n level,\n message: entry.message,\n ...(entry.correlationId && { correlationId: entry.correlationId }),\n ...(entry.metadata && { metadata: entry.metadata }),\n ...(entry.error !== undefined && { error: this.serializeError(entry.error) }),\n };\n\n const consoleFn = level === 'error' ? console.error\n : level === 'warn' ? console.warn\n : level === 'debug' ? console.debug\n : console.info;\n\n consoleFn(JSON.stringify(output));\n }\n\n private serializeError(error: unknown): unknown {\n if (error instanceof Error) {\n return { name: error.name, message: error.message };\n }\n return error;\n }\n}\n","import type { AuditRepository, AuditFilter } from './AuditRepository.js';\nimport type { AuditEvent } from './AuditEvent.js';\n\nexport class InMemoryAuditRepository implements AuditRepository {\n private readonly store = new Map<string, AuditEvent>();\n\n async record(event: AuditEvent): Promise<void> {\n this.store.set(event.id, event);\n }\n\n async list(filter?: AuditFilter): Promise<AuditEvent[]> {\n let events = Array.from(this.store.values());\n\n if (!filter) return events;\n\n if (filter.actorId !== undefined) {\n events = events.filter((e) => e.actor.id === filter.actorId);\n }\n if (filter.action !== undefined) {\n events = events.filter((e) => e.action === filter.action);\n }\n if (filter.resourceType !== undefined) {\n events = events.filter((e) => e.resource?.type === filter.resourceType);\n }\n if (filter.resourceId !== undefined) {\n events = events.filter((e) => e.resource?.id === filter.resourceId);\n }\n if (filter.level !== undefined) {\n events = events.filter((e) => e.level === filter.level);\n }\n if (filter.from !== undefined) {\n const from = filter.from;\n events = events.filter((e) => e.timestamp >= from);\n }\n if (filter.to !== undefined) {\n const to = filter.to;\n events = events.filter((e) => e.timestamp <= to);\n }\n if (filter.correlationId !== undefined) {\n events = events.filter((e) => e.correlationId === filter.correlationId);\n }\n\n return events;\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport type { AuditRepository } from './AuditRepository.js';\nimport type { AuditEvent } from './AuditEvent.js';\nimport type { AuditLevel } from './AuditLevel.js';\nimport type { Actor, ResourceRef, Metadata } from '../types/index.js';\n\nexport interface RecordAuditInput {\n action: string;\n actor: Actor;\n level?: AuditLevel;\n resource?: ResourceRef;\n before?: Metadata;\n after?: Metadata;\n metadata?: Metadata;\n correlationId?: string;\n requestId?: string;\n ip?: string;\n userAgent?: string;\n}\n\nexport class AuditRecorder {\n constructor(private readonly repository: AuditRepository) {}\n\n async record(input: RecordAuditInput): Promise<AuditEvent> {\n const event: AuditEvent = {\n id: randomUUID(),\n timestamp: new Date(),\n action: input.action,\n actor: input.actor,\n level: input.level ?? 'info',\n resource: input.resource,\n before: input.before,\n after: input.after,\n metadata: input.metadata,\n correlationId: input.correlationId,\n requestId: input.requestId,\n ip: input.ip,\n userAgent: input.userAgent,\n };\n\n await this.repository.record(event);\n return event;\n }\n}\n","import type { Actor } from '../types/index.js';\nimport type { RbacPolicy } from './RbacPolicy.js';\n\nexport class RbacEngine {\n constructor(private readonly policy: RbacPolicy) {}\n\n can(actor: Actor, permission: string): boolean {\n const permissions = this.resolvePermissions(actor);\n return permissions.some((p) => this.matchesPattern(p, permission));\n }\n\n private resolvePermissions(actor: Actor): string[] {\n const direct = actor.permissions ?? [];\n const fromRoles = (actor.roles ?? []).flatMap((roleName) => {\n const role = this.policy.roles[roleName];\n return role?.permissions ?? [];\n });\n return [...direct, ...fromRoles];\n }\n\n private matchesPattern(pattern: string, target: string): boolean {\n if (pattern === '*') return true;\n if (pattern === target) return true;\n if (pattern.endsWith('.*')) {\n const prefix = pattern.slice(0, -2);\n return target === prefix || target.startsWith(`${prefix}.`);\n }\n return false;\n }\n}\n","import type { FeatureFlagProvider } from './FeatureFlagProvider.js';\nimport type { FeatureFlag } from './FeatureFlag.js';\nimport type { Actor } from '../types/index.js';\n\nexport class InMemoryFeatureFlagProvider implements FeatureFlagProvider {\n private readonly flags = new Map<string, FeatureFlag>();\n\n constructor(flags: FeatureFlag[] = []) {\n for (const flag of flags) {\n this.flags.set(flag.key, flag);\n }\n }\n\n async isEnabled(key: string, _actor?: Actor): Promise<boolean> {\n return this.flags.get(key)?.enabled ?? false;\n }\n\n get(key: string): FeatureFlag | undefined {\n return this.flags.get(key);\n }\n\n set(flag: FeatureFlag): void {\n this.flags.set(flag.key, flag);\n }\n\n list(): FeatureFlag[] {\n return Array.from(this.flags.values());\n }\n}\n","import type { ConfigProvider } from './ConfigProvider.js';\nimport type { MetadataValue } from '../types/index.js';\n\nexport class InMemoryConfigProvider implements ConfigProvider {\n private readonly store = new Map<string, MetadataValue>();\n\n constructor(initial: Record<string, MetadataValue> = {}) {\n for (const [key, value] of Object.entries(initial)) {\n this.store.set(key, value);\n }\n }\n\n get<T extends MetadataValue>(key: string): T | undefined {\n return this.store.get(key) as T | undefined;\n }\n\n set<T extends MetadataValue>(key: string, value: T): void {\n this.store.set(key, value);\n }\n\n has(key: string): boolean {\n return this.store.has(key);\n }\n\n getOrDefault<T extends MetadataValue>(key: string, defaultValue: T): T {\n const value = this.store.get(key);\n return value !== undefined ? (value as T) : defaultValue;\n }\n}\n","import type { EventBus, EventHandler } from './EventBus.js';\nimport type { DomainEvent } from './DomainEvent.js';\n\nexport class InMemoryEventBus implements EventBus {\n private readonly handlers = new Map<string, Set<EventHandler>>();\n\n async publish<TPayload>(event: DomainEvent<TPayload>): Promise<void> {\n const set = this.handlers.get(event.type);\n if (!set) return;\n\n const promises = Array.from(set).map((handler) =>\n Promise.resolve(handler(event as DomainEvent<unknown>)),\n );\n await Promise.all(promises);\n }\n\n subscribe<TPayload>(eventType: string, handler: EventHandler<TPayload>): void {\n if (!this.handlers.has(eventType)) {\n this.handlers.set(eventType, new Set());\n }\n this.handlers.get(eventType)!.add(handler as EventHandler);\n }\n\n unsubscribe<TPayload>(eventType: string, handler: EventHandler<TPayload>): void {\n this.handlers.get(eventType)?.delete(handler as EventHandler);\n }\n}\n"],"mappings":"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","names":["ErrorCode"]}
|