@cratis/chronicle 6.9.1 → 6.10.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.
Files changed (268) hide show
  1. package/ChronicleClient.ts +52 -13
  2. package/ChronicleOptions.spec.ts +54 -0
  3. package/ChronicleOptions.ts +20 -5
  4. package/EventStore.ts +7 -1
  5. package/README.md +2 -3
  6. package/artifacts/DefaultClientArtifactsProvider.ts +4 -1
  7. package/connection/ChronicleConnection.auth.spec.ts +219 -0
  8. package/connection/ChronicleConnection.ts +70 -31
  9. package/connection/ChronicleServices.ts +1 -1
  10. package/connection/CompatibilityPreflight.ts +1 -1
  11. package/connection/RejectedChronicleCredentials.ts +10 -0
  12. package/connection/TokenProvider.spec.ts +5 -6
  13. package/connection/TokenProvider.ts +26 -17
  14. package/connection/clientVersion.spec.ts +27 -0
  15. package/connection/clientVersion.ts +9 -0
  16. package/connection/describeRequestError.spec.ts +22 -0
  17. package/connection/fetchOAuthAccessToken.ts +33 -2
  18. package/dist/ChronicleClient.d.ts +3 -0
  19. package/dist/ChronicleClient.d.ts.map +1 -1
  20. package/dist/ChronicleClient.js +55 -13
  21. package/dist/ChronicleClient.js.map +1 -1
  22. package/dist/ChronicleOptions.d.ts +5 -1
  23. package/dist/ChronicleOptions.d.ts.map +1 -1
  24. package/dist/ChronicleOptions.js +20 -5
  25. package/dist/ChronicleOptions.js.map +1 -1
  26. package/dist/EventStore.d.ts +2 -0
  27. package/dist/EventStore.d.ts.map +1 -1
  28. package/dist/EventStore.js +6 -1
  29. package/dist/EventStore.js.map +1 -1
  30. package/dist/artifacts/DefaultClientArtifactsProvider.d.ts.map +1 -1
  31. package/dist/artifacts/DefaultClientArtifactsProvider.js +4 -1
  32. package/dist/artifacts/DefaultClientArtifactsProvider.js.map +1 -1
  33. package/dist/connection/ChronicleConnection.d.ts +3 -3
  34. package/dist/connection/ChronicleConnection.d.ts.map +1 -1
  35. package/dist/connection/ChronicleConnection.js +74 -26
  36. package/dist/connection/ChronicleConnection.js.map +1 -1
  37. package/dist/connection/ChronicleServices.d.ts +1 -2
  38. package/dist/connection/ChronicleServices.d.ts.map +1 -1
  39. package/dist/connection/CompatibilityPreflight.js +1 -1
  40. package/dist/connection/CompatibilityPreflight.js.map +1 -1
  41. package/dist/connection/RejectedChronicleCredentials.d.ts +5 -0
  42. package/dist/connection/RejectedChronicleCredentials.d.ts.map +1 -0
  43. package/dist/connection/RejectedChronicleCredentials.js +10 -0
  44. package/dist/connection/RejectedChronicleCredentials.js.map +1 -0
  45. package/dist/connection/TokenProvider.d.ts +8 -6
  46. package/dist/connection/TokenProvider.d.ts.map +1 -1
  47. package/dist/connection/TokenProvider.js +25 -11
  48. package/dist/connection/TokenProvider.js.map +1 -1
  49. package/dist/connection/clientVersion.d.ts +3 -0
  50. package/dist/connection/clientVersion.d.ts.map +1 -0
  51. package/dist/connection/clientVersion.js +7 -0
  52. package/dist/connection/clientVersion.js.map +1 -0
  53. package/dist/connection/fetchOAuthAccessToken.d.ts +12 -0
  54. package/dist/connection/fetchOAuthAccessToken.d.ts.map +1 -1
  55. package/dist/connection/fetchOAuthAccessToken.js +37 -2
  56. package/dist/connection/fetchOAuthAccessToken.js.map +1 -1
  57. package/dist/externalServices/ExternalServiceBuilder.d.ts +1 -1
  58. package/dist/externalServices/ExternalServiceBuilder.d.ts.map +1 -1
  59. package/dist/externalServices/ExternalServiceBuilder.js +1 -1
  60. package/dist/externalServices/ExternalServiceBuilder.js.map +1 -1
  61. package/dist/externalServices/ExternalServices.d.ts.map +1 -1
  62. package/dist/externalServices/ExternalServices.js +3 -1
  63. package/dist/externalServices/ExternalServices.js.map +1 -1
  64. package/dist/index.d.ts +1 -0
  65. package/dist/index.d.ts.map +1 -1
  66. package/dist/index.js +1 -0
  67. package/dist/index.js.map +1 -1
  68. package/dist/projections/Projections.d.ts.map +1 -1
  69. package/dist/projections/Projections.js +9 -7
  70. package/dist/projections/Projections.js.map +1 -1
  71. package/dist/projections/constantValueExpression.d.ts +3 -0
  72. package/dist/projections/constantValueExpression.d.ts.map +1 -0
  73. package/dist/projections/constantValueExpression.js +26 -0
  74. package/dist/projections/constantValueExpression.js.map +1 -0
  75. package/dist/projections/declarative/ChildrenBuilder.d.ts +2 -0
  76. package/dist/projections/declarative/ChildrenBuilder.d.ts.map +1 -1
  77. package/dist/projections/declarative/ChildrenBuilder.js +5 -0
  78. package/dist/projections/declarative/ChildrenBuilder.js.map +1 -1
  79. package/dist/projections/declarative/FromBuilder.d.ts.map +1 -1
  80. package/dist/projections/declarative/FromBuilder.js +3 -2
  81. package/dist/projections/declarative/FromBuilder.js.map +1 -1
  82. package/dist/projections/declarative/JoinBuilder.d.ts.map +1 -1
  83. package/dist/projections/declarative/JoinBuilder.js +2 -1
  84. package/dist/projections/declarative/JoinBuilder.js.map +1 -1
  85. package/dist/projections/declarative/NestedBuilder.d.ts.map +1 -1
  86. package/dist/projections/declarative/NestedBuilder.js +3 -1
  87. package/dist/projections/declarative/NestedBuilder.js.map +1 -1
  88. package/dist/projections/declarative/ProjectionBuilderCore.d.ts +5 -0
  89. package/dist/projections/declarative/ProjectionBuilderCore.d.ts.map +1 -1
  90. package/dist/projections/declarative/ProjectionBuilderCore.js +18 -2
  91. package/dist/projections/declarative/ProjectionBuilderCore.js.map +1 -1
  92. package/dist/projections/declarative/ProjectionBuilderFor.d.ts +6 -0
  93. package/dist/projections/declarative/ProjectionBuilderFor.d.ts.map +1 -1
  94. package/dist/projections/declarative/ProjectionBuilderFor.js +5 -0
  95. package/dist/projections/declarative/ProjectionBuilderFor.js.map +1 -1
  96. package/dist/projections/declarative/SetBuilder.d.ts.map +1 -1
  97. package/dist/projections/declarative/SetBuilder.js +2 -1
  98. package/dist/projections/declarative/SetBuilder.js.map +1 -1
  99. package/dist/projections/modelBound/addFrom.d.ts.map +1 -1
  100. package/dist/projections/modelBound/addFrom.js +3 -2
  101. package/dist/projections/modelBound/addFrom.js.map +1 -1
  102. package/dist/projections/modelBound/childrenAndNestedBuilder.d.ts +20 -0
  103. package/dist/projections/modelBound/childrenAndNestedBuilder.d.ts.map +1 -1
  104. package/dist/projections/modelBound/childrenAndNestedBuilder.js +14 -11
  105. package/dist/projections/modelBound/childrenAndNestedBuilder.js.map +1 -1
  106. package/dist/projections/modelBound/childrenFrom.d.ts +4 -2
  107. package/dist/projections/modelBound/childrenFrom.d.ts.map +1 -1
  108. package/dist/projections/modelBound/childrenFrom.js +8 -4
  109. package/dist/projections/modelBound/childrenFrom.js.map +1 -1
  110. package/dist/projections/modelBound/clearWith.d.ts.map +1 -1
  111. package/dist/projections/modelBound/clearWith.js +3 -2
  112. package/dist/projections/modelBound/clearWith.js.map +1 -1
  113. package/dist/projections/modelBound/count.d.ts.map +1 -1
  114. package/dist/projections/modelBound/count.js +3 -2
  115. package/dist/projections/modelBound/count.js.map +1 -1
  116. package/dist/projections/modelBound/decrement.d.ts.map +1 -1
  117. package/dist/projections/modelBound/decrement.js +3 -2
  118. package/dist/projections/modelBound/decrement.js.map +1 -1
  119. package/dist/projections/modelBound/fromAll.d.ts.map +1 -1
  120. package/dist/projections/modelBound/fromAll.js +3 -2
  121. package/dist/projections/modelBound/fromAll.js.map +1 -1
  122. package/dist/projections/modelBound/fromEvery.d.ts.map +1 -1
  123. package/dist/projections/modelBound/fromEvery.js +3 -2
  124. package/dist/projections/modelBound/fromEvery.js.map +1 -1
  125. package/dist/projections/modelBound/increment.d.ts.map +1 -1
  126. package/dist/projections/modelBound/increment.js +3 -2
  127. package/dist/projections/modelBound/increment.js.map +1 -1
  128. package/dist/projections/modelBound/join.d.ts.map +1 -1
  129. package/dist/projections/modelBound/join.js +3 -2
  130. package/dist/projections/modelBound/join.js.map +1 -1
  131. package/dist/projections/modelBound/nested.d.ts.map +1 -1
  132. package/dist/projections/modelBound/nested.js +3 -2
  133. package/dist/projections/modelBound/nested.js.map +1 -1
  134. package/dist/projections/modelBound/noAutoMap.d.ts.map +1 -1
  135. package/dist/projections/modelBound/noAutoMap.js +3 -2
  136. package/dist/projections/modelBound/noAutoMap.js.map +1 -1
  137. package/dist/projections/modelBound/removedWith.d.ts.map +1 -1
  138. package/dist/projections/modelBound/removedWith.js +3 -2
  139. package/dist/projections/modelBound/removedWith.js.map +1 -1
  140. package/dist/projections/modelBound/removedWithJoin.d.ts.map +1 -1
  141. package/dist/projections/modelBound/removedWithJoin.js +3 -2
  142. package/dist/projections/modelBound/removedWithJoin.js.map +1 -1
  143. package/dist/projections/modelBound/setFrom.d.ts.map +1 -1
  144. package/dist/projections/modelBound/setFrom.js +3 -2
  145. package/dist/projections/modelBound/setFrom.js.map +1 -1
  146. package/dist/projections/modelBound/setFromContext.d.ts.map +1 -1
  147. package/dist/projections/modelBound/setFromContext.js +3 -2
  148. package/dist/projections/modelBound/setFromContext.js.map +1 -1
  149. package/dist/projections/modelBound/setValue.d.ts.map +1 -1
  150. package/dist/projections/modelBound/setValue.js +3 -2
  151. package/dist/projections/modelBound/setValue.js.map +1 -1
  152. package/dist/projections/modelBound/subtractFrom.d.ts.map +1 -1
  153. package/dist/projections/modelBound/subtractFrom.js +3 -2
  154. package/dist/projections/modelBound/subtractFrom.js.map +1 -1
  155. package/dist/projections/notSetPropertyPath.d.ts +3 -0
  156. package/dist/projections/notSetPropertyPath.d.ts.map +1 -0
  157. package/dist/projections/notSetPropertyPath.js +5 -0
  158. package/dist/projections/notSetPropertyPath.js.map +1 -0
  159. package/dist/reactors/Reactors.d.ts +4 -0
  160. package/dist/reactors/Reactors.d.ts.map +1 -1
  161. package/dist/reactors/Reactors.js +24 -6
  162. package/dist/reactors/Reactors.js.map +1 -1
  163. package/dist/reactors/reactor.d.ts +2 -2
  164. package/dist/reactors/reactor.js +2 -2
  165. package/dist/readModels/MaterializedReadModels.d.ts.map +1 -1
  166. package/dist/readModels/MaterializedReadModels.js +2 -4
  167. package/dist/readModels/MaterializedReadModels.js.map +1 -1
  168. package/dist/readModels/ReadModels.d.ts +2 -1
  169. package/dist/readModels/ReadModels.d.ts.map +1 -1
  170. package/dist/readModels/ReadModels.js +16 -10
  171. package/dist/readModels/ReadModels.js.map +1 -1
  172. package/dist/readModels/deserializeReadModel.d.ts +5 -0
  173. package/dist/readModels/deserializeReadModel.d.ts.map +1 -0
  174. package/dist/readModels/deserializeReadModel.js +84 -0
  175. package/dist/readModels/deserializeReadModel.js.map +1 -0
  176. package/dist/readModels/rootReadModelTypes.d.ts +5 -0
  177. package/dist/readModels/rootReadModelTypes.d.ts.map +1 -0
  178. package/dist/readModels/rootReadModelTypes.js +69 -0
  179. package/dist/readModels/rootReadModelTypes.js.map +1 -0
  180. package/dist/reducers/Reducers.d.ts +4 -0
  181. package/dist/reducers/Reducers.d.ts.map +1 -1
  182. package/dist/reducers/Reducers.js +24 -6
  183. package/dist/reducers/Reducers.js.map +1 -1
  184. package/dist/schemas/JsonSchemaGenerator.d.ts.map +1 -1
  185. package/dist/schemas/JsonSchemaGenerator.js +4 -4
  186. package/dist/schemas/JsonSchemaGenerator.js.map +1 -1
  187. package/dist/tsconfig.tsbuildinfo +1 -1
  188. package/dist/types/TypeDiscoverer.d.ts +8 -1
  189. package/dist/types/TypeDiscoverer.d.ts.map +1 -1
  190. package/dist/types/TypeDiscoverer.js +25 -5
  191. package/dist/types/TypeDiscoverer.js.map +1 -1
  192. package/dist/types/TypeIntrospector.d.ts.map +1 -1
  193. package/dist/types/TypeIntrospector.js +3 -2
  194. package/dist/types/TypeIntrospector.js.map +1 -1
  195. package/dist/types/conceptValueType.d.ts +4 -0
  196. package/dist/types/conceptValueType.d.ts.map +1 -0
  197. package/dist/types/conceptValueType.js +10 -0
  198. package/dist/types/conceptValueType.js.map +1 -0
  199. package/dist/types/modelBoundProperty.d.ts +6 -0
  200. package/dist/types/modelBoundProperty.d.ts.map +1 -0
  201. package/dist/types/modelBoundProperty.js +53 -0
  202. package/dist/types/modelBoundProperty.js.map +1 -0
  203. package/externalServices/ExternalServiceBuilder.ts +4 -4
  204. package/externalServices/ExternalServices.spec.ts +87 -0
  205. package/externalServices/ExternalServices.ts +3 -1
  206. package/for_ChronicleClient/connectionAuthentication.spec.ts +67 -0
  207. package/index.ts +1 -0
  208. package/observation/observationDisposal.spec.ts +74 -0
  209. package/package.json +2 -1
  210. package/projections/Projections.childrenAndNested.spec.ts +2 -0
  211. package/projections/Projections.modelBoundCompleteness.spec.ts +47 -0
  212. package/projections/Projections.ts +9 -7
  213. package/projections/constantValueExpression.spec.ts +31 -0
  214. package/projections/constantValueExpression.ts +28 -0
  215. package/projections/declarative/ChildrenBuilder.spec.ts +46 -1
  216. package/projections/declarative/ChildrenBuilder.ts +6 -0
  217. package/projections/declarative/FromBuilder.ts +3 -2
  218. package/projections/declarative/JoinBuilder.ts +2 -1
  219. package/projections/declarative/NestedBuilder.ts +3 -1
  220. package/projections/declarative/ProjectionBuilderCore.ts +20 -2
  221. package/projections/declarative/ProjectionBuilderFor.spec.ts +61 -4
  222. package/projections/declarative/ProjectionBuilderFor.ts +7 -0
  223. package/projections/declarative/SetBuilder.ts +2 -1
  224. package/projections/modelBound/addFrom.ts +3 -2
  225. package/projections/modelBound/childrenAndNestedBuilder.ts +14 -11
  226. package/projections/modelBound/childrenFrom.ts +11 -5
  227. package/projections/modelBound/clearWith.ts +3 -2
  228. package/projections/modelBound/count.ts +3 -2
  229. package/projections/modelBound/decorators.standard.spec.ts +45 -0
  230. package/projections/modelBound/decrement.ts +3 -2
  231. package/projections/modelBound/fromAll.ts +3 -2
  232. package/projections/modelBound/fromEvery.ts +3 -2
  233. package/projections/modelBound/increment.ts +3 -2
  234. package/projections/modelBound/join.ts +3 -2
  235. package/projections/modelBound/nested.ts +3 -2
  236. package/projections/modelBound/noAutoMap.ts +3 -2
  237. package/projections/modelBound/removedWith.ts +3 -2
  238. package/projections/modelBound/removedWithJoin.ts +3 -2
  239. package/projections/modelBound/setFrom.ts +3 -2
  240. package/projections/modelBound/setFromContext.ts +3 -2
  241. package/projections/modelBound/setValue.ts +3 -2
  242. package/projections/modelBound/subtractFrom.ts +3 -2
  243. package/projections/notSetPropertyPath.ts +5 -0
  244. package/reactors/Reactors.ts +22 -7
  245. package/reactors/reactor.ts +2 -2
  246. package/readModels/MaterializedReadModels.spec.ts +22 -0
  247. package/readModels/MaterializedReadModels.ts +2 -4
  248. package/readModels/ReadModels.spec.ts +58 -1
  249. package/readModels/ReadModels.ts +17 -11
  250. package/readModels/conceptValueType.spec.ts +20 -0
  251. package/readModels/deserializeReadModel.spec.ts +84 -0
  252. package/readModels/deserializeReadModel.ts +82 -0
  253. package/readModels/discovery.spec.ts +27 -0
  254. package/readModels/rootReadModelTypes.spec.ts +115 -0
  255. package/readModels/rootReadModelTypes.ts +65 -0
  256. package/reducers/Reducers.ts +22 -7
  257. package/schemas/JsonSchemaGenerator.ts +4 -4
  258. package/schemas/legacyDesignMetadata.spec.ts +24 -2
  259. package/types/TypeDiscoverer.spec.ts +57 -0
  260. package/types/TypeDiscoverer.ts +27 -6
  261. package/types/TypeIntrospector.ts +3 -2
  262. package/types/conceptValueType.ts +11 -0
  263. package/types/modelBoundProperty.ts +53 -0
  264. package/dist/externalServices/ExternalServicesContracts.d.ts +0 -137
  265. package/dist/externalServices/ExternalServicesContracts.d.ts.map +0 -1
  266. package/dist/externalServices/ExternalServicesContracts.js +0 -654
  267. package/dist/externalServices/ExternalServicesContracts.js.map +0 -1
  268. package/externalServices/ExternalServicesContracts.ts +0 -709
