@cratis/arc 22.142.0 → 22.144.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 (87) hide show
  1. package/commands/Command.ts +6 -0
  2. package/commands/for_Command/PayInvoice.ts +20 -0
  3. package/commands/for_Command/when_getting_the_slice_location.ts +21 -0
  4. package/dist/cjs/commands/Command.d.ts +2 -0
  5. package/dist/cjs/commands/Command.d.ts.map +1 -1
  6. package/dist/cjs/commands/Command.js +4 -0
  7. package/dist/cjs/commands/Command.js.map +1 -1
  8. package/dist/cjs/queries/ObservableQueryFor.d.ts +2 -0
  9. package/dist/cjs/queries/ObservableQueryFor.d.ts.map +1 -1
  10. package/dist/cjs/queries/ObservableQueryFor.js +4 -0
  11. package/dist/cjs/queries/ObservableQueryFor.js.map +1 -1
  12. package/dist/cjs/queries/QueryFor.d.ts +2 -0
  13. package/dist/cjs/queries/QueryFor.d.ts.map +1 -1
  14. package/dist/cjs/queries/QueryFor.js +4 -0
  15. package/dist/cjs/queries/QueryFor.js.map +1 -1
  16. package/dist/cjs/reflection/SliceLocation.d.ts +12 -0
  17. package/dist/cjs/reflection/SliceLocation.d.ts.map +1 -0
  18. package/dist/cjs/reflection/SliceLocation.js +76 -0
  19. package/dist/cjs/reflection/SliceLocation.js.map +1 -0
  20. package/dist/cjs/reflection/index.d.ts +1 -0
  21. package/dist/cjs/reflection/index.d.ts.map +1 -1
  22. package/dist/cjs/reflection/index.js +2 -0
  23. package/dist/cjs/reflection/index.js.map +1 -1
  24. package/dist/esm/commands/Command.d.ts +2 -0
  25. package/dist/esm/commands/Command.d.ts.map +1 -1
  26. package/dist/esm/commands/Command.js +4 -0
  27. package/dist/esm/commands/Command.js.map +1 -1
  28. package/dist/esm/commands/for_Command/PayInvoice.d.ts +11 -0
  29. package/dist/esm/commands/for_Command/PayInvoice.d.ts.map +1 -0
  30. package/dist/esm/commands/for_Command/PayInvoice.js +14 -0
  31. package/dist/esm/commands/for_Command/PayInvoice.js.map +1 -0
  32. package/dist/esm/commands/for_Command/when_getting_the_slice_location.d.ts +2 -0
  33. package/dist/esm/commands/for_Command/when_getting_the_slice_location.d.ts.map +1 -0
  34. package/dist/esm/commands/for_Command/when_getting_the_slice_location.js +15 -0
  35. package/dist/esm/commands/for_Command/when_getting_the_slice_location.js.map +1 -0
  36. package/dist/esm/queries/ObservableQueryFor.d.ts +2 -0
  37. package/dist/esm/queries/ObservableQueryFor.d.ts.map +1 -1
  38. package/dist/esm/queries/ObservableQueryFor.js +4 -0
  39. package/dist/esm/queries/ObservableQueryFor.js.map +1 -1
  40. package/dist/esm/queries/QueryFor.d.ts +2 -0
  41. package/dist/esm/queries/QueryFor.d.ts.map +1 -1
  42. package/dist/esm/queries/QueryFor.js +4 -0
  43. package/dist/esm/queries/QueryFor.js.map +1 -1
  44. package/dist/esm/queries/for_ObservableQueryFor/when_getting_the_slice_location.d.ts +2 -0
  45. package/dist/esm/queries/for_ObservableQueryFor/when_getting_the_slice_location.d.ts.map +1 -0
  46. package/dist/esm/queries/for_ObservableQueryFor/when_getting_the_slice_location.js +27 -0
  47. package/dist/esm/queries/for_ObservableQueryFor/when_getting_the_slice_location.js.map +1 -0
  48. package/dist/esm/queries/for_QueryFor/when_getting_the_slice_location.d.ts +2 -0
  49. package/dist/esm/queries/for_QueryFor/when_getting_the_slice_location.d.ts.map +1 -0
  50. package/dist/esm/queries/for_QueryFor/when_getting_the_slice_location.js +27 -0
  51. package/dist/esm/queries/for_QueryFor/when_getting_the_slice_location.js.map +1 -0
  52. package/dist/esm/reflection/SliceLocation.d.ts +12 -0
  53. package/dist/esm/reflection/SliceLocation.d.ts.map +1 -0
  54. package/dist/esm/reflection/SliceLocation.js +74 -0
  55. package/dist/esm/reflection/SliceLocation.js.map +1 -0
  56. package/dist/esm/reflection/for_SliceLocation/when_converting_to_string.d.ts +2 -0
  57. package/dist/esm/reflection/for_SliceLocation/when_converting_to_string.d.ts.map +1 -0
  58. package/dist/esm/reflection/for_SliceLocation/when_converting_to_string.js +6 -0
  59. package/dist/esm/reflection/for_SliceLocation/when_converting_to_string.js.map +1 -0
  60. package/dist/esm/reflection/for_SliceLocation/when_getting_it_of_a_type.d.ts +2 -0
  61. package/dist/esm/reflection/for_SliceLocation/when_getting_it_of_a_type.d.ts.map +1 -0
  62. package/dist/esm/reflection/for_SliceLocation/when_getting_it_of_a_type.js +29 -0
  63. package/dist/esm/reflection/for_SliceLocation/when_getting_it_of_a_type.js.map +1 -0
  64. package/dist/esm/reflection/for_SliceLocation/when_getting_it_of_an_instance_whose_class_declares_none.d.ts +2 -0
  65. package/dist/esm/reflection/for_SliceLocation/when_getting_it_of_an_instance_whose_class_declares_none.d.ts.map +1 -0
  66. package/dist/esm/reflection/for_SliceLocation/when_getting_it_of_an_instance_whose_class_declares_none.js +14 -0
  67. package/dist/esm/reflection/for_SliceLocation/when_getting_it_of_an_instance_whose_class_declares_none.js.map +1 -0
  68. package/dist/esm/reflection/for_SliceLocation/when_getting_it_of_an_instance_whose_class_declares_one.d.ts +2 -0
  69. package/dist/esm/reflection/for_SliceLocation/when_getting_it_of_an_instance_whose_class_declares_one.d.ts.map +1 -0
  70. package/dist/esm/reflection/for_SliceLocation/when_getting_it_of_an_instance_whose_class_declares_one.js +12 -0
  71. package/dist/esm/reflection/for_SliceLocation/when_getting_it_of_an_instance_whose_class_declares_one.js.map +1 -0
  72. package/dist/esm/reflection/index.d.ts +1 -0
  73. package/dist/esm/reflection/index.d.ts.map +1 -1
  74. package/dist/esm/reflection/index.js +1 -0
  75. package/dist/esm/reflection/index.js.map +1 -1
  76. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  77. package/package.json +3 -3
  78. package/queries/ObservableQueryFor.ts +6 -0
  79. package/queries/QueryFor.ts +6 -0
  80. package/queries/for_ObservableQueryFor/when_getting_the_slice_location.ts +37 -0
  81. package/queries/for_QueryFor/when_getting_the_slice_location.ts +37 -0
  82. package/reflection/SliceLocation.ts +78 -0
  83. package/reflection/for_SliceLocation/when_converting_to_string.ts +9 -0
  84. package/reflection/for_SliceLocation/when_getting_it_of_a_type.ts +38 -0
  85. package/reflection/for_SliceLocation/when_getting_it_of_an_instance_whose_class_declares_none.ts +20 -0
  86. package/reflection/for_SliceLocation/when_getting_it_of_an_instance_whose_class_declares_one.ts +18 -0
  87. package/reflection/index.ts +1 -0
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@cratis/arc",
4
- "version": "22.142.0",
4
+ "version": "22.144.0",
5
5
  "description": "TypeScript command, query, validation, identity, and messaging runtime for Cratis Arc — the CQRS application framework for ASP.NET Core — used by generated proxies.",
