@cratis/arc 22.139.0 → 22.140.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 (66) hide show
  1. package/UrlHelpers.ts +20 -1
  2. package/commands/Command.ts +7 -1
  3. package/commands/for_Command/when_validating/with_null_required_property.ts +4 -1
  4. package/commands/for_Command/when_validating/with_required_property_missing.ts +7 -1
  5. package/dist/cjs/UrlHelpers.d.ts +1 -0
  6. package/dist/cjs/UrlHelpers.d.ts.map +1 -1
  7. package/dist/cjs/UrlHelpers.js +17 -1
  8. package/dist/cjs/UrlHelpers.js.map +1 -1
  9. package/dist/cjs/commands/Command.d.ts.map +1 -1
  10. package/dist/cjs/commands/Command.js +5 -1
  11. package/dist/cjs/commands/Command.js.map +1 -1
  12. package/dist/cjs/queries/ObservableQueryMultiplexer.d.ts.map +1 -1
  13. package/dist/cjs/queries/ObservableQueryMultiplexer.js +2 -1
  14. package/dist/cjs/queries/ObservableQueryMultiplexer.js.map +1 -1
  15. package/dist/cjs/validation/ValidationResult.d.ts.map +1 -1
  16. package/dist/cjs/validation/ValidationResult.js +4 -1
  17. package/dist/cjs/validation/ValidationResult.js.map +1 -1
  18. package/dist/cjs/validation/ValidationResultReasonDetail.d.ts +4 -0
  19. package/dist/cjs/validation/ValidationResultReasonDetail.d.ts.map +1 -0
  20. package/dist/cjs/validation/ValidationResultReasonDetail.js +15 -0
  21. package/dist/cjs/validation/ValidationResultReasonDetail.js.map +1 -0
  22. package/dist/cjs/validation/index.d.ts +1 -0
  23. package/dist/cjs/validation/index.d.ts.map +1 -1
  24. package/dist/cjs/validation/index.js +2 -0
  25. package/dist/cjs/validation/index.js.map +1 -1
  26. package/dist/esm/UrlHelpers.d.ts +1 -0
  27. package/dist/esm/UrlHelpers.d.ts.map +1 -1
  28. package/dist/esm/UrlHelpers.js +17 -2
  29. package/dist/esm/UrlHelpers.js.map +1 -1
  30. package/dist/esm/commands/Command.d.ts.map +1 -1
  31. package/dist/esm/commands/Command.js +5 -1
  32. package/dist/esm/commands/Command.js.map +1 -1
  33. package/dist/esm/commands/for_Command/when_validating/with_null_required_property.js +4 -1
  34. package/dist/esm/commands/for_Command/when_validating/with_null_required_property.js.map +1 -1
  35. package/dist/esm/commands/for_Command/when_validating/with_required_property_missing.js +7 -1
  36. package/dist/esm/commands/for_Command/when_validating/with_required_property_missing.js.map +1 -1
  37. package/dist/esm/for_UrlHelpers/when_building_query_params/with_object_values.d.ts +2 -0
  38. package/dist/esm/for_UrlHelpers/when_building_query_params/with_object_values.d.ts.map +1 -0
  39. package/dist/esm/for_UrlHelpers/when_building_query_params/with_object_values.js +23 -0
  40. package/dist/esm/for_UrlHelpers/when_building_query_params/with_object_values.js.map +1 -0
  41. package/dist/esm/queries/ObservableQueryMultiplexer.d.ts.map +1 -1
  42. package/dist/esm/queries/ObservableQueryMultiplexer.js +2 -1
  43. package/dist/esm/queries/ObservableQueryMultiplexer.js.map +1 -1
  44. package/dist/esm/queries/for_ObservableQueryMultiplexer/when_building_a_subscription_request/with_dictionary_values.d.ts +2 -0
  45. package/dist/esm/queries/for_ObservableQueryMultiplexer/when_building_a_subscription_request/with_dictionary_values.d.ts.map +1 -0
  46. package/dist/esm/queries/for_ObservableQueryMultiplexer/when_building_a_subscription_request/with_dictionary_values.js +22 -0
  47. package/dist/esm/queries/for_ObservableQueryMultiplexer/when_building_a_subscription_request/with_dictionary_values.js.map +1 -0
  48. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  49. package/dist/esm/validation/ValidationResult.d.ts.map +1 -1
  50. package/dist/esm/validation/ValidationResult.js +4 -1
  51. package/dist/esm/validation/ValidationResult.js.map +1 -1
  52. package/dist/esm/validation/ValidationResultReasonDetail.d.ts +4 -0
  53. package/dist/esm/validation/ValidationResultReasonDetail.d.ts.map +1 -0
  54. package/dist/esm/validation/ValidationResultReasonDetail.js +13 -0
  55. package/dist/esm/validation/ValidationResultReasonDetail.js.map +1 -0
  56. package/dist/esm/validation/index.d.ts +1 -0
  57. package/dist/esm/validation/index.d.ts.map +1 -1
  58. package/dist/esm/validation/index.js +1 -0
  59. package/dist/esm/validation/index.js.map +1 -1
  60. package/for_UrlHelpers/when_building_query_params/with_object_values.ts +30 -0
  61. package/package.json +1 -1
  62. package/queries/ObservableQueryMultiplexer.ts +2 -1
  63. package/queries/for_ObservableQueryMultiplexer/when_building_a_subscription_request/with_dictionary_values.ts +27 -0
  64. package/validation/ValidationResult.ts +4 -1
  65. package/validation/ValidationResultReasonDetail.ts +13 -0
  66. package/validation/index.ts +1 -0