@@ -7,6 +7,7 @@ import { ConceptAs, field, Guid } from '@cratis/fundamentals';
7
7
  import ts from 'typescript';
8
8
  import { describe, expect, it } from 'vitest';
9
9
  import { JsonSchemaGenerator } from './JsonSchemaGenerator.js';
10
+ import { eventType, getEventTypeMetadata } from '../events/eventTypeDecorator.js';
10
11
 
11
12
  const source = `
12
13
  function mark() { return () => {}; }
@@ -16,7 +17,16 @@ class LegacyId extends ConceptAs {
16
17
  class LegacyHolder {
17
18
  @field(LegacyId) id!: LegacyId;
18
19
  }
19
- exports.types = { LegacyId, LegacyHolder };
20
+ @eventType('no-defaults')
21
+ class NoDefaults {
22
+ constructor(readonly name: string, readonly when: Date, readonly count: number) {}
23
+ }
24
+ class ExplicitField {
25
+ constructor(readonly count: number) {}
26
+ }
27
+ field(Boolean)(ExplicitField.prototype, 'count');
28
+ eventType('explicit-field')(ExplicitField);
29
+ exports.types = { LegacyId, LegacyHolder, NoDefaults, ExplicitField };
20
30
  `;
21
31
 
22
32
  const compiled = ts.transpileModule(source, {
@@ -30,10 +40,22 @@ const compiled = ts.transpileModule(source, {
30
40
 
31
41
  describe('legacy emitDecoratorMetadata compatibility', () => {
32
42
  it('resolves a Guid-backed concept through emitted design:type', () => {
33
- const sandbox = { exports: {} as { types?: { LegacyId: Function; LegacyHolder: Function } }, ConceptAs, field, Guid, Reflect };
43
+ const sandbox = { exports: {} as { types?: { LegacyId: Function; LegacyHolder: Function } }, ConceptAs, field, Guid, Reflect, eventType, String, Number, Boolean, Date };
34
44
  runInNewContext(compiled, sandbox);
35
45
  const { LegacyId, LegacyHolder } = sandbox.exports.types!;
36
46
  expect(Reflect.getMetadata('design:type', LegacyId.prototype, 'value')).toBe(Guid);
37
47
  expect(JsonSchemaGenerator.generate(LegacyHolder).properties?.id).toEqual({ type: 'string', format: 'guid' });
38
48
  });
49
+
50
+ it('resolves constructor parameter properties without defaults from design:paramtypes', () => {
51
+ const sandbox = { exports: {} as { types?: { NoDefaults: Function; ExplicitField: Function } }, ConceptAs, field, Guid, Reflect, eventType, String, Number, Boolean, Date };
52
+ runInNewContext(compiled, sandbox);
53
+ const { NoDefaults, ExplicitField } = sandbox.exports.types!;
54
+ expect(getEventTypeMetadata(NoDefaults)?.schema.properties).toEqual({
55
+ name: { type: 'string' },
56
+ when: { type: 'string', format: 'date-time' },
57
+ count: { type: 'number' }
58
+ });
59
+ expect(getEventTypeMetadata(ExplicitField)?.schema.properties?.count).toEqual({ type: 'boolean' });
60
+ });
39
61
  });
@@ -0,0 +1,57 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { mkdtemp, mkdir, rm, writeFile } from 'node:fs/promises';
5
+ import { tmpdir } from 'node:os';
6
+ import path from 'node:path';
7
+ import { describe, expect, it, vi } from 'vitest';
8
+ import { TypeDiscoverer } from './TypeDiscoverer.js';
9
+
10
+ describe('TypeDiscoverer', () => {
11
+ it('passes included patterns and stripped exclusions to glob ignore', async () => {
12
+ const glob = vi.fn().mockResolvedValue([]);
13
+ await new TypeDiscoverer(glob).discover([
14
+ '**/*.ts', '!**/*.d.ts', '!**/node_modules', '!**/dist', '!**/build', '!**/.git', '!**/.vscode', '!**/*.spec.ts', '!**/*.test.ts'
15
+ ]);
16
+ expect(glob).toHaveBeenCalledWith(['**/*.ts'], {
17
+ ignore: [
18
+ '**/*.d.ts', '**/*.d.ts/**', '**/node_modules', '**/node_modules/**',
19
+ '**/dist', '**/dist/**', '**/build', '**/build/**', '**/.git', '**/.git/**',
20
+ '**/.vscode', '**/.vscode/**', '**/*.spec.ts', '**/*.spec.ts/**',
21
+ '**/*.test.ts', '**/*.test.ts/**'
22
+ ]
23
+ });
24
+ });
25
+
26
+ it('excludes declaration files, tests and directory contents with the real glob', async () => {
27
+ const directory = await mkdtemp(path.join(tmpdir(), 'chronicle-discovery-'));
28
+ try {
29
+ for (const subdirectory of ['node_modules', 'dist', 'build', '.git', '.vscode']) {
30
+ await mkdir(path.join(directory, subdirectory));
31
+ await writeFile(path.join(directory, subdirectory, 'excluded.ts'), '');
32
+ }
33
+ for (const file of ['included.ts', 'excluded.d.ts', 'excluded.spec.ts', 'excluded.test.ts']) {
34
+ await writeFile(path.join(directory, file), '');
35
+ }
36
+ const imported: string[] = [];
37
+ const discoverer = new TypeDiscoverer(undefined, async file => { imported.push(file); });
38
+ await discoverer.discover([
39
+ `${directory}/**/*.ts`, `!${directory}/**/*.d.ts`, `!${directory}/**/*.spec.ts`,
40
+ `!${directory}/**/*.test.ts`, ...['node_modules', 'dist', 'build', '.git', '.vscode'].map(name => `!${directory}/**/${name}`)
41
+ ]);
42
+ expect(imported).toEqual([path.join(directory, 'included.ts')]);
43
+ } finally {
44
+ await rm(directory, { recursive: true, force: true });
45
+ }
46
+ });
47
+
48
+ it('reports the path and preserves the cause of a failed import', async () => {
49
+ const failure = new SyntaxError('invalid decorator');
50
+ const discoverer = new TypeDiscoverer(async () => ['broken.ts'], async () => { throw failure; });
51
+ const file = path.resolve('broken.ts');
52
+ await expect(discoverer.discover('*.ts')).rejects.toMatchObject({
53
+ message: expect.stringContaining(file),
54
+ cause: failure
55
+ });
56
+ });
57
+ });
@@ -7,7 +7,7 @@ import { Constructor } from '@cratis/fundamentals';
7
7
  import { TypeIntrospector } from './TypeIntrospector.js';
8
8
  import { hasPropertyMetadata } from './propertyDecoratorMetadata.js';
9
9
 
10
- type GlobFunction = (pattern: string | string[]) => Promise<string[]>;
10
+ type GlobFunction = (pattern: string | string[], options?: { ignore: string[] }) => Promise<string[]>;
11
11
  type FileImporter = (filePath: string) => Promise<unknown>;
12
12
 
13
13
  const modelBoundPropertyKeys = [
@@ -29,6 +29,7 @@ export class TypeDiscoverer {
29
29
  static readonly default = new TypeDiscoverer();
30
30
 
31
31
  private static readonly _registeredTypes: Map<DecoratorType, Map<string, Constructor>> = new Map();
32
+ private static readonly _propertyOnlyModels = new Set<Constructor>();
32
33
 
33
34
  private readonly _glob: GlobFunction;
34
35
  private readonly _importFile: FileImporter;
@@ -49,20 +50,39 @@ export class TypeDiscoverer {
49
50
  */
50
51
  async discover(pattern: string | string[]): Promise<void> {
51
52
  const patterns = Array.isArray(pattern) ? pattern : [pattern];
52
- const files = await this._glob(patterns);
53
+ const included = patterns.filter(pattern => !pattern.startsWith('!'));
54
+ const excluded = patterns.filter(pattern => pattern.startsWith('!')).map(pattern => pattern.slice(1));
55
+ const ignore = excluded.flatMap(pattern => [pattern, `${pattern}/**`]);
56
+ const files = await this._glob(included, { ignore });
53
57
  for (const file of files) {
54
- const module = await this._importFile(path.resolve(file));
58
+ const filePath = path.resolve(file);
59
+ let module: unknown;
60
+ try {
61
+ module = await this._importFile(filePath);
62
+ } catch (error) {
63
+ throw new Error(`Could not import discovered file '${filePath}'.`, { cause: error });
64
+ }
55
65
  if (module && typeof module === 'object') {
56
66
  for (const type of Object.values(module)) {
57
67
  if (typeof type !== 'function' || !type.prototype) continue;
58
68
  if (hasModelBoundProperties(type)) {
59
- this.register(DecoratorType.ReadModel, type as Constructor);
69
+ this.trackModelBoundProperty(type as Constructor);
60
70
  }
61
71
  }
62
72
  }
63
73
  }
64
74
  }
65
75
 
76
+ /** Collects property-bound models without registering child names as root model identifiers. */
77
+ trackModelBoundProperty(type: Constructor): void {
78
+ TypeDiscoverer._propertyOnlyModels.add(type);
79
+ }
80
+
81
+ /** Returns models with property mappings for artifact registration-time root filtering. */
82
+ getPropertyOnlyModels(): Constructor[] {
83
+ return [...TypeDiscoverer._propertyOnlyModels];
84
+ }
85
+
66
86
  /**
67
87
  * Registers a discoverable type for a decorator category.
68
88
  * @param decoratorType - The decorator category to register for.
@@ -116,9 +136,10 @@ export class TypeDiscoverer {
116
136
  */
117
137
  clear(): void {
118
138
  TypeDiscoverer._registeredTypes.clear();
139
+ TypeDiscoverer._propertyOnlyModels.clear();
119
140
  }
120
141
 
121
- private static async resolveWithGlobPackage(pattern: string | string[]): Promise<string[]> {
142
+ private static async resolveWithGlobPackage(pattern: string | string[], options?: { ignore: string[] }): Promise<string[]> {
122
143
  let globFunction: unknown;
123
144
  try {
124
145
  const globModule = await import('glob') as { glob?: unknown };
@@ -131,7 +152,7 @@ export class TypeDiscoverer {
131
152
  throw new Error('The "glob" module was loaded but does not export a function named "glob".');
132
153
  }
133
154
 
134
- const files = await globFunction(pattern);
155
+ const files = await globFunction(pattern, options);
135
156
  if (!Array.isArray(files) || files.some(file => typeof file !== 'string')) {
136
157
  throw new Error('Type discovery glob resolution did not return an array of file paths.');
137
158
  }
@@ -82,11 +82,12 @@ export class TypeIntrospector {
82
82
 
83
83
  for (let index = 0; index < constructorParameterNames.length; index++) {
84
84
  const parameterName = constructorParameterNames[index];
85
- if (members.has(parameterName)) {
85
+ const resolvedType = members.get(parameterName);
86
+ if (resolvedType && resolvedType !== Object) {
86
87
  continue;
87
88
  }
88
89
 
89
- members.set(parameterName, constructorParameterTypes[index]);
90
+ members.set(parameterName, constructorParameterTypes[index] ?? resolvedType);
90
91
  }
91
92
 
92
93
  return members;
@@ -0,0 +1,11 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import 'reflect-metadata';
5
+
6
+ /** Resolves the runtime value type erased from ConceptAs<T>. */
7
+ export function conceptValueType(type: Function): Function | undefined {
8
+ return (type as Function & { valueType?: Function }).valueType ??
9
+ Reflect.getMetadata('design:type', type.prototype, 'value') as Function | undefined ??
10
+ (Reflect.getMetadata('design:paramtypes', type) as Function[] | undefined)?.[0];
11
+ }
@@ -0,0 +1,53 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import type { Constructor } from '@cratis/fundamentals';
5
+ import { TypeDiscoverer } from './TypeDiscoverer.js';
6
+ import { ChronicleClassOrPropertyDecorator, ChroniclePropertyDecorator, decorateClassOrProperty, decorateProperty } from './propertyDecoratorMetadata.js';
7
+ import { getStandardMetadata, hasOwnStandardMetadata } from './standardDecoratorMetadata.js';
8
+
9
+ const registered = new WeakSet<Function>();
10
+
11
+ function register(type: Function): void {
12
+ if (registered.has(type)) return;
13
+ TypeDiscoverer.default.trackModelBoundProperty(type as Constructor);
14
+ registered.add(type);
15
+ }
16
+
17
+ function registerDeclaringClass(instance: object, metadata: object): void {
18
+ let type: Function | null = instance.constructor;
19
+ while (type && (!hasOwnStandardMetadata(type) || getStandardMetadata(type) !== metadata)) {
20
+ type = Object.getPrototypeOf(type) as Function | null;
21
+ }
22
+ if (type) register(type);
23
+ }
24
+
25
+ /** Registers a mapped class when its property decorator can identify the constructor. */
26
+ export function decorateModelBoundProperty(legacy: PropertyDecorator): ChroniclePropertyDecorator {
27
+ const decorate = decorateProperty(legacy);
28
+ return (target: object | undefined, keyOrContext: string | symbol | ClassFieldDecoratorContext) => {
29
+ decorate(target as object, keyOrContext as string);
30
+ if (typeof keyOrContext === 'object') {
31
+ // Standard field decorators do not receive the class constructor. Their initializer
32
+ // runs when the first instance is created; direct queries can also register the type.
33
+ const metadata = keyOrContext.metadata;
34
+ keyOrContext.addInitializer(function () { if (metadata) registerDeclaringClass(this as object, metadata); });
35
+ } else {
36
+ register((target as { constructor: Function }).constructor);
37
+ }
38
+ };
39
+ }
40
+
41
+ /** Registers property mappings without changing class-level decorator behavior. */
42
+ export function decorateModelBoundClassOrProperty(legacy: (target: object, property?: string | symbol) => void): ChronicleClassOrPropertyDecorator {
43
+ const decorate = decorateClassOrProperty(legacy);
44
+ return (target: object | undefined, keyOrContext?: string | symbol | ClassDecoratorContext | ClassFieldDecoratorContext) => {
45
+ decorate(target as object, keyOrContext as string);
46
+ if (typeof keyOrContext === 'object' && keyOrContext?.kind === 'field') {
47
+ const metadata = keyOrContext.metadata;
48
+ keyOrContext.addInitializer(function () { if (metadata) registerDeclaringClass(this as object, metadata); });
49
+ } else if (typeof keyOrContext === 'string' || typeof keyOrContext === 'symbol') {
50
+ register((target as { constructor: Function }).constructor);
51
+ }
52
+ };
53
+ }
@@ -1,137 +0,0 @@
1
- import { BinaryReader, BinaryWriter } from '@bufbuild/protobuf/wire';
2
- import type { CallOptions } from 'nice-grpc-common';
3
- /**
4
- * The type of endpoint an external service exposes.
5
- */
6
- export declare enum ExternalServiceEndpointType {
7
- Http = 0,
8
- MsSql = 1,
9
- PostgreSql = 2
10
- }
11
- /**
12
- * Basic authentication credentials for an HTTP endpoint.
13
- */
14
- export interface BasicAuthorization {
15
- Username: string;
16
- Password: string;
17
- }
18
- /**
19
- * A bearer token for an HTTP endpoint.
20
- */
21
- export interface BearerTokenAuthorization {
22
- Token: string;
23
- }
24
- /**
25
- * OAuth client credentials for an HTTP endpoint.
26
- */
27
- export interface OAuthAuthorization {
28
- Authority: string;
29
- ClientId: string;
30
- ClientSecret: string;
31
- }
32
- /**
33
- * The authorization configured for an HTTP endpoint - at most one of the three is set.
34
- */
35
- export interface OneOfBasicAuthorizationBearerTokenAuthorizationOAuthAuthorization {
36
- Value0: BasicAuthorization | undefined;
37
- Value1: BearerTokenAuthorization | undefined;
38
- Value2: OAuthAuthorization | undefined;
39
- }
40
- /**
41
- * Configuration for an HTTP-based external service endpoint.
42
- */
43
- export interface HttpEndpointConfiguration {
44
- Url: string;
45
- Authorization: OneOfBasicAuthorizationBearerTokenAuthorizationOAuthAuthorization | undefined;
46
- Headers: {
47
- [key: string]: string;
48
- };
49
- }
50
- /**
51
- * Configuration for a database-based external service endpoint.
52
- */
53
- export interface DatabaseEndpointConfiguration {
54
- Host: string;
55
- Port: number;
56
- Database: string;
57
- Username: string;
58
- Password: string;
59
- Options: {
60
- [key: string]: string;
61
- };
62
- }
63
- /**
64
- * The endpoint configured for an external service - either Http or Database, based on Type.
65
- */
66
- export interface ExternalServiceEndpoint {
67
- Type: ExternalServiceEndpointType;
68
- Http: HttpEndpointConfiguration | undefined;
69
- Database: DatabaseEndpointConfiguration | undefined;
70
- }
71
- /**
72
- * The definition of an external service registration.
73
- */
74
- export interface ExternalServiceDefinition {
75
- Id: string;
76
- Name: string;
77
- Endpoint: ExternalServiceEndpoint | undefined;
78
- }
79
- /**
80
- * Request for registering external services with the Kernel.
81
- */
82
- export interface AddExternalServices {
83
- EventStore: string;
84
- ExternalServices: ExternalServiceDefinition[];
85
- }
86
- /**
87
- * An empty protobuf message.
88
- */
89
- export interface Empty {
90
- }
91
- type Builtin = Date | Function | Uint8Array | string | number | boolean | bigint | undefined;
92
- export type DeepPartial<T> = T extends Builtin ? T : T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>> : T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>> : T extends {} ? {
93
- [K in keyof T]?: DeepPartial<T[K]>;
94
- } : Partial<T>;
95
- interface MessageFns<T> {
96
- encode(message: T, writer?: BinaryWriter): BinaryWriter;
97
- decode(input: BinaryReader | Uint8Array, length?: number): T;
98
- fromJSON(object: unknown): T;
99
- toJSON(message: T): unknown;
100
- create(base?: DeepPartial<T>): T;
101
- fromPartial(object: DeepPartial<T>): T;
102
- }
103
- export declare const EmptyMessage: MessageFns<Empty>;
104
- export declare const BasicAuthorizationMessage: MessageFns<BasicAuthorization>;
105
- export declare const BearerTokenAuthorizationMessage: MessageFns<BearerTokenAuthorization>;
106
- export declare const OAuthAuthorizationMessage: MessageFns<OAuthAuthorization>;
107
- export declare const OneOfBasicAuthorizationBearerTokenAuthorizationOAuthAuthorizationMessage: MessageFns<OneOfBasicAuthorizationBearerTokenAuthorizationOAuthAuthorization>;
108
- export declare const HttpEndpointConfigurationMessage: MessageFns<HttpEndpointConfiguration>;
109
- export declare const DatabaseEndpointConfigurationMessage: MessageFns<DatabaseEndpointConfiguration>;
110
- export declare const ExternalServiceEndpointMessage: MessageFns<ExternalServiceEndpoint>;
111
- export declare const ExternalServiceDefinitionMessage: MessageFns<ExternalServiceDefinition>;
112
- export declare const AddExternalServicesMessage: MessageFns<AddExternalServices>;
113
- /**
114
- * External services gRPC service definition, for use with nice-grpc's client factory.
115
- */
116
- export declare const ExternalServicesDefinition: {
117
- readonly name: 'ExternalServices';
118
- readonly fullName: 'Cratis.Chronicle.Contracts.ExternalServices.ExternalServices';
119
- readonly methods: {
120
- readonly add: {
121
- readonly name: 'Add';
122
- readonly requestType: MessageFns<AddExternalServices>;
123
- readonly requestStream: false;
124
- readonly responseType: MessageFns<Empty>;
125
- readonly responseStream: false;
126
- readonly options: {};
127
- };
128
- };
129
- };
130
- /**
131
- * External services service client interface.
132
- */
133
- export interface ExternalServicesClient<CallOptionsExt = {}> {
134
- add(request: DeepPartial<AddExternalServices>, options?: CallOptions & CallOptionsExt): Promise<Empty>;
135
- }
136
- export {};
137
- //# sourceMappingURL=ExternalServicesContracts.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ExternalServicesContracts.d.ts","sourceRoot":"","sources":["../../externalServices/ExternalServicesContracts.ts"],"names":[],"mappings":"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"}