6
6
  "keywords": [
7
7
  "cratis",
@@ -118,10 +118,10 @@
118
118
  "up": "yarn g:up"
119
119
  },
120
120
  "dependencies": {
121
- "@cratis/fundamentals": "^7.25.1",
121
+ "@cratis/fundamentals": "^7.27.0",
122
122
  "rxjs": "^7.8.2"
123
123
  },
124
124
  "devDependencies": {
125
- "@cratis/fundamentals": "7.25.1"
125
+ "@cratis/fundamentals": "7.27.0"
126
126
  }
127
127
  }
@@ -19,6 +19,7 @@ import { UrlHelpers } from '../UrlHelpers.js';
19
19
  import type { GetHttpHeaders } from '../GetHttpHeaders.js';
20
20
  import type { ParameterDescriptor } from '../reflection/ParameterDescriptor.js';
21
21
  import { ParametersHelper } from '../reflection/ParametersHelper.js';
22
+ import { SliceLocation } from '../reflection/SliceLocation.js';
22
23
  import type { QueryHttpMethod } from './QueryHttpMethod.js';
23
24
  import { executeQueryHttpRequest } from './QueryHttpRequest.js';
24
25
 
@@ -32,6 +33,11 @@ export abstract class ObservableQueryFor<
32
33
  TDataType,