@@ -1 +1 @@
1
- {"version":3,"file":"ValidationResult.d.ts","sourceRoot":"","sources":["../../../validation/ValidationResult.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAOzE,qBAAa,gBAAgB;IAarB,QAAQ,CAAC,QAAQ,EAAE,wBAAwB;IAC3C,QAAQ,CAAC,OAAO,EAAE,MAAM;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE;IAC1B,QAAQ,CAAC,KAAK,EAAE,GAAG;IACnB,QAAQ,CAAC,MAAM,EAAE,sBAAsB;IACvC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM;IANlC,YACa,QAAQ,EAAE,wBAAwB,EAClC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EAAE,EACjB,KAAK,EAAE,GAAG,EACV,MAAM,GAAE,sBAAoD,EAC5D,YAAY,CAAC,EAAE,MAAM,YAAA,EACjC;CACJ"}
1
+ {"version":3,"file":"ValidationResult.d.ts","sourceRoot":"","sources":["../../../validation/ValidationResult.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AASzE,qBAAa,gBAAgB;IAcrB,QAAQ,CAAC,QAAQ,EAAE,wBAAwB;IAC3C,QAAQ,CAAC,OAAO,EAAE,MAAM;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE;IAC1B,QAAQ,CAAC,KAAK,EAAE,GAAG;IACnB,QAAQ,CAAC,MAAM,EAAE,sBAAsB;IACvC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM;IANlC,YACa,QAAQ,EAAE,wBAAwB,EAClC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EAAE,EACjB,KAAK,EAAE,GAAG,EACV,MAAM,GAAE,sBAAoD,EAC5D,YAAY,CAAC,EAAE,MAAM,YAAA,EACjC;CACJ"}
@@ -4,6 +4,8 @@ import { ValidationResultReason } from './ValidationResultReason.js';
4
4
  // Licensed under the MIT license. See LICENSE file in the project root for full license information.
5
5
  /* eslint-disable @typescript-eslint/no-explicit-any */ /**
6
6
  * Represents a validation error with a message for one or more members.
7
+ * Client-generated missing required properties use `rule` with `ValidationResultReasonDetail.Required`.
8
+ * Their messages are framework diagnostics, not application-authored user-facing copy.
7
9
  */ class ValidationResult {
8
10
  severity;
9
11
  message;
@@ -14,7 +16,8 @@ import { ValidationResultReason } from './ValidationResultReason.js';
14
16
  /**
15
17
  * Initializes a new instance of the {@link ValidationResult} class.
16
18
  * @param severity The severity of the result.
17
- * @param message The message. A developer diagnostic when {@link reason} is anything but `rule`.
19
+ * @param message The message. A developer diagnostic when {@link reason} is anything but `rule`,
20
+ * or when the client supplies the `Required` reasonDetail.
18
21
  * @param members The members the result is attributed to.
19
22
  * @param state State associated with the result - the rule author's, carried straight through.
20
23
  * @param reason What composed the result. Defaults to `rule`, meaning an authored rule rejected the input.
@@ -1 +1 @@
1
- {"version":3,"file":"ValidationResult.js","sources":["../../../validation/ValidationResult.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { ValidationResultReason } from './ValidationResultReason.js';\nimport { ValidationResultSeverity } from './ValidationResultSeverity.js';\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\n/**\n * Represents a validation error with a message for one or more members.\n */\nexport class ValidationResult {\n /**\n * Initializes a new instance of the {@link ValidationResult} class.\n * @param severity The severity of the result.\n * @param message The message. A developer diagnostic when {@link reason} is anything but `rule`.\n * @param members The members the result is attributed to.\n * @param state State associated with the result - the rule author's, carried straight through.\n * @param reason What composed the result. Defaults to `rule`, meaning an authored rule rejected the input.\n * @param reasonDetail Which specific thing within {@link reason} produced the result - the name of the violated\n * constraint for `constraintViolation`, for instance. Undefined when the reason carries no finer identity.\n * Branch on this rather than matching {@link message}, which is prose and free to change.\n */\n constructor(\n readonly severity: ValidationResultSeverity,\n readonly message: string,\n readonly members: string[],\n readonly state: any,\n readonly reason: ValidationResultReason = ValidationResultReason.Rule,\n readonly reasonDetail?: string) {\n }\n}\n"],"names":["ValidationResult","reason","ValidationResultReason","Rule","reasonDetail","severity","message","members","state"],"mappings":";;AAAA;AACA;AAKA;;AAIC,IACM,MAAMA,gBAAAA,CAAAA;;;;;;;AACT;;;;;;;;;;QAWA,WAAA,CACI,QAA2C,EAC3C,OAAwB,EACxB,OAA0B,EAC1B,KAAmB,EACnB,MAASC,GAAiCC,sBAAAA,CAAuBC,IAAI,EAC5DC,YAAqB,CAAE;aALvBC,QAAAA,GAAAA,QAAAA;aACAC,OAAAA,GAAAA,OAAAA;aACAC,OAAAA,GAAAA,OAAAA;aACAC,KAAAA,GAAAA,KAAAA;aACAP,MAAAA,GAAAA,MAAAA;aACAG,YAAAA,GAAAA,YAAAA;AACb,IAAA;AACJ;;"}
1
+ {"version":3,"file":"ValidationResult.js","sources":["../../../validation/ValidationResult.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { ValidationResultReason } from './ValidationResultReason.js';\nimport { ValidationResultSeverity } from './ValidationResultSeverity.js';\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\n/**\n * Represents a validation error with a message for one or more members.\n * Client-generated missing required properties use `rule` with `ValidationResultReasonDetail.Required`.\n * Their messages are framework diagnostics, not application-authored user-facing copy.\n */\nexport class ValidationResult {\n /**\n * Initializes a new instance of the {@link ValidationResult} class.\n * @param severity The severity of the result.\n * @param message The message. A developer diagnostic when {@link reason} is anything but `rule`,\n * or when the client supplies the `Required` reasonDetail.\n * @param members The members the result is attributed to.\n * @param state State associated with the result - the rule author's, carried straight through.\n * @param reason What composed the result. Defaults to `rule`, meaning an authored rule rejected the input.\n * @param reasonDetail Which specific thing within {@link reason} produced the result - the name of the violated\n * constraint for `constraintViolation`, for instance. Undefined when the reason carries no finer identity.\n * Branch on this rather than matching {@link message}, which is prose and free to change.\n */\n constructor(\n readonly severity: ValidationResultSeverity,\n readonly message: string,\n readonly members: string[],\n readonly state: any,\n readonly reason: ValidationResultReason = ValidationResultReason.Rule,\n readonly reasonDetail?: string) {\n }\n}\n"],"names":["ValidationResult","reason","ValidationResultReason","Rule","reasonDetail","severity","message","members","state"],"mappings":";;AAAA;AACA;AAKA;;;;AAMC,IACM,MAAMA,gBAAAA,CAAAA;;;;;;;AACT;;;;;;;;;;;QAYA,WAAA,CACI,QAA2C,EAC3C,OAAwB,EACxB,OAA0B,EAC1B,KAAmB,EACnB,MAASC,GAAiCC,sBAAAA,CAAuBC,IAAI,EAC5DC,YAAqB,CAAE;aALvBC,QAAAA,GAAAA,QAAAA;aACAC,OAAAA,GAAAA,OAAAA;aACAC,OAAAA,GAAAA,OAAAA;aACAC,KAAAA,GAAAA,KAAAA;aACAP,MAAAA,GAAAA,MAAAA;aACAG,YAAAA,GAAAA,YAAAA;AACb,IAAA;AACJ;;"}
@@ -0,0 +1,4 @@
1
+ export declare const ValidationResultReasonDetail: {
2
+ readonly Required: 'Required';
3
+ };
4
+ //# sourceMappingURL=ValidationResultReasonDetail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ValidationResultReasonDetail.d.ts","sourceRoot":"","sources":["../../../validation/ValidationResultReasonDetail.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,4BAA4B;aAKrC,QAAQ,EAAE,UAAU;CACd,CAAC"}
@@ -0,0 +1,13 @@
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
+ * Holds well-known finer identities within a validation result's reason.
5
+ */ const ValidationResultReasonDetail = {
6
+ /**
7
+ * The client found a missing required command property. Used with `rule`.
8
+ * The message is framework-authored; map it to your own user-facing copy.
9
+ */ Required: 'Required'
10
+ };
11
+
12
+ export { ValidationResultReasonDetail };
13
+ //# sourceMappingURL=ValidationResultReasonDetail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ValidationResultReasonDetail.js","sources":["../../../validation/ValidationResultReasonDetail.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\n/**\n * Holds well-known finer identities within a validation result's reason.\n */\nexport const ValidationResultReasonDetail = {\n /**\n * The client found a missing required command property. Used with `rule`.\n * The message is framework-authored; map it to your own user-facing copy.\n */\n Required: 'Required'\n} as const;\n"],"names":["ValidationResultReasonDetail","Required"],"mappings":"AAAA;AACA;AAEA;;UAGaA,4BAAAA,GAA+B;AACxC;;;AAGC,QACDC,QAAAA,EAAU;AACd;;"}
@@ -1,6 +1,7 @@
1
1
  export * from './Validator.js';
2
2
  export * from './ValidationResult.js';
3
3
  export * from './ValidationResultReason.js';
4
+ export * from './ValidationResultReasonDetail.js';
4
5
  export * from './ValidationResultSeverity.js';
5
6
  export * from './IValidationRule.js';
6
7
  export * from './PropertyValidator.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../validation/index.ts"],"names":[],"mappings":"AAGA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AACtC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,4BAA4B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../validation/index.ts"],"names":[],"mappings":"AAGA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AACtC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,mCAAmC,CAAC;AAClD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,4BAA4B,CAAC"}
@@ -1,6 +1,7 @@
1
1
  export { Validator } from './Validator.js';
2
2
  export { ValidationResult } from './ValidationResult.js';
3
3
  export { ValidationResultReason } from './ValidationResultReason.js';
4
+ export { ValidationResultReasonDetail } from './ValidationResultReasonDetail.js';
4
5
  export { ValidationResultSeverity } from './ValidationResultSeverity.js';
5
6
  export { PropertyValidator } from './PropertyValidator.js';
6
7
  export { PropertyRule } from './PropertyRule.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../validation/index.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nexport * from './Validator.js';\nexport * from './ValidationResult.js';\nexport * from './ValidationResultReason.js';\nexport * from './ValidationResultSeverity.js';\nexport * from './IValidationRule.js';\nexport * from './PropertyValidator.js';\nexport * from './PropertyRule.js';\nexport * from './RuleBuilder.js';\nexport * from './RuleBuilderExtensions.js';\nexport * from './rules/NotEmptyRule.js';\nexport * from './rules/LengthRules.js';\nexport * from './rules/EmailRule.js';\nexport * from './rules/RegexRule.js';\nexport * from './rules/ComparisonRules.js';\n"],"names":[],"mappings":";;;;;;;;;;;;;;AAAA;AACA"}
1
+ {"version":3,"file":"index.js","sources":["../../../validation/index.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nexport * from './Validator.js';\nexport * from './ValidationResult.js';\nexport * from './ValidationResultReason.js';\nexport * from './ValidationResultReasonDetail.js';\nexport * from './ValidationResultSeverity.js';\nexport * from './IValidationRule.js';\nexport * from './PropertyValidator.js';\nexport * from './PropertyRule.js';\nexport * from './RuleBuilder.js';\nexport * from './RuleBuilderExtensions.js';\nexport * from './rules/NotEmptyRule.js';\nexport * from './rules/LengthRules.js';\nexport * from './rules/EmailRule.js';\nexport * from './rules/RegexRule.js';\nexport * from './rules/ComparisonRules.js';\n"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA;AACA"}
@@ -0,0 +1,30 @@
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 { describe, it } from 'vitest';
5
+ import { UrlHelpers } from '../../UrlHelpers.js';
6
+
7
+ const parts = { quoted: '"abc"', number: '42', comma: 'a,b' };
8
+
9
+ describe('when building query params with dictionary values', () => {
10
+ it('should encode one JSON object value', () => {
11
+ const result = UrlHelpers.buildQueryParams({ parts });
12
+ result.getAll('parts').should.deep.equal([JSON.stringify(parts)]);
13
+ });
14
+
15
+ it('should serialize an empty dictionary', () => {
16
+ UrlHelpers.buildQueryParams({ parts: {} }).get('parts')!.should.equal('{}');
17
+ });
18
+
19
+ it('should preserve existing route parameter serialization', () => {
20
+ const result = UrlHelpers.replaceRouteParameters('/parts/{parts}', { parts });
21
+ result.route.should.equal('/parts/%5Bobject%20Object%5D');
22
+ });
23
+
24
+ it('should preserve existing scalar and array serialization', () => {
25
+ const result = UrlHelpers.buildQueryParams({ count: 42, enabled: true, names: ['a', 'b'] });
26
+ result.get('count')!.should.equal('42');
27
+ result.get('enabled')!.should.equal('true');
28
+ result.getAll('names').should.deep.equal(['a', 'b']);
29
+ });
30
+ });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@cratis/arc",
4
- "version": "22.139.0",
4
+ "version": "22.140.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",
@@ -7,6 +7,7 @@ import { DataReceived } from './ObservableQueryConnection.js';
7
7
  import { SubscriptionRequest } from './WebSocketHubConnection.js';
8
8
  import { Globals } from '../Globals.js';
9
9
  import { MultiplexerConnectionState } from './ObservableQueryDiagnosticsSnapshot.js';
10
+ import { formatObjectQueryValue } from '../UrlHelpers.js';
10
11
 
11
12
  /* eslint-disable @typescript-eslint/no-explicit-any */
12
13
 
@@ -128,7 +129,7 @@ export class ObservableQueryMultiplexer {
128
129
  for (const [key, value] of Object.entries(a)) {
129
130
  if (pagingAndSortingKeys.has(key)) continue;
130
131
  if (value === undefined || value === null) continue;
131
- remaining[key] = String(value);
132
+ remaining[key] = formatObjectQueryValue(value);
132
133
  hasRemaining = true;
133
134
  }
134
135
 
@@ -0,0 +1,27 @@
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 { describe, it } from 'vitest';
5
+ import { ObservableQueryMultiplexer } from '../../ObservableQueryMultiplexer.js';
6
+ import { SubscriptionRequest } from '../../WebSocketHubConnection.js';
7
+
8
+ const parts = { quoted: '"abc"', number: '42', comma: 'a,b' };
9
+
10
+ describe('when building a subscription request with dictionary values', () => {
11
+ it('should send the dictionary as one JSON string argument', () => {
12
+ let received: SubscriptionRequest | undefined;
13
+ const multiplexer = new ObservableQueryMultiplexer(1, () => ({
14
+ queryCount: 0, lastPingLatency: 0, averageLatency: 0, isConnected: false,
15
+ subscribe: (_id, request) => { received = request; },
16
+ unsubscribe: () => {}, dispose: () => {}
17
+ }));
18
+ const date = new Date('2026-10-24T10:00:00Z');
19
+ const unsubscribe = multiplexer.subscribe('Parts.Get', { parts, count: 42, names: ['a', 'b'], date }, () => {});
20
+ received!.arguments!.parts!.should.equal(JSON.stringify(parts));
21
+ received!.arguments!.count!.should.equal('42');
22
+ received!.arguments!.names!.should.equal('a,b');
23
+ received!.arguments!.date!.should.equal(String(date));
24
+ unsubscribe();
25
+ multiplexer.dispose();
26
+ });
27
+ });
@@ -8,12 +8,15 @@ import { ValidationResultSeverity } from './ValidationResultSeverity.js';
8
8
 
9
9
  /**
10
10
  * Represents a validation error with a message for one or more members.
11
+ * Client-generated missing required properties use `rule` with `ValidationResultReasonDetail.Required`.
12
+ * Their messages are framework diagnostics, not application-authored user-facing copy.
11
13
  */
12
14
  export class ValidationResult {
13
15
  /**
14
16
  * Initializes a new instance of the {@link ValidationResult} class.
15
17
  * @param severity The severity of the result.
16
- * @param message The message. A developer diagnostic when {@link reason} is anything but `rule`.
18
+ * @param message The message. A developer diagnostic when {@link reason} is anything but `rule`,
19
+ * or when the client supplies the `Required` reasonDetail.
17
20
  * @param members The members the result is attributed to.
18
21
  * @param state State associated with the result - the rule author's, carried straight through.
19
22
  * @param reason What composed the result. Defaults to `rule`, meaning an authored rule rejected the input.
@@ -0,0 +1,13 @@
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
+ * Holds well-known finer identities within a validation result's reason.
6
+ */
7
+ export const ValidationResultReasonDetail = {
8
+ /**
9
+ * The client found a missing required command property. Used with `rule`.
10
+ * The message is framework-authored; map it to your own user-facing copy.
11
+ */
12
+ Required: 'Required'
13
+ } as const;
@@ -4,6 +4,7 @@
4
4
  export * from './Validator.js';
5
5
  export * from './ValidationResult.js';
6
6
  export * from './ValidationResultReason.js';
7
+ export * from './ValidationResultReasonDetail.js';
7
8
  export * from './ValidationResultSeverity.js';
8
9
  export * from './IValidationRule.js';
9
10
  export * from './PropertyValidator.js';