@cratis/chronicle 3.1.1 → 4.0.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/EventStore.ts +1 -1
- package/compliance/ComplianceContracts.ts +59 -0
- package/compliance/IPIIManager.ts +12 -0
- package/compliance/PIIManager.spec.ts +50 -0
- package/compliance/PIIManager.ts +9 -0
- package/compliance/PIINotSupportedOnEventSourceId.ts +21 -0
- package/compliance/index.ts +2 -0
- package/compliance/pii.spec.ts +37 -0
- package/compliance/pii.ts +16 -1
- package/compliance/subject.spec.ts +45 -0
- package/compliance/subject.ts +64 -0
- package/dist/EventStore.js +1 -1
- package/dist/EventStore.js.map +1 -1
- package/dist/compliance/ComplianceContracts.d.ts +31 -0
- package/dist/compliance/ComplianceContracts.d.ts.map +1 -1
- package/dist/compliance/ComplianceContracts.js +52 -0
- package/dist/compliance/ComplianceContracts.js.map +1 -1
- package/dist/compliance/IPIIManager.d.ts +11 -0
- package/dist/compliance/IPIIManager.d.ts.map +1 -1
- package/dist/compliance/PIIManager.d.ts +2 -0
- package/dist/compliance/PIIManager.d.ts.map +1 -1
- package/dist/compliance/PIIManager.js +8 -0
- package/dist/compliance/PIIManager.js.map +1 -1
- package/dist/compliance/PIINotSupportedOnEventSourceId.d.ts +11 -0
- package/dist/compliance/PIINotSupportedOnEventSourceId.d.ts.map +1 -0
- package/dist/compliance/PIINotSupportedOnEventSourceId.js +19 -0
- package/dist/compliance/PIINotSupportedOnEventSourceId.js.map +1 -0
- package/dist/compliance/index.d.ts +2 -0
- package/dist/compliance/index.d.ts.map +1 -1
- package/dist/compliance/index.js +2 -0
- package/dist/compliance/index.js.map +1 -1
- package/dist/compliance/pii.d.ts.map +1 -1
- package/dist/compliance/pii.js +13 -1
- package/dist/compliance/pii.js.map +1 -1
- package/dist/compliance/subject.d.ts +39 -0
- package/dist/compliance/subject.d.ts.map +1 -0
- package/dist/compliance/subject.js +58 -0
- package/dist/compliance/subject.js.map +1 -0
- package/dist/eventSequences/AppendOptions.d.ts +8 -0
- package/dist/eventSequences/AppendOptions.d.ts.map +1 -1
- package/dist/eventSequences/EventForEventSourceId.d.ts +7 -0
- package/dist/eventSequences/EventForEventSourceId.d.ts.map +1 -1
- package/dist/eventSequences/EventSequence.d.ts.map +1 -1
- package/dist/eventSequences/EventSequence.js +17 -6
- package/dist/eventSequences/EventSequence.js.map +1 -1
- package/dist/events/EventContext.d.ts +3 -0
- package/dist/events/EventContext.d.ts.map +1 -1
- package/dist/events/Tag.d.ts +10 -0
- package/dist/events/Tag.d.ts.map +1 -0
- package/dist/events/Tag.js +16 -0
- package/dist/events/Tag.js.map +1 -0
- package/dist/events/filterEventsByTagDecorator.d.ts +35 -0
- package/dist/events/filterEventsByTagDecorator.d.ts.map +1 -0
- package/dist/events/filterEventsByTagDecorator.js +48 -0
- package/dist/events/filterEventsByTagDecorator.js.map +1 -0
- package/dist/events/index.d.ts +4 -0
- package/dist/events/index.d.ts.map +1 -1
- package/dist/events/index.js +4 -0
- package/dist/events/index.js.map +1 -1
- package/dist/events/mergeTags.d.ts +12 -0
- package/dist/events/mergeTags.d.ts.map +1 -0
- package/dist/events/mergeTags.js +26 -0
- package/dist/events/mergeTags.js.map +1 -0
- package/dist/events/tagDecorator.d.ts +38 -0
- package/dist/events/tagDecorator.d.ts.map +1 -0
- package/dist/events/tagDecorator.js +54 -0
- package/dist/events/tagDecorator.js.map +1 -0
- package/dist/observation/ObserverRunningState.d.ts +9 -15
- package/dist/observation/ObserverRunningState.d.ts.map +1 -1
- package/dist/observation/ObserverRunningState.js +8 -14
- package/dist/observation/ObserverRunningState.js.map +1 -1
- package/dist/observation/index.d.ts +1 -0
- package/dist/observation/index.d.ts.map +1 -1
- package/dist/observation/index.js +1 -0
- package/dist/observation/index.js.map +1 -1
- package/dist/observation/toObserverRunningState.d.ts +9 -0
- package/dist/observation/toObserverRunningState.d.ts.map +1 -0
- package/dist/observation/toObserverRunningState.js +26 -0
- package/dist/observation/toObserverRunningState.js.map +1 -0
- package/dist/projections/IProjections.d.ts +71 -1
- package/dist/projections/IProjections.d.ts.map +1 -1
- package/dist/projections/ProjectionQueryResult.d.ts +8 -0
- package/dist/projections/ProjectionQueryResult.d.ts.map +1 -0
- package/dist/projections/ProjectionQueryResult.js +4 -0
- package/dist/projections/ProjectionQueryResult.js.map +1 -0
- package/dist/projections/ProjectionState.d.ts +18 -0
- package/dist/projections/ProjectionState.d.ts.map +1 -0
- package/dist/projections/ProjectionState.js +4 -0
- package/dist/projections/ProjectionState.js.map +1 -0
- package/dist/projections/Projections.d.ts +46 -1
- package/dist/projections/Projections.d.ts.map +1 -1
- package/dist/projections/Projections.js +153 -6
- package/dist/projections/Projections.js.map +1 -1
- package/dist/projections/UnableToQueryProjection.d.ts +12 -0
- package/dist/projections/UnableToQueryProjection.d.ts.map +1 -0
- package/dist/projections/UnableToQueryProjection.js +17 -0
- package/dist/projections/UnableToQueryProjection.js.map +1 -0
- package/dist/projections/index.d.ts +3 -0
- package/dist/projections/index.d.ts.map +1 -1
- package/dist/projections/index.js +1 -0
- package/dist/projections/index.js.map +1 -1
- package/dist/projections/modelBound/eventSequence.d.ts +22 -0
- package/dist/projections/modelBound/eventSequence.d.ts.map +1 -0
- package/dist/projections/modelBound/eventSequence.js +34 -0
- package/dist/projections/modelBound/eventSequence.js.map +1 -0
- package/dist/projections/modelBound/fromAll.d.ts +26 -0
- package/dist/projections/modelBound/fromAll.d.ts.map +1 -0
- package/dist/projections/modelBound/fromAll.js +31 -0
- package/dist/projections/modelBound/fromAll.js.map +1 -0
- package/dist/projections/modelBound/index.d.ts +4 -0
- package/dist/projections/modelBound/index.d.ts.map +1 -1
- package/dist/projections/modelBound/index.js +3 -0
- package/dist/projections/modelBound/index.js.map +1 -1
- package/dist/projections/modelBound/noAutoMap.d.ts +26 -0
- package/dist/projections/modelBound/noAutoMap.d.ts.map +1 -0
- package/dist/projections/modelBound/noAutoMap.js +44 -0
- package/dist/projections/modelBound/noAutoMap.js.map +1 -0
- package/dist/reactors/Reactors.d.ts.map +1 -1
- package/dist/reactors/Reactors.js +7 -3
- package/dist/reactors/Reactors.js.map +1 -1
- package/dist/readModels/MaterializedReadModels.d.ts +0 -1
- package/dist/readModels/MaterializedReadModels.d.ts.map +1 -1
- package/dist/readModels/MaterializedReadModels.js +2 -8
- package/dist/readModels/MaterializedReadModels.js.map +1 -1
- package/dist/readModels/ReadModelSubjectResolver.d.ts +22 -0
- package/dist/readModels/ReadModelSubjectResolver.d.ts.map +1 -0
- package/dist/readModels/ReadModelSubjectResolver.js +38 -0
- package/dist/readModels/ReadModelSubjectResolver.js.map +1 -0
- package/dist/readModels/ReadModels.d.ts.map +1 -1
- package/dist/readModels/ReadModels.js +7 -7
- package/dist/readModels/ReadModels.js.map +1 -1
- package/dist/readModels/index.d.ts +1 -0
- package/dist/readModels/index.d.ts.map +1 -1
- package/dist/readModels/index.js +1 -0
- package/dist/readModels/index.js.map +1 -1
- package/dist/reducers/Reducers.d.ts.map +1 -1
- package/dist/reducers/Reducers.js +21 -3
- package/dist/reducers/Reducers.js.map +1 -1
- package/dist/schemas/JsonSchema.d.ts +14 -0
- package/dist/schemas/JsonSchema.d.ts.map +1 -1
- package/dist/schemas/JsonSchemaGenerator.d.ts +61 -5
- package/dist/schemas/JsonSchemaGenerator.d.ts.map +1 -1
- package/dist/schemas/JsonSchemaGenerator.js +130 -26
- package/dist/schemas/JsonSchemaGenerator.js.map +1 -1
- package/dist/schemas/index.d.ts +1 -1
- package/dist/schemas/index.d.ts.map +1 -1
- package/dist/seeding/EventSeeding.d.ts.map +1 -1
- package/dist/seeding/EventSeeding.js +3 -1
- package/dist/seeding/EventSeeding.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/eventSequences/AppendOptions.ts +9 -0
- package/eventSequences/EventForEventSourceId.ts +9 -0
- package/eventSequences/EventSequence.ts +20 -6
- package/events/EventContext.ts +4 -0
- package/events/Tag.ts +14 -0
- package/events/filterEventsByTagDecorator.ts +51 -0
- package/events/index.ts +4 -0
- package/events/mergeTags.spec.ts +50 -0
- package/events/mergeTags.ts +27 -0
- package/events/tagDecorator.spec.ts +115 -0
- package/events/tagDecorator.ts +59 -0
- package/observation/ObserverRunningState.ts +9 -18
- package/observation/index.ts +1 -0
- package/observation/toObserverRunningState.ts +27 -0
- package/package.json +8 -8
- package/projections/IProjections.ts +81 -1
- package/projections/ProjectionQueryResult.ts +10 -0
- package/projections/ProjectionState.ts +25 -0
- package/projections/Projections.childrenAndNested.spec.ts +1 -1
- package/projections/Projections.modelBoundCompleteness.spec.ts +224 -0
- package/projections/Projections.operationalSurface.spec.ts +257 -0
- package/projections/Projections.spec.ts +1 -1
- package/projections/Projections.ts +180 -5
- package/projections/UnableToQueryProjection.ts +17 -0
- package/projections/index.ts +3 -0
- package/projections/modelBound/eventSequence.ts +38 -0
- package/projections/modelBound/fromAll.ts +42 -0
- package/projections/modelBound/index.ts +4 -0
- package/projections/modelBound/noAutoMap.ts +47 -0
- package/reactors/Reactors.ts +7 -3
- package/readModels/MaterializedReadModels.spec.ts +98 -0
- package/readModels/MaterializedReadModels.ts +2 -8
- package/readModels/ReadModelSubjectResolver.spec.ts +84 -0
- package/readModels/ReadModelSubjectResolver.ts +44 -0
- package/readModels/ReadModels.spec.ts +118 -0
- package/readModels/ReadModels.ts +7 -7
- package/readModels/index.ts +1 -0
- package/reducers/Reducers.spec.ts +80 -0
- package/reducers/Reducers.ts +22 -3
- package/schemas/JsonSchema.ts +16 -0
- package/schemas/JsonSchemaGenerator.spec.ts +195 -0
- package/schemas/JsonSchemaGenerator.ts +145 -27
- package/schemas/index.ts +1 -1
- package/seeding/EventSeeding.ts +3 -1
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
3
|
|
|
4
4
|
import 'reflect-metadata';
|
|
5
|
-
import { ConceptAs, Guid } from '@cratis/fundamentals';
|
|
6
|
-
import { JsonSchema } from './JsonSchema';
|
|
5
|
+
import { ConceptAs, Constructor, Fields, Guid } from '@cratis/fundamentals';
|
|
6
|
+
import { ComplianceSchemaMetadata, JsonSchema } from './JsonSchema';
|
|
7
7
|
import { TypeIntrospector } from '../types';
|
|
8
|
+
import { ComplianceMetadata } from '../compliance/ComplianceMetadata';
|
|
8
9
|
import { ComplianceMetadataResolver } from '../compliance/ComplianceMetadataResolver';
|
|
9
10
|
|
|
10
11
|
/**
|
|
@@ -48,12 +49,17 @@ export class JsonSchemaGenerator {
|
|
|
48
49
|
const prototype = target.prototype;
|
|
49
50
|
|
|
50
51
|
for (const [memberName, memberType] of membersToUse.entries()) {
|
|
51
|
-
const propertySchema = this.mapRuntimeTypeToSchema(memberType);
|
|
52
|
+
const propertySchema = this.mapRuntimeTypeToSchema(memberType, target, memberName);
|
|
52
53
|
// Only include properties whose type was resolved. An empty schema ({}) means
|
|
53
54
|
// the runtime type was unavailable (e.g. esbuild/tsx omits design:paramtypes).
|
|
54
55
|
if (Object.keys(propertySchema).length > 0) {
|
|
55
|
-
//
|
|
56
|
-
|
|
56
|
+
// An array of concept elements resolves and applies its own item-level compliance
|
|
57
|
+
// inside mapRuntimeTypeToSchema - the general property/type/declaring-class walk
|
|
58
|
+
// below is skipped for it, mirroring the C# generator's enumerable-of-concept branch.
|
|
59
|
+
if (!this.isConceptArrayMember(target, memberName, memberType)) {
|
|
60
|
+
const metadata = this.collectComplianceMetadata(prototype, memberName, memberType);
|
|
61
|
+
this.addComplianceMetadataToSchema(propertySchema, metadata);
|
|
62
|
+
}
|
|
57
63
|
schemaProperties[memberName] = propertySchema;
|
|
58
64
|
}
|
|
59
65
|
}
|
|
@@ -72,7 +78,7 @@ export class JsonSchemaGenerator {
|
|
|
72
78
|
};
|
|
73
79
|
}
|
|
74
80
|
|
|
75
|
-
private static mapRuntimeTypeToSchema(runtimeType: Function | undefined): JsonSchema {
|
|
81
|
+
private static mapRuntimeTypeToSchema(runtimeType: Function | undefined, declaringType?: Function, propertyName?: string): JsonSchema {
|
|
76
82
|
const knownTypeFormat = this.getKnownTypeFormat(runtimeType);
|
|
77
83
|
if (knownTypeFormat) {
|
|
78
84
|
return knownTypeFormat;
|
|
@@ -91,7 +97,7 @@ export class JsonSchemaGenerator {
|
|
|
91
97
|
}
|
|
92
98
|
|
|
93
99
|
if (runtimeType === Array) {
|
|
94
|
-
return
|
|
100
|
+
return this.mapArrayTypeToSchema(declaringType, propertyName);
|
|
95
101
|
}
|
|
96
102
|
|
|
97
103
|
if (!runtimeType) {
|
|
@@ -115,6 +121,63 @@ export class JsonSchemaGenerator {
|
|
|
115
121
|
return { type: 'object' };
|
|
116
122
|
}
|
|
117
123
|
|
|
124
|
+
/**
|
|
125
|
+
* Maps an array-typed member to a schema, resolving the element type from a
|
|
126
|
+
* `@field(Array, { genericArguments: [ItemType] })` declaration when present.
|
|
127
|
+
* @param declaringType - The class constructor that declares the array property.
|
|
128
|
+
* @param propertyName - The array property name.
|
|
129
|
+
* @returns The array schema, with the element's own compliance metadata carried onto `items` when the element is a PII concept.
|
|
130
|
+
*/
|
|
131
|
+
private static mapArrayTypeToSchema(declaringType: Function | undefined, propertyName: string | undefined): JsonSchema {
|
|
132
|
+
const elementType = this.getArrayElementType(declaringType, propertyName);
|
|
133
|
+
|
|
134
|
+
// An array whose element is a ConceptAs<T> loses its classification the moment it is put in
|
|
135
|
+
// a list unless the element concept's own compliance metadata is carried onto the item schema -
|
|
136
|
+
// a value that would be encrypted as a scalar would otherwise be persisted in the clear as a
|
|
137
|
+
// list element. Mirrors the C# generator's explicit enumerable-of-concept branch.
|
|
138
|
+
if (elementType && this.isConceptAs(elementType)) {
|
|
139
|
+
const itemSchema = this.mapRuntimeTypeToSchema(elementType);
|
|
140
|
+
const metadata = ComplianceMetadataResolver.getMetadataForType(elementType);
|
|
141
|
+
this.addComplianceMetadataToSchema(itemSchema, metadata);
|
|
142
|
+
return { type: 'array', items: itemSchema };
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return { type: 'array', items: { type: 'object' } };
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Resolves the element type of an array property from its `@field(Array, { genericArguments: [...] })`
|
|
150
|
+
* declaration. TypeScript erases generic type arguments at runtime, so without an explicit
|
|
151
|
+
* `@field` declaration the element type cannot be recovered.
|
|
152
|
+
* @param declaringType - The class constructor that declares the array property.
|
|
153
|
+
* @param propertyName - The array property name.
|
|
154
|
+
* @returns The element type constructor, or undefined when it cannot be resolved.
|
|
155
|
+
*/
|
|
156
|
+
private static getArrayElementType(declaringType: Function | undefined, propertyName: string | undefined): Function | undefined {
|
|
157
|
+
if (!declaringType || !propertyName) {
|
|
158
|
+
return undefined;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const field = Fields.getFieldsForType(declaringType as Constructor).find(candidate => candidate.name === propertyName);
|
|
162
|
+
return field?.genericArguments?.[0];
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Checks whether a member is an array whose element type is a ConceptAs<T>.
|
|
167
|
+
* @param declaringType - The class constructor that declares the property.
|
|
168
|
+
* @param propertyName - The property name.
|
|
169
|
+
* @param runtimeType - The member's reflected runtime type.
|
|
170
|
+
* @returns True when the member is an array of concept elements; false otherwise.
|
|
171
|
+
*/
|
|
172
|
+
private static isConceptArrayMember(declaringType: Function, propertyName: string, runtimeType: Function | undefined): boolean {
|
|
173
|
+
if (runtimeType !== Array) {
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const elementType = this.getArrayElementType(declaringType, propertyName);
|
|
178
|
+
return elementType !== undefined && this.isConceptAs(elementType);
|
|
179
|
+
}
|
|
180
|
+
|
|
118
181
|
private static isConceptAs(runtimeType: Function): boolean {
|
|
119
182
|
let current: Function | null = runtimeType;
|
|
120
183
|
while (current && current !== Function.prototype) {
|
|
@@ -150,35 +213,90 @@ export class JsonSchemaGenerator {
|
|
|
150
213
|
}
|
|
151
214
|
|
|
152
215
|
/**
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
* @param
|
|
156
|
-
* @param target - The class prototype.
|
|
216
|
+
* Collects compliance metadata for a property from every source C# resolves PII from: the
|
|
217
|
+
* property itself, its declaring class, and its own type (the concept case).
|
|
218
|
+
* @param target - The class prototype the property is declared on.
|
|
157
219
|
* @param propertyKey - The property name.
|
|
220
|
+
* @param propertyType - The property's runtime type, when resolved.
|
|
221
|
+
* @returns The collected compliance metadata, in property → declaring-class → type order.
|
|
158
222
|
*/
|
|
159
|
-
private static
|
|
160
|
-
const
|
|
223
|
+
private static collectComplianceMetadata(target: object, propertyKey: string, propertyType?: Function): ComplianceMetadata[] {
|
|
224
|
+
const metadata: ComplianceMetadata[] = [];
|
|
161
225
|
|
|
162
|
-
//
|
|
226
|
+
// Property-level compliance decorator.
|
|
163
227
|
if (ComplianceMetadataResolver.hasMetadataFor(target, propertyKey)) {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
228
|
+
metadata.push(...ComplianceMetadataResolver.getMetadataFor(target, propertyKey));
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Declaring class-level compliance decorator - a class-level @pii() marks every one of
|
|
232
|
+
// its own properties, the same way C#'s PIIMetadataProvider checks property.DeclaringType.
|
|
233
|
+
const declaringClass = (target as { constructor?: Function }).constructor;
|
|
234
|
+
if (declaringClass) {
|
|
235
|
+
metadata.push(...ComplianceMetadataResolver.getMetadataForType(declaringClass));
|
|
169
236
|
}
|
|
170
237
|
|
|
171
|
-
//
|
|
238
|
+
// Type-level compliance decorator on the property's own type (e.g., @pii on a ConceptAs).
|
|
172
239
|
if (propertyType) {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
240
|
+
metadata.push(...ComplianceMetadataResolver.getMetadataForType(propertyType));
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return metadata;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Adds compliance metadata to a schema node, descending into an object's properties so that
|
|
248
|
+
* the metadata always lands on the leaves that actually hold a value.
|
|
249
|
+
* @param schema - The schema node to add to.
|
|
250
|
+
* @param metadata - The compliance metadata to add.
|
|
251
|
+
* @remarks
|
|
252
|
+
* A compliance marker can be declared on something that is not a single value: a `@pii()` on a
|
|
253
|
+
* composite value-object type, or on a property whose type is such an object. Compliance is
|
|
254
|
+
* applied per value, so leaving the marker on the container would make Chronicle hand the whole
|
|
255
|
+
* JSON object to the value handler and store one opaque ciphertext string where the schema still
|
|
256
|
+
* says "object". Releasing that gives back a string, not an object, and the read model then
|
|
257
|
+
* fails to materialize. Pushing the metadata down to every leaf keeps encryption symmetric with
|
|
258
|
+
* the release walk, keeps each value independently encrypted, and preserves the document shape.
|
|
259
|
+
*
|
|
260
|
+
* An array-typed node is deliberately left as a container: coarse compliance on a whole
|
|
261
|
+
* collection is an established, separately handled behavior (the collection is blob-encrypted
|
|
262
|
+
* and its shape restored on release).
|
|
263
|
+
*/
|
|
264
|
+
private static addComplianceMetadataToSchema(schema: JsonSchema, metadata: ComplianceMetadata[]): void {
|
|
265
|
+
if (metadata.length === 0) {
|
|
266
|
+
return;
|
|
178
267
|
}
|
|
179
268
|
|
|
180
|
-
if (
|
|
181
|
-
(
|
|
269
|
+
if (schema.properties && Object.keys(schema.properties).length > 0) {
|
|
270
|
+
for (const propertySchema of Object.values(schema.properties)) {
|
|
271
|
+
this.addComplianceMetadataToSchema(propertySchema, metadata);
|
|
272
|
+
}
|
|
273
|
+
return;
|
|
182
274
|
}
|
|
275
|
+
|
|
276
|
+
const compliance = schema.compliance ?? [];
|
|
277
|
+
for (const item of metadata) {
|
|
278
|
+
const metadataType = item.metadataType.value.toString();
|
|
279
|
+
if (!this.hasComplianceMetadataOfType(compliance, metadataType)) {
|
|
280
|
+
compliance.push({ metadataType, details: item.details });
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (compliance.length > 0) {
|
|
285
|
+
schema.compliance = compliance;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Checks whether a compliance array already carries metadata of a given type.
|
|
291
|
+
* @param compliance - The compliance array to check.
|
|
292
|
+
* @param metadataType - The metadata type to look for.
|
|
293
|
+
* @returns True when the metadata type is already present, false if not.
|
|
294
|
+
* @remarks
|
|
295
|
+
* A leaf can be reached by more than one marker — for example a `@pii()` concept inside a value
|
|
296
|
+
* object whose type is itself marked `@pii()`. Recording the same metadata type twice adds
|
|
297
|
+
* nothing and makes the generated schema noisier to read and to diff.
|
|
298
|
+
*/
|
|
299
|
+
private static hasComplianceMetadataOfType(compliance: ComplianceSchemaMetadata[], metadataType: string): boolean {
|
|
300
|
+
return compliance.some(item => item.metadataType === metadataType);
|
|
183
301
|
}
|
|
184
302
|
}
|
package/schemas/index.ts
CHANGED
|
@@ -3,4 +3,4 @@
|
|
|
3
3
|
|
|
4
4
|
export { JsonSchemaGenerator } from './JsonSchemaGenerator';
|
|
5
5
|
export { jsonSchemaProperty, getTrackedJsonSchemaProperties } from './jsonSchemaProperty';
|
|
6
|
-
export type { JsonSchema } from './JsonSchema';
|
|
6
|
+
export type { ComplianceSchemaMetadata, JsonSchema } from './JsonSchema';
|
package/seeding/EventSeeding.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { IClientArtifactsProvider } from '../artifacts';
|
|
|
6
6
|
import { ChronicleConnection } from '../connection';
|
|
7
7
|
import { EventStoreNamespaceName } from '../EventStoreNamespaceName';
|
|
8
8
|
import { getEventTypeFor } from '../events/eventTypeDecorator';
|
|
9
|
+
import { getTagsFor } from '../events/tagDecorator';
|
|
9
10
|
import { ICanSeedEvents } from './ICanSeedEvents';
|
|
10
11
|
import { IEventSeeding } from './IEventSeeding';
|
|
11
12
|
import { IEventSeedingBuilder } from './IEventSeedingBuilder';
|
|
@@ -104,11 +105,12 @@ export class EventSeeding implements IEventSeeding {
|
|
|
104
105
|
private addEntries<TEvent extends object>(eventSourceId: string, events: Iterable<TEvent>, isGlobal: boolean, targetNamespace: string): void {
|
|
105
106
|
for (const event of events) {
|
|
106
107
|
const eventType = getEventTypeFor(event.constructor as Function);
|
|
108
|
+
const tags = getTagsFor(event.constructor as Function).map(t => t.value);
|
|
107
109
|
this._entries.push({
|
|
108
110
|
eventSourceId,
|
|
109
111
|
eventTypeId: eventType.id.value,
|
|
110
112
|
content: JSON.stringify(event),
|
|
111
|
-
tags
|
|
113
|
+
tags,
|
|
112
114
|
isGlobal,
|
|
113
115
|
targetNamespace
|
|
114
116
|
});
|