33
34
  TParameters = object,
34
35
  > implements IObservableQueryFor<TDataType, TParameters> {
36
+ /**
37
+ * Gets the {@link SliceLocation} of the query. Generated proxies override it with the location resolved from the backend namespace.
38
+ */
39
+ static readonly sliceLocation: SliceLocation = SliceLocation.empty;
40
+
35
41
  private _microservice: string;
36
42
  private _apiBasePath: string;
37
43
  private _origin: string;
@@ -12,6 +12,7 @@ import { Sorting } from './Sorting.js';
12
12
  import { GetHttpHeaders } from '../GetHttpHeaders.js';
13
13
  import { ParameterDescriptor } from '../reflection/ParameterDescriptor.js';
14
14
  import { ParametersHelper } from '../reflection/ParametersHelper.js';
15
+ import { SliceLocation } from '../reflection/SliceLocation.js';
15
16
  import { QueryHttpMethod } from './QueryHttpMethod.js';
16
17
  import { executeQueryHttpRequest } from './QueryHttpRequest.js';
17
18
  import { isAbortError } from './isAbortError.js';
@@ -21,6 +22,11 @@ import { isAbortError } from './isAbortError.js';
21
22
  * @template TDataType Type of data returned by the query.
22
23
  */
23
24
  export abstract class QueryFor<TDataType, TParameters = object> implements IQueryFor<TDataType, TParameters> {
25
+ /**
26
+ * Gets the {@link SliceLocation} of the query. Generated proxies override it with the location resolved from the backend namespace.
27
+ */
28
+ static readonly sliceLocation: SliceLocation = SliceLocation.empty;
29
+
24
30
  private _microservice: string;
25
31
  private _apiBasePath: string;
26
32
  private _origin: string;
@@ -0,0 +1,37 @@
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 { ObservableQueryFor } from '../ObservableQueryFor.js';
5
+ import { IQuery } from '../IQuery.js';
6
+ import { TestObservableQuery } from './given/TestQueries.js';
7
+ import { ParameterDescriptor } from '../../reflection/ParameterDescriptor.js';
8
+ import { SliceLocation } from '../../reflection/SliceLocation.js';
9
+
10
+ class ObserveInvoices extends ObservableQueryFor<string[]> {
11
+ static readonly sliceLocation: SliceLocation = new SliceLocation('Billing', 'Invoices', 'Listing');
12
+ readonly route = '/api/billing/invoices/observe';
13
+ readonly defaultValue: string[] = [];
14
+ readonly parameterDescriptors: ParameterDescriptor[] = [];
15
+
16
+ get requiredRequestParameters(): string[] {
17
+ return [];
18
+ }
19
+
20
+ constructor() {
21
+ super(String, true);
22
+ }
23
+ }
24
+
25
+ describe('when getting the slice location', () => {
26
+ let declared: SliceLocation | undefined;
27
+ let undeclared: SliceLocation | undefined;
28
+
29
+ beforeEach(() => {
30
+ const query: IQuery = new ObserveInvoices();
31
+ declared = SliceLocation.of(query);
32
+ undeclared = SliceLocation.of(new TestObservableQuery());
33
+ });
34
+
35
+ it('should return the static slice location of the proxy class', () => declared!.should.equal(ObserveInvoices.sliceLocation));
36
+ it('should return the empty slice location when the class declares none', () => undeclared!.should.equal(SliceLocation.empty));
37
+ });
@@ -0,0 +1,37 @@
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 { QueryFor } from '../QueryFor.js';
5
+ import { IQuery } from '../IQuery.js';
6
+ import { TestQueryFor } from './given/TestQueries.js';
7
+ import { ParameterDescriptor } from '../../reflection/ParameterDescriptor.js';
8
+ import { SliceLocation } from '../../reflection/SliceLocation.js';
9
+
10
+ class AllInvoices extends QueryFor<string[]> {
11
+ static readonly sliceLocation: SliceLocation = new SliceLocation('Billing', 'Invoices', 'Listing');
12
+ readonly route = '/api/billing/invoices';
13
+ readonly defaultValue: string[] = [];
14
+ readonly parameterDescriptors: ParameterDescriptor[] = [];
15
+
16
+ get requiredRequestParameters(): string[] {
17
+ return [];
18
+ }
19
+
20
+ constructor() {
21
+ super(String, true);
22
+ }
23
+ }
24
+
25
+ describe('when getting the slice location', () => {
26
+ let declared: SliceLocation | undefined;
27
+ let undeclared: SliceLocation | undefined;
28
+
29
+ beforeEach(() => {
30
+ const query: IQuery = new AllInvoices();
31
+ declared = SliceLocation.of(query);
32
+ undeclared = SliceLocation.of(new TestQueryFor());
33
+ });
34
+
35
+ it('should return the static slice location of the proxy class', () => declared!.should.equal(AllInvoices.sliceLocation));
36
+ it('should return the empty slice location when the class declares none', () => undeclared!.should.equal(SliceLocation.empty));
37
+ });
@@ -0,0 +1,78 @@
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
+ /**
5
+ * Represents a class, abstract or concrete, that may declare a static `sliceLocation` member.
6
+ */
7
+ export type SliceLocationDeclaringType = abstract new (...args: never[]) => unknown;
8
+
9
+ function isSliceLocationShaped(value: unknown): value is { module: string, feature: string, slice: string } {
10
+ if (typeof value !== 'object' || value === null) {
11
+ return false;
12
+ }
13
+ const candidate = value as Record<string, unknown>;
14
+ return typeof candidate.module === 'string' && typeof candidate.feature === 'string' && typeof candidate.slice === 'string';
15
+ }
16
+
17
+ /**
18
+ * Represents where a command or query lives: the module, feature and slice resolved from its backend namespace.
19
+ * @remarks
20
+ * Generated proxies carry it as the static `sliceLocation` member, resolved from the same namespace mapping as the
21
+ * folder the proxy is generated to. When the namespace is too shallow for all three parts, the deepest parts are
22
+ * filled and the rest are empty strings, never null.
23
+ *
24
+ * The location is static metadata on the proxy class only. Instances carry no `sliceLocation` member, because a
25
+ * command or query may itself have a property named `SliceLocation`, which the generated accessor would clash with.
26
+ * Read it with {@link SliceLocation.of} for an instance or {@link SliceLocation.ofType} for a class.
27
+ */
28
+ export class SliceLocation {
29
+ /**
30
+ * Gets a slice location where every part is empty.
31
+ */
32
+ static readonly empty: SliceLocation = new SliceLocation('', '', '');
33
+
34
+ /**
35
+ * Initializes a new instance of the {@link SliceLocation} class.
36
+ * @param module The module the slice belongs to.
37
+ * @param feature The feature the slice belongs to.
38
+ * @param slice The slice itself.
39
+ */
40
+ constructor(readonly module: string, readonly feature: string, readonly slice: string) {
41
+ }
42
+
43
+ /**
44
+ * Gets the slice location declared on the class of an instance, such as a generated command or query proxy.
45
+ * @param instance The instance to get for.
46
+ * @returns The declared {@link SliceLocation}, or {@link SliceLocation.empty} when the class declares none.
47
+ */
48
+ static of(instance: object): SliceLocation {
49
+ return SliceLocation.ofType(instance.constructor as SliceLocationDeclaringType);
50
+ }
51
+
52
+ /**
53
+ * Gets the slice location declared as the static `sliceLocation` member of a type, such as a generated command or query proxy class.
54
+ * @param type The type to get for.
55
+ * @returns The declared {@link SliceLocation}, or {@link SliceLocation.empty} when the type declares none.
56
+ */
57
+ static ofType(type: SliceLocationDeclaringType): SliceLocation {
58
+ const declared = (type as { sliceLocation?: unknown }).sliceLocation;
59
+ if (declared instanceof SliceLocation) {
60
+ return declared;
61
+ }
62
+
63
+ // A proxy compiled against another copy of @cratis/arc carries an instance of that copy's class.
64
+ if (isSliceLocationShaped(declared)) {
65
+ return new SliceLocation(declared.module, declared.feature, declared.slice);
66
+ }
67
+
68
+ return SliceLocation.empty;
69
+ }
70
+
71
+ /**
72
+ * Gets the parts that are set, joined with a forward slash.
73
+ * @returns The slice location as a path, for example `Billing/Invoices/Pay`.
74
+ */
75
+ toString(): string {
76
+ return [this.module, this.feature, this.slice].filter(part => part.length > 0).join('/');
77
+ }
78
+ }
@@ -0,0 +1,9 @@
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 { SliceLocation } from '../SliceLocation.js';
5
+
6
+ describe('when converting to string', () => {
7
+ it('should join all parts with a forward slash', () => new SliceLocation('Billing', 'Invoices', 'Pay').toString().should.equal('Billing/Invoices/Pay'));
8
+ it('should leave out empty parts', () => new SliceLocation('', 'Invoices', 'Pay').toString().should.equal('Invoices/Pay'));
9
+ });
@@ -0,0 +1,38 @@
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 { SliceLocation } from '../SliceLocation.js';
5
+
6
+ abstract class Declaring {
7
+ static readonly sliceLocation: SliceLocation = new SliceLocation('Billing', 'Invoices', 'Pay');
8
+ }
9
+
10
+ class NotDeclaring {
11
+ }
12
+
13
+ class DeclaringOneFromAnotherCopy {
14
+ static readonly sliceLocation = { module: 'Billing', feature: 'Invoices', slice: 'Refund' };
15
+ }
16
+
17
+ class DeclaringSomethingElse {
18
+ static readonly sliceLocation = 'Billing/Invoices/Pay';
19
+ }
20
+
21
+ describe('when getting it of a type', () => {
22
+ let declared: SliceLocation;
23
+ let undeclared: SliceLocation;
24
+ let notASliceLocation: SliceLocation;
25
+ let fromAnotherCopy: SliceLocation;
26
+
27
+ beforeEach(() => {
28
+ declared = SliceLocation.ofType(Declaring);
29
+ undeclared = SliceLocation.ofType(NotDeclaring);
30
+ notASliceLocation = SliceLocation.ofType(DeclaringSomethingElse);
31
+ fromAnotherCopy = SliceLocation.ofType(DeclaringOneFromAnotherCopy);
32
+ });
33
+
34
+ it('should return the declared slice location', () => declared.should.equal(Declaring.sliceLocation));
35
+ it('should return the empty slice location when the type declares none', () => undeclared.should.equal(SliceLocation.empty));
36
+ it('should return a slice location with the parts declared by another copy of the class', () => fromAnotherCopy.should.deep.equal(new SliceLocation('Billing', 'Invoices', 'Refund')));
37
+ it('should return the empty slice location when the static member is not a slice location', () => notASliceLocation.should.equal(SliceLocation.empty));
38
+ });
@@ -0,0 +1,20 @@
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 { SliceLocation } from '../SliceLocation.js';
5
+
6
+ class NotDeclaring {
7
+ }
8
+
9
+ describe('when getting it of an instance whose class declares none', () => {
10
+ let result: SliceLocation;
11
+
12
+ beforeEach(() => {
13
+ result = SliceLocation.of(new NotDeclaring());
14
+ });
15
+
16
+ it('should return the empty slice location', () => result.should.equal(SliceLocation.empty));
17
+ it('should have an empty module', () => result.module.should.equal(''));
18
+ it('should have an empty feature', () => result.feature.should.equal(''));
19
+ it('should have an empty slice', () => result.slice.should.equal(''));
20
+ });
@@ -0,0 +1,18 @@
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 { SliceLocation } from '../SliceLocation.js';
5
+
6
+ class Declaring {
7
+ static readonly sliceLocation: SliceLocation = new SliceLocation('Billing', 'Invoices', 'Pay');
8
+ }
9
+
10
+ describe('when getting it of an instance whose class declares one', () => {
11
+ let result: SliceLocation;
12
+
13
+ beforeEach(() => {
14
+ result = SliceLocation.of(new Declaring());
15
+ });
16
+
17
+ it('should return the declared slice location', () => result.should.equal(Declaring.sliceLocation));
18
+ });
@@ -5,3 +5,4 @@ export * from './IHaveParameters.js';
5
5
  export * from './ParameterDescriptor.js';
6
6
  export * from './ParametersHelper.js';
7
7
  export * from './PropertyDescriptor.js';
8
+ export * from './SliceLocation.js';