@atlas-id/contracts 0.1.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/LICENSE ADDED
@@ -0,0 +1,28 @@
1
+ Copyright (c) 2024 Opendex, Inc.
2
+
3
+ All rights reserved.
4
+
5
+ This software and associated documentation files (the "Software") are the
6
+ proprietary and confidential property of Opendex, Inc. ("Opendex").
7
+
8
+ The Software is protected by copyright laws and international copyright
9
+ treaties, as well as other intellectual property laws and treaties.
10
+
11
+ No part of this Software may be reproduced, distributed, transmitted,
12
+ displayed, published, or broadcast in any form or by any means, including
13
+ but not limited to electronic, mechanical, photocopying, recording, or
14
+ otherwise, without the prior written permission of Opendex.
15
+
16
+ Unauthorized copying, modification, distribution, or use of this Software,
17
+ via any medium, is strictly prohibited and may result in severe civil and
18
+ criminal penalties, and will be prosecuted to the maximum extent possible
19
+ under the law.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24
+ OPENDEX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
25
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
+
28
+ For licensing inquiries, please contact: legal@opendex.com
package/README.md ADDED
@@ -0,0 +1,289 @@
1
+ # Atlas ID Contracts
2
+
3
+ Biblioteca de contratos TypeScript compartidos para el ecosistema de servicios de Atlas ID. Define los tipos, estructuras de datos y contratos de eventos utilizados para la comunicación entre servicios en arquitecturas distribuidas.
4
+
5
+ **Propiedad de Opendex, Inc.** - Este software es propietario y no es de código abierto.
6
+
7
+ ## Función Principal
8
+
9
+ Este paquete proporciona contratos tipados y versionados que garantizan la consistencia y compatibilidad entre los diferentes servicios del sistema IAM. Actúa como la fuente única de verdad para:
10
+
11
+ - Definiciones de tipos TypeScript para eventos, notificaciones y conexiones OAuth
12
+ - Contratos de eventos con versionado semántico
13
+ - Esquemas de validación en runtime
14
+ - Utilidades de validación y type guards
15
+
16
+ ## Arquitectura
17
+
18
+ El proyecto está organizado en módulos especializados:
19
+
20
+ ### Eventos
21
+
22
+ Define la estructura base para eventos en sistemas distribuidos con soporte para:
23
+ - Versionado semántico de contratos
24
+ - Metadata de trazabilidad (traceId, spanId, correlationId, causationId)
25
+ - Soporte para multi-tenancy (tenantId, projectId)
26
+ - Identificación de origen (source)
27
+
28
+ ### Notificaciones
29
+
30
+ Contratos para el sistema de notificaciones que soporta múltiples canales:
31
+ - Email con soporte para templates, variables, CC, BCC y reply-to
32
+ - SMS con templates y variables
33
+ - Webhooks con versionado de firmas y payloads personalizados
34
+
35
+ Incluye estados del ciclo de vida: requested, scheduled, dispatched, delivered, failed, cancelled.
36
+
37
+ ### Conexiones OAuth
38
+
39
+ Contratos para gestión de conexiones OAuth con soporte para:
40
+ - Múltiples protocolos: OAuth2, OIDC, SAML
41
+ - Gestión de tokens (access, refresh, ID tokens)
42
+ - Estados de conexión: active, refreshing, revoked, expired
43
+ - Soporte para PKCE y webhooks de refresh
44
+
45
+ ### Versionado
46
+
47
+ Utilidades para trabajar con versionado semántico:
48
+ - Validación de formato de versiones
49
+ - Parsing y comparación de versiones
50
+ - Funciones de comparación (mayor que, menor que, igual)
51
+
52
+ ## Uso
53
+
54
+ ### Instalación
55
+
56
+ ```bash
57
+ pnpm add @atlas-id/contracts
58
+ ```
59
+
60
+ ### Importación de Tipos
61
+
62
+ ```typescript
63
+ import type {
64
+ EventEnvelope,
65
+ NotificationRequest,
66
+ OAuthConnection,
67
+ SemanticVersion,
68
+ } from '@atlas-id/contracts';
69
+ ```
70
+
71
+ ### Uso de Contratos de Eventos
72
+
73
+ ```typescript
74
+ import { notificationEvents } from '@atlas-id/contracts';
75
+
76
+ // El contrato incluye el tipo, versión, schema y un ejemplo
77
+ const event = {
78
+ ...notificationEvents.requested.example,
79
+ id: 'evt_custom_123',
80
+ occurredAt: new Date().toISOString(),
81
+ payload: {
82
+ notification: {
83
+ // ... datos de la notificación
84
+ },
85
+ },
86
+ };
87
+ ```
88
+
89
+ ### Validación en Runtime
90
+
91
+ ```typescript
92
+ import {
93
+ notificationRequestSchema,
94
+ createEventEnvelopeSchema,
95
+ } from '@atlas-id/contracts';
96
+
97
+ // Validar una solicitud de notificación
98
+ const result = notificationRequestSchema.safeParse(requestData);
99
+ if (result.success) {
100
+ // requestData es válido
101
+ } else {
102
+ // result.error contiene los errores de validación
103
+ }
104
+ ```
105
+
106
+ ### Type Guards
107
+
108
+ ```typescript
109
+ import {
110
+ isEmailNotificationRequest,
111
+ isSmsNotificationRequest,
112
+ isWebhookNotificationRequest,
113
+ } from '@atlas-id/contracts';
114
+
115
+ function processNotification(request: NotificationRequest) {
116
+ if (isEmailNotificationRequest(request)) {
117
+ // TypeScript sabe que request es EmailNotificationRequest
118
+ console.log(request.to);
119
+ } else if (isSmsNotificationRequest(request)) {
120
+ // TypeScript sabe que request es SmsNotificationRequest
121
+ console.log(request.to);
122
+ }
123
+ }
124
+ ```
125
+
126
+ ### Utilidades de Validación
127
+
128
+ ```typescript
129
+ import {
130
+ isValidUuid,
131
+ isValidEmail,
132
+ isValidUrl,
133
+ isValidE164Phone,
134
+ isValidIso8601,
135
+ } from '@atlas-id/contracts';
136
+
137
+ if (isValidUuid(userId)) {
138
+ // userId es un UUID válido
139
+ }
140
+
141
+ if (isValidEmail(email)) {
142
+ // email tiene formato válido
143
+ }
144
+ ```
145
+
146
+ ### Versionado Semántico
147
+
148
+ ```typescript
149
+ import {
150
+ isValidSemanticVersion,
151
+ parseSemanticVersion,
152
+ compareSemanticVersions,
153
+ isVersionGreaterThan,
154
+ } from '@atlas-id/contracts';
155
+
156
+ if (isValidSemanticVersion('1.2.3')) {
157
+ const parsed = parseSemanticVersion('1.2.3');
158
+ // { major: 1, minor: 2, patch: 3 }
159
+ }
160
+
161
+ if (isVersionGreaterThan('2.0.0', '1.9.9')) {
162
+ // La versión 2.0.0 es mayor que 1.9.9
163
+ }
164
+ ```
165
+
166
+ ## Estructura de Contratos
167
+
168
+ Cada contrato de evento sigue la estructura:
169
+
170
+ ```typescript
171
+ {
172
+ type: string; // Tipo del evento (ej: 'notifications.requested')
173
+ version: SemanticVersion; // Versión semántica del contrato
174
+ schema: string; // Identificador del schema (tipo@version)
175
+ example: EventEnvelope; // Ejemplo completo del evento
176
+ }
177
+ ```
178
+
179
+ Los eventos incluyen metadata de trazabilidad:
180
+
181
+ ```typescript
182
+ {
183
+ traceId?: string; // ID de traza para distributed tracing
184
+ spanId?: string; // ID de span dentro de la traza
185
+ correlationId?: string; // ID para correlacionar eventos relacionados
186
+ causationId?: string; // ID del evento que causó este evento
187
+ tenantId?: string; // ID del tenant (multi-tenancy)
188
+ projectId?: string; // ID del proyecto
189
+ source: string; // Servicio que originó el evento
190
+ }
191
+ ```
192
+
193
+ ## Validación
194
+
195
+ El paquete proporciona validación en dos niveles:
196
+
197
+ 1. **Compilación**: TypeScript valida los tipos en tiempo de compilación
198
+ 2. **Runtime**: Zod valida los datos en tiempo de ejecución
199
+
200
+ Los esquemas de Zod están disponibles para validar:
201
+ - Event envelopes
202
+ - Notification requests
203
+ - OAuth connections
204
+ - Token sets
205
+ - Versiones semánticas
206
+
207
+ ## Constantes
208
+
209
+ Los tipos de eventos están centralizados en constantes para evitar errores de tipeo:
210
+
211
+ ```typescript
212
+ import {
213
+ NOTIFICATION_EVENT_TYPES,
214
+ OAUTH_CONNECTION_EVENT_TYPES,
215
+ } from '@atlas-id/contracts';
216
+
217
+ // En lugar de 'notifications.requested'
218
+ const eventType = NOTIFICATION_EVENT_TYPES.REQUESTED;
219
+ ```
220
+
221
+ ## Desarrollo
222
+
223
+ ### Scripts Disponibles
224
+
225
+ - `pnpm build`: Compila el proyecto TypeScript
226
+ - `pnpm typecheck`: Valida tipos sin compilar
227
+ - `pnpm test`: Ejecuta tests unitarios
228
+ - `pnpm test:watch`: Ejecuta tests en modo watch
229
+ - `pnpm test:coverage`: Genera reporte de cobertura
230
+ - `pnpm lint`: Ejecuta ESLint
231
+ - `pnpm lint:fix`: Ejecuta ESLint y corrige errores automáticamente
232
+ - `pnpm clean`: Limpia directorios de build y node_modules
233
+
234
+ ### Estructura del Proyecto
235
+
236
+ ```
237
+ src/
238
+ events.ts # Tipos y contratos base de eventos
239
+ notifications.ts # Contratos de notificaciones
240
+ oauth-connections.ts # Contratos de conexiones OAuth
241
+ versioning.ts # Utilidades de versionado semántico
242
+ utils/
243
+ validation.ts # Utilidades de validación
244
+ schemas/
245
+ index.ts # Esquemas Zod para validación runtime
246
+ *.test.ts # Tests unitarios
247
+ ```
248
+
249
+ ### Tests
250
+
251
+ Los tests validan:
252
+ - Funcionalidad de utilidades de versionado
253
+ - Type guards y discriminación de tipos
254
+ - Validación de formatos (UUID, email, URL, etc.)
255
+ - Estructura y validez de ejemplos en contratos
256
+ - Esquemas de validación Zod
257
+
258
+ ### Contribución
259
+
260
+ Al agregar nuevos contratos o modificar existentes:
261
+
262
+ 1. Actualizar los tipos TypeScript
263
+ 2. Agregar documentación JSDoc
264
+ 3. Crear o actualizar esquemas Zod
265
+ 4. Agregar ejemplos en los contratos
266
+ 5. Escribir tests unitarios
267
+ 6. Actualizar el CHANGELOG.md
268
+
269
+ Los cambios que modifiquen la estructura de contratos existentes deben incrementar la versión semántica del contrato afectado.
270
+
271
+ ## Compatibilidad
272
+
273
+ - Node.js: 18+
274
+ - TypeScript: 5.3+
275
+ - ESM y CommonJS soportados
276
+
277
+ ## Propiedad y Licencia
278
+
279
+ Copyright (c) 2024 Opendex, Inc. Todos los derechos reservados.
280
+
281
+ Este software es propiedad exclusiva de Opendex, Inc. y no es de código abierto.
282
+ Está protegido por leyes de derechos de autor y otras leyes de propiedad intelectual.
283
+
284
+ El uso, reproducción, distribución o modificación de este software sin el
285
+ consentimiento escrito previo de Opendex, Inc. está estrictamente prohibido.
286
+
287
+ Para consultas sobre licencias, contactar: legal@opendex.com
288
+
289
+ Ver archivo LICENSE para más detalles.
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "@atlas-id/contracts",
3
+ "version": "0.1.0",
4
+ "license": "UNLICENSED",
5
+ "author": "Opendex, Inc.",
6
+ "type": "module",
7
+ "types": "./dist/index.d.ts",
8
+ "scripts": {
9
+ "build": "rimraf dist && tsup-node",
10
+ "typecheck": "tsc --noEmit",
11
+ "test": "vitest run",
12
+ "test:watch": "vitest watch",
13
+ "test:coverage": "vitest run --coverage",
14
+ "lint": "eslint --ext .ts .",
15
+ "lint:fix": "eslint --ext .ts . --fix",
16
+ "clean": "rimraf dist && rimraf node_modules",
17
+ "prebuild": "pnpm typecheck && pnpm lint && pnpm test"
18
+ },
19
+ "files": [
20
+ "dist",
21
+ "src",
22
+ "README.md",
23
+ "LICENSE"
24
+ ],
25
+ "exports": {
26
+ ".": {
27
+ "types": "./dist/index.d.ts",
28
+ "require": {
29
+ "default": "./dist/index.js"
30
+ },
31
+ "default": "./dist/esm/index.js"
32
+ },
33
+ "./dist/*": {
34
+ "types": "./dist/*.d.ts",
35
+ "require": {
36
+ "default": "./dist/*.js"
37
+ },
38
+ "default": "./dist/esm/*.js"
39
+ }
40
+ },
41
+ "peerDependencies": {},
42
+ "dependencies": {
43
+ "zod": "^3.23.8"
44
+ },
45
+ "devDependencies": {
46
+ "@typescript-eslint/eslint-plugin": "^7.18.0",
47
+ "@typescript-eslint/parser": "^7.18.0",
48
+ "@vitest/coverage-v8": "^4.0.16",
49
+ "eslint": "^8.57.1",
50
+ "husky": "^9.0.11",
51
+ "rimraf": "^6.1.2",
52
+ "tsup": "^8.5.1",
53
+ "typescript": "5.3.3",
54
+ "vitest": "^4.0.16"
55
+ }
56
+ }
@@ -0,0 +1,136 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { z } from 'zod';
3
+ import { notificationEvents } from './notifications';
4
+ import { oauthConnectionEvents } from './oauth-connections';
5
+ import { isValidSemanticVersion } from './versioning';
6
+ import {
7
+ createEventEnvelopeSchema,
8
+ notificationRequestSchema,
9
+ oauthConnectionSchema,
10
+ tokenSetSchema,
11
+ } from './schemas';
12
+
13
+ describe('contracts validation', () => {
14
+ describe('notificationEvents examples', () => {
15
+ it('debe validar el ejemplo de requested event', () => {
16
+ const contract = notificationEvents.requested;
17
+ const example = contract.example;
18
+
19
+ expect(isValidSemanticVersion(example.version)).toBe(true);
20
+ expect(example.type).toBe('notifications.requested');
21
+ expect(contract.schema).toBe('notifications.requested@1.0.0');
22
+ expect(example.meta.source).toBeDefined();
23
+
24
+ // Type guard para acceder a las propiedades específicas
25
+ if ('notification' in example.payload) {
26
+ expect(example.payload.notification).toBeDefined();
27
+ expect(example.payload.notification.request.channel).toBe('email');
28
+ }
29
+ });
30
+
31
+ it('debe validar el ejemplo de dispatched event', () => {
32
+ const example = notificationEvents.dispatched.example;
33
+
34
+ expect(isValidSemanticVersion(example.version)).toBe(true);
35
+ expect(example.type).toBe('notifications.dispatched');
36
+
37
+ if ('notificationId' in example.payload && 'channel' in example.payload && 'provider' in example.payload) {
38
+ expect(example.payload.notificationId).toBeDefined();
39
+ expect(example.payload.channel).toBeDefined();
40
+ expect(example.payload.provider).toBeDefined();
41
+ }
42
+ });
43
+
44
+ it('debe validar el ejemplo de delivered event', () => {
45
+ const example = notificationEvents.delivered.example;
46
+
47
+ expect(isValidSemanticVersion(example.version)).toBe(true);
48
+ expect(example.type).toBe('notifications.delivered');
49
+
50
+ if ('notificationId' in example.payload && 'deliveredAt' in example.payload) {
51
+ expect(example.payload.notificationId).toBeDefined();
52
+ expect(example.payload.deliveredAt).toBeDefined();
53
+ }
54
+ });
55
+
56
+ it('debe validar el ejemplo de failed event', () => {
57
+ const example = notificationEvents.failed.example;
58
+
59
+ expect(isValidSemanticVersion(example.version)).toBe(true);
60
+ expect(example.type).toBe('notifications.failed');
61
+
62
+ if ('notificationId' in example.payload && 'errorCode' in example.payload) {
63
+ expect(example.payload.notificationId).toBeDefined();
64
+ expect(example.payload.errorCode).toBeDefined();
65
+ expect(example.payload.retriable).toBeDefined();
66
+ }
67
+ });
68
+
69
+ it('los ejemplos deben pasar validación con Zod', () => {
70
+ const requestedPayloadSchema = z.object({
71
+ notification: z.object({
72
+ id: z.string(),
73
+ request: notificationRequestSchema,
74
+ status: z.string(),
75
+ createdAt: z.string(),
76
+ updatedAt: z.string(),
77
+ }),
78
+ });
79
+
80
+ const requestedEnvelopeSchema = createEventEnvelopeSchema(requestedPayloadSchema);
81
+
82
+ const result = requestedEnvelopeSchema.safeParse(notificationEvents.requested.example);
83
+ expect(result.success).toBe(true);
84
+ });
85
+ });
86
+
87
+ describe('oauthConnectionEvents examples', () => {
88
+ it('debe validar el ejemplo de linked event', () => {
89
+ const example = oauthConnectionEvents.linked.example;
90
+
91
+ expect(isValidSemanticVersion(example.version)).toBe(true);
92
+ expect(example.type).toBe('oauth.connection.linked');
93
+
94
+ if ('connection' in example.payload && 'tokenSet' in example.payload) {
95
+ expect(example.payload.connection).toBeDefined();
96
+ expect(example.payload.tokenSet).toBeDefined();
97
+ }
98
+ });
99
+
100
+ it('debe validar el ejemplo de tokenRefreshed event', () => {
101
+ const example = oauthConnectionEvents.tokenRefreshed.example;
102
+
103
+ expect(isValidSemanticVersion(example.version)).toBe(true);
104
+ expect(example.type).toBe('oauth.connection.token_refreshed');
105
+
106
+ if ('connectionId' in example.payload && 'tokenSet' in example.payload) {
107
+ expect(example.payload.connectionId).toBeDefined();
108
+ expect(example.payload.tokenSet).toBeDefined();
109
+ }
110
+ });
111
+
112
+ it('debe validar el ejemplo de revoked event', () => {
113
+ const example = oauthConnectionEvents.revoked.example;
114
+
115
+ expect(isValidSemanticVersion(example.version)).toBe(true);
116
+ expect(example.type).toBe('oauth.connection.revoked');
117
+
118
+ if ('connectionId' in example.payload && 'reason' in example.payload) {
119
+ expect(example.payload.connectionId).toBeDefined();
120
+ expect(example.payload.reason).toBeDefined();
121
+ }
122
+ });
123
+
124
+ it('los ejemplos deben pasar validación con Zod', () => {
125
+ const linkedPayloadSchema = z.object({
126
+ connection: oauthConnectionSchema,
127
+ tokenSet: tokenSetSchema,
128
+ });
129
+
130
+ const linkedEnvelopeSchema = createEventEnvelopeSchema(linkedPayloadSchema);
131
+
132
+ const result = linkedEnvelopeSchema.safeParse(oauthConnectionEvents.linked.example);
133
+ expect(result.success).toBe(true);
134
+ });
135
+ });
136
+ });
@@ -0,0 +1,48 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import {
3
+ NOTIFICATION_EVENT_TYPES,
4
+ OAUTH_CONNECTION_EVENT_TYPES,
5
+ type EventEnvelope,
6
+ type EventMeta,
7
+ } from './events';
8
+
9
+ describe('events', () => {
10
+ describe('constants', () => {
11
+ it('NOTIFICATION_EVENT_TYPES debe tener todos los tipos', () => {
12
+ expect(NOTIFICATION_EVENT_TYPES.REQUESTED).toBe('notifications.requested');
13
+ expect(NOTIFICATION_EVENT_TYPES.DISPATCHED).toBe('notifications.dispatched');
14
+ expect(NOTIFICATION_EVENT_TYPES.DELIVERED).toBe('notifications.delivered');
15
+ expect(NOTIFICATION_EVENT_TYPES.FAILED).toBe('notifications.failed');
16
+ });
17
+
18
+ it('OAUTH_CONNECTION_EVENT_TYPES debe tener todos los tipos', () => {
19
+ expect(OAUTH_CONNECTION_EVENT_TYPES.LINKED).toBe('oauth.connection.linked');
20
+ expect(OAUTH_CONNECTION_EVENT_TYPES.TOKEN_REFRESHED).toBe('oauth.connection.token_refreshed');
21
+ expect(OAUTH_CONNECTION_EVENT_TYPES.REVOKED).toBe('oauth.connection.revoked');
22
+ });
23
+ });
24
+
25
+ describe('EventEnvelope', () => {
26
+ it('debe crear un envelope válido', () => {
27
+ const meta: EventMeta = {
28
+ source: 'test-service',
29
+ traceId: 'trace_123',
30
+ };
31
+
32
+ const envelope: EventEnvelope<{ data: string }> = {
33
+ id: 'evt_123',
34
+ type: 'test.event',
35
+ version: '1.0.0',
36
+ occurredAt: new Date().toISOString(),
37
+ payload: { data: 'test' },
38
+ meta,
39
+ };
40
+
41
+ expect(envelope.id).toBe('evt_123');
42
+ expect(envelope.type).toBe('test.event');
43
+ expect(envelope.version).toBe('1.0.0');
44
+ expect(envelope.payload.data).toBe('test');
45
+ expect(envelope.meta.source).toBe('test-service');
46
+ });
47
+ });
48
+ });
package/src/events.ts ADDED
@@ -0,0 +1,85 @@
1
+ import { SemanticVersion } from './versioning';
2
+
3
+ /**
4
+ * Constantes para tipos de eventos del sistema de notificaciones.
5
+ * Centraliza los nombres de eventos para evitar errores de tipeo.
6
+ */
7
+ export const NOTIFICATION_EVENT_TYPES = {
8
+ REQUESTED: 'notifications.requested',
9
+ DISPATCHED: 'notifications.dispatched',
10
+ DELIVERED: 'notifications.delivered',
11
+ FAILED: 'notifications.failed',
12
+ } as const;
13
+
14
+ /**
15
+ * Constantes para tipos de eventos de conexiones OAuth.
16
+ */
17
+ export const OAUTH_CONNECTION_EVENT_TYPES = {
18
+ LINKED: 'oauth.connection.linked',
19
+ TOKEN_REFRESHED: 'oauth.connection.token_refreshed',
20
+ REVOKED: 'oauth.connection.revoked',
21
+ } as const;
22
+
23
+ /**
24
+ * Metadata asociada a un evento para trazabilidad y correlación en sistemas distribuidos.
25
+ *
26
+ * @property traceId - ID de traza para distributed tracing (OpenTelemetry, etc.)
27
+ * @property spanId - ID de span dentro de la traza
28
+ * @property correlationId - ID para correlacionar eventos relacionados en un flujo de negocio
29
+ * @property causationId - ID del evento que causó este evento (event sourcing)
30
+ * @property tenantId - ID del tenant en arquitecturas multi-tenant
31
+ * @property projectId - ID del proyecto asociado
32
+ * @property source - Nombre del servicio o componente que originó el evento
33
+ */
34
+ export type EventMeta = {
35
+ traceId?: string;
36
+ spanId?: string;
37
+ correlationId?: string;
38
+ causationId?: string;
39
+ tenantId?: string;
40
+ projectId?: string;
41
+ source: string;
42
+ };
43
+
44
+ /**
45
+ * Envelope que envuelve un evento con toda su metadata y información de versionado.
46
+ * Esta estructura permite la serialización, transmisión y procesamiento de eventos
47
+ * en sistemas distribuidos con garantías de trazabilidad.
48
+ *
49
+ * @template TPayload - Tipo del payload específico del evento
50
+ * @template TMeta - Tipo de metadata (por defecto EventMeta)
51
+ *
52
+ * @property id - Identificador único del evento (recomendado: UUID v4)
53
+ * @property type - Tipo del evento (ej: 'notifications.requested')
54
+ * @property version - Versión semántica del contrato del evento
55
+ * @property occurredAt - Timestamp ISO 8601 de cuándo ocurrió el evento
56
+ * @property payload - Datos específicos del evento
57
+ * @property meta - Metadata de trazabilidad y contexto
58
+ */
59
+ export type EventEnvelope<TPayload, TMeta extends EventMeta = EventMeta> = {
60
+ id: string;
61
+ type: string;
62
+ version: SemanticVersion;
63
+ occurredAt: string;
64
+ payload: TPayload;
65
+ meta: TMeta;
66
+ };
67
+
68
+ /**
69
+ * Contrato que define la estructura y versión de un tipo de evento.
70
+ * Incluye un ejemplo para documentación y validación.
71
+ *
72
+ * @template TPayload - Tipo del payload del evento
73
+ * @template TMeta - Tipo de metadata del evento
74
+ *
75
+ * @property type - Tipo del evento
76
+ * @property version - Versión semántica del contrato
77
+ * @property schema - Identificador del esquema (formato: tipo@version)
78
+ * @property example - Ejemplo completo de un evento de este tipo
79
+ */
80
+ export type EventContract<TPayload, TMeta extends EventMeta = EventMeta> = {
81
+ type: string;
82
+ version: SemanticVersion;
83
+ schema: string;
84
+ example: EventEnvelope<TPayload, TMeta>;
85
+ };
package/src/index.ts ADDED
@@ -0,0 +1,6 @@
1
+ export * from './events';
2
+ export * from './notifications';
3
+ export * from './oauth-connections';
4
+ export * from './versioning';
5
+ export * from './utils';
6
+ export * from './schemas';