@registrystack/client 0.38.0 → 0.40.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/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # @registrystack/client
2
2
 
3
- One versioned Node.js package for the Discovery, Evidence, Relay, Base Registry
4
- Engine, Casework, and Messaging client APIs in Registry Stack.
3
+ One versioned Node.js package for the Discovery, Evidence, Base Registry
4
+ Engine, Casework, Messaging, and Scheduling client APIs in Registry Stack.
5
5
 
6
6
  ## Install
7
7
 
@@ -17,7 +17,7 @@ bindings.
17
17
  ## Usage
18
18
 
19
19
  ```js
20
- const { discovery, evidence, relay, breg, casework, messaging } = require('@registrystack/client');
20
+ const { discovery, evidence, breg, casework, messaging, scheduling } = require('@registrystack/client');
21
21
 
22
22
  const registry = new breg.BaseRegistryClient({
23
23
  baseUrl: 'https://registry.example.invalid/',
@@ -28,6 +28,9 @@ const work = new casework.CaseworkClient({
28
28
  const messages = new messaging.MessagingClient({
29
29
  baseUrl: 'https://messaging.example.invalid/',
30
30
  });
31
+ const appointments = new scheduling.SchedulingClient({
32
+ baseUrl: 'https://scheduling.example.invalid/',
33
+ });
31
34
  ```
32
35
 
33
36
  ## Products
@@ -36,13 +39,14 @@ const messages = new messaging.MessagingClient({
36
39
  curated index.
37
40
  - `evidence`: Evidence Gateway, request and verify signed minimum-disclosure
38
41
  assertions.
39
- - `relay`: Registry Relay, scoped read-only APIs over existing sources.
40
42
  - `breg`: Base Registry Engine, records, contracts, writes, lifecycle, and typed
41
43
  applied-request result navigation.
42
44
  - `casework`: Registry Casework, staff inbox, claims, drafts, decisions,
43
45
  recovery, history, holdings, and directory bootstrap.
44
46
  - `messaging`: Registry Messaging, submit, inspect, cancel, and preview
45
47
  institution-owned messages.
48
+ - `scheduling`: Registry Scheduling, published offerings, availability,
49
+ holds, and appointments over operator-anchored supply.
46
50
 
47
51
  Each product remains in its own namespace because its routing,
48
52
  authentication, errors, and verification rules are different.
@@ -80,11 +84,21 @@ descriptions grant no authority, so select the opaque create, patch, and
80
84
  lifecycle authorities from that same contract before executing a mutation.
81
85
  Methods ending in `Json` keep values exact across the Node number boundary:
82
86
  they accept domain JSON text and return `valueJson` alongside the usual
83
- trace, ETag, location, and opaque continuation. The client never retries a
84
- mutation automatically. See
87
+ trace, ETag, location, and opaque continuation. See
85
88
  [Exact JSON in Node](https://docs.registrystack.org/reference/client-api/#exact-json-in-node)
86
89
  for the full rules.
87
90
 
91
+ A keyed BReg, Casework, Messaging, or Scheduling mutation whose outcome is
92
+ unknown is resent identically under the same idempotency key up to
93
+ `maxMutationRetries` times, a client option: 0 to 2, default 2, and 0 sends it
94
+ once. Reads, unkeyed calls, and every 4xx refusal are never resent. When the returned error
95
+ still reports `outcomeUnknown`, the mutation may have taken effect: recover by
96
+ sending it again under the same key, because a new key could apply it twice.
97
+ `outcomeUnknown` is false for `410 idempotency.expired`, but there an earlier
98
+ attempt under the key was answered and may have committed: reconcile that
99
+ attempt before choosing a new key.
100
+ See [Unknown outcomes](https://docs.registrystack.org/reference/client-api/#unknown-outcomes-and-the-same-key-retry).
101
+
88
102
  `breg.verifyWebhookDelivery({ method, path, headers, body, key })` authenticates
89
103
  the exact bytes of one Version 1 webhook delivery. The result returns
90
104
  `deliveryTime` and `idempotencyKey`; the receiver must bound clock skew and
@@ -107,6 +121,9 @@ Registry Stack v0.30.0.
107
121
  The `messaging` namespace is part of the unified package beginning with
108
122
  Registry Stack v0.38.0.
109
123
 
124
+ The `scheduling` namespace is part of the unified package beginning with
125
+ Registry Stack v0.40.0.
126
+
110
127
  ## Casework notes
111
128
 
112
129
  The Casework module is for a trusted server host. Each call takes that request's
@@ -115,9 +132,15 @@ selected source profile. The client does not retain them. Browsers should send
115
132
  only the host's session cookie. Claim, release, and decide consume the
116
133
  caller-filtered action returned on the item, including its exact route and
117
134
  `ifMatch` revision. Mutations require a caller-controlled idempotency key and
118
- are never retried automatically. After a lost response, use
135
+ are resent only under the bounded same-key retry above; review request create
136
+ and cancel are never resent. After a lost response, use
119
137
  `recoverDecisionByKey` with the original key so recovery does not depend on the
120
138
  attempt identifier being received.
139
+ Reviewer inboxes accept an `ownership` filter before pagination.
140
+ `supervisoryReviewTasks` returns only task and accountability references for
141
+ queues the selected supervisor currently serves; its state is a holder-free
142
+ string. A single decided-task read
143
+ includes `decisionReceipt` only for the caller who recorded that decision.
121
144
 
122
145
  ## Documentation
123
146
 
package/breg/client.d.ts CHANGED
@@ -8,10 +8,10 @@ export type JsonObject = { readonly [key: string]: JsonValue }
8
8
  export type SafeInteger = number
9
9
 
10
10
  export type WebhookVerificationRefusalCode =
11
- | 'missing_header'
12
- | 'malformed_signature'
13
- | 'signature_mismatch'
14
- | 'unsupported_version'
11
+ | 'missing-header'
12
+ | 'malformed-signature'
13
+ | 'signature-mismatch'
14
+ | 'unsupported-version'
15
15
 
16
16
  export interface WebhookDeliveryInput {
17
17
  method: string
@@ -137,10 +137,44 @@ export interface BaseRegistryClientConfig {
137
137
  maxResponseBytes?: SafeInteger | null
138
138
  userAgent?: string | null
139
139
  trustedRootCertificates?: string | null
140
+ /**
141
+ * How many times a keyed mutation (create, patch, attachment upload or
142
+ * delete, lifecycle action, immediate action, batch, tombstone, statistics
143
+ * publish or withdraw) whose outcome is unknown is resent, identically and
144
+ * under the same idempotency key, before its error is returned: a whole
145
+ * number from 0 to 2, default 2; 0 sends it once. Any other value is a
146
+ * `configuration` error.
147
+ */
148
+ maxMutationRetries?: SafeInteger | null
140
149
  }
141
150
 
142
151
  export type RecordFormat = 'json' | 'json-ld'
143
152
 
153
+ export interface BRegStatisticalDimensionDescriptor {
154
+ readonly field: string
155
+ readonly vocabulary: string
156
+ readonly codes: ReadonlyArray<string>
157
+ }
158
+
159
+ export interface BRegStatisticalDatasetDescriptor {
160
+ readonly id: string
161
+ readonly unit: string
162
+ readonly periodKind: 'flow' | 'stock'
163
+ readonly granularity: 'day' | 'month' | 'quarter' | 'year'
164
+ readonly firstPeriod: string
165
+ readonly dimensions: ReadonlyArray<BRegStatisticalDimensionDescriptor>
166
+ readonly definitionDigest: string
167
+ readonly operations: ReadonlyArray<
168
+ | 'read-live'
169
+ | 'list-releases'
170
+ | 'read-released-series'
171
+ | 'read-latest-release'
172
+ | 'read-release-version'
173
+ | 'publish-release'
174
+ | 'withdraw-release'
175
+ >
176
+ }
177
+
144
178
  export interface RecordProjectionOptions {
145
179
  select?: ReadonlyArray<string> | null
146
180
  accessProfile?: string | null
@@ -224,8 +258,8 @@ export type BRegRequestResultReferenceData = JsonObject & {
224
258
  }
225
259
  export type BRegRequestState = 'draft' | 'submitted' | 'cancelled' | 'applied'
226
260
  export type BRegRequestReviewRequirement =
227
- | Readonly<{ mode: 'none' }>
228
- | Readonly<{ authority: string; policyId: string }>
261
+ | Readonly<{ type: 'none' }>
262
+ | Readonly<{ type: 'required'; authority: string; policyId: string }>
229
263
  export type BRegExternalReviewStatus = Readonly<{
230
264
  submission: Readonly<{
231
265
  state: 'pending' | 'accepted' | 'uncertain' | 'cancelling' | 'cancelled' | 'failed'
@@ -349,8 +383,17 @@ export interface RawOutcome {
349
383
  mediaType: string
350
384
  traceId: string
351
385
  etag?: string
386
+ reprDigest?: string
352
387
  }
353
388
 
389
+ export type StatisticsFormat = 'json' | 'csv'
390
+ export type StatisticsReleaseStatus = 'provisional' | 'final'
391
+ export type StatisticsReleaseSelection = 'any' | 'final'
392
+ export type StatisticsWithdrawalReason =
393
+ | 'computation-error'
394
+ | 'source-data-error'
395
+ | 'disclosure-risk'
396
+
354
397
  export interface PatchOperation {
355
398
  op: 'add' | 'replace' | 'test'
356
399
  field: string
@@ -451,9 +494,9 @@ export interface BRegQueryDescriptor {
451
494
  readonly sortableFields: ReadonlyArray<BRegQueryField>
452
495
  readonly allowCount: boolean
453
496
  readonly defaultPageSize: number
454
- readonly maxPageSize: number
455
- readonly maxFilterClauses: number
456
- readonly maxInValues: number
497
+ readonly maximumPageSize: number
498
+ readonly maximumFilterClauses: number
499
+ readonly maximumInValues: number
457
500
  readonly pagination: { readonly parameter: string; readonly responsePath: string; readonly exclusive: boolean }
458
501
  readonly temporal: JsonObject | null
459
502
  readonly spatialQueries?: {
@@ -811,7 +854,7 @@ export interface BRegAttachmentState {
811
854
 
812
855
  /** What one record projection says about one slot. */
813
856
  export type BRegAttachmentSlotValue =
814
- | { readonly kind: 'not_selected'; readonly value: null }
857
+ | { readonly kind: 'not-selected'; readonly value: null }
815
858
  | { readonly kind: 'empty'; readonly value: null }
816
859
  | { readonly kind: 'filled'; readonly value: BRegAttachmentState }
817
860
 
@@ -931,6 +974,18 @@ export declare class BRegLifecycleAction {
931
974
  readonly body: JsonObject
932
975
  }
933
976
 
977
+ /**
978
+ * Inert bounded immediate-action evidence: inputs, saved target conditions,
979
+ * and the idempotency key. Persist these bytes with owner-only access before
980
+ * invoking.
981
+ */
982
+ export declare class BRegPreparedAction {
983
+ private constructor()
984
+ private readonly __opaque: void
985
+ static fromBytes(bytes: Buffer): BRegPreparedAction
986
+ toBytes(): Buffer
987
+ }
988
+
934
989
  /** Inert bounded Create evidence. Persist these bytes with owner-only access. */
935
990
  export declare class BRegPreparedCreate {
936
991
  private constructor()
@@ -947,6 +1002,12 @@ export declare class BRegPreparedLifecycle {
947
1002
  toBytes(): Buffer
948
1003
  }
949
1004
 
1005
+ /** Revalidated action invocation and key. It still requires fresh metadata authority to send. */
1006
+ export declare class BRegRecoveredAction {
1007
+ private constructor()
1008
+ private readonly __opaque: void
1009
+ }
1010
+
950
1011
  /** Revalidated Create request. It still requires fresh metadata authority to send. */
951
1012
  export declare class BRegRecoveredCreate {
952
1013
  private constructor()
@@ -966,6 +1027,8 @@ export declare class BRegMetadata {
966
1027
  readonly operations: ReadonlyArray<BRegOperationDescriptor>
967
1028
  readonly immediateActions: ReadonlyArray<BRegImmediateActionDescriptor>
968
1029
  readonly actionsJson: string | null
1030
+ /** Validated caller-filtered inert descriptions. They never grant entity authority. */
1031
+ readonly statisticalDatasets: ReadonlyArray<BRegStatisticalDatasetDescriptor> | null
969
1032
  readonly registryIdentifier: string
970
1033
  readonly registryVersion: string
971
1034
  readonly registryRevision: string
@@ -986,10 +1049,26 @@ export interface BaseRegistryClientFailure extends Error {
986
1049
  readonly code?: string
987
1050
  readonly planRefusal?: string
988
1051
  readonly refusalCode?: string
1052
+ readonly reasonCode?: string
1053
+ readonly fieldPath?: string
989
1054
  readonly status?: number
990
1055
  readonly traceId?: string
991
1056
  readonly transportKind?: string
992
1057
  readonly tokenKind?: string
1058
+ /**
1059
+ * Whether the request may have taken effect although this error was raised:
1060
+ * a timeout or broken exchange after sending, an unusable answer, or a 5xx
1061
+ * other than `action.handler_failed` and
1062
+ * `statistical_dataset.domain_violation`, which the engine returns only with
1063
+ * the attempt rolled back. When true, recover a keyed mutation by sending it
1064
+ * again under the same idempotency key; a new key could apply it twice.
1065
+ * False for a configuration or request defect, a credential the token
1066
+ * provider could not supply, a connection never established, and every 4xx
1067
+ * refusal. It is false for `410 idempotency.expired` too, but there an
1068
+ * earlier attempt under the key committed and only its held response is
1069
+ * gone: read the resource before choosing a new key.
1070
+ */
1071
+ readonly outcomeUnknown: boolean
993
1072
  }
994
1073
 
995
1074
  export declare class BaseRegistryClientError extends Error implements BaseRegistryClientFailure {
@@ -997,10 +1076,26 @@ export declare class BaseRegistryClientError extends Error implements BaseRegist
997
1076
  readonly code?: string
998
1077
  readonly planRefusal?: string
999
1078
  readonly refusalCode?: string
1079
+ readonly reasonCode?: string
1080
+ readonly fieldPath?: string
1000
1081
  readonly status?: number
1001
1082
  readonly traceId?: string
1002
1083
  readonly transportKind?: string
1003
1084
  readonly tokenKind?: string
1085
+ /**
1086
+ * Whether the request may have taken effect although this error was raised:
1087
+ * a timeout or broken exchange after sending, an unusable answer, or a 5xx
1088
+ * other than `action.handler_failed` and
1089
+ * `statistical_dataset.domain_violation`, which the engine returns only with
1090
+ * the attempt rolled back. When true, recover a keyed mutation by sending it
1091
+ * again under the same idempotency key; a new key could apply it twice.
1092
+ * False for a configuration or request defect, a credential the token
1093
+ * provider could not supply, a connection never established, and every 4xx
1094
+ * refusal. It is false for `410 idempotency.expired` too, but there an
1095
+ * earlier attempt under the key committed and only its held response is
1096
+ * gone: read the resource before choosing a new key.
1097
+ */
1098
+ readonly outcomeUnknown: boolean
1004
1099
  }
1005
1100
 
1006
1101
  export declare class BaseRegistryClient {
@@ -1009,6 +1104,13 @@ export declare class BaseRegistryClient {
1009
1104
  ready(): Promise<CompleteOutcome<ProbeStatus>>
1010
1105
  openapi(accessProfile?: string | null): Promise<RawOutcome>
1011
1106
  registryMetadata(accessProfile?: string | null): Promise<RawOutcome>
1107
+ statisticsLive(dataset: string, from?: string | null, to?: string | null, accessProfile?: string | null, format?: StatisticsFormat | null): Promise<RawOutcome>
1108
+ statisticsReleases(dataset: string, top?: SafeInteger | null, skipToken?: string | null, accessProfile?: string | null): Promise<RawOutcome>
1109
+ statisticsLatestRelease(dataset: string, period: string, selection: StatisticsReleaseSelection, accessProfile?: string | null, format?: StatisticsFormat | null): Promise<RawOutcome>
1110
+ statisticsReleaseVersion(dataset: string, period: string, version: SafeInteger, accessProfile?: string | null, format?: StatisticsFormat | null): Promise<RawOutcome>
1111
+ statisticsReleaseSeries(dataset: string, from: string, to: string, selection: StatisticsReleaseSelection, accessProfile?: string | null, format?: StatisticsFormat | null): Promise<RawOutcome>
1112
+ statisticsPublish(dataset: string, period: string, status: StatisticsReleaseStatus, accessProfile: string, idempotencyKey: string): Promise<RawOutcome>
1113
+ statisticsWithdraw(dataset: string, period: string, version: SafeInteger, reason: StatisticsWithdrawalReason, accessProfile: string, idempotencyKey: string): Promise<RawOutcome>
1012
1114
  registryContract(accessProfile?: string | null): Promise<BRegMetadata>
1013
1115
  entitySchema(entityIdentifier: string, accessProfile?: string | null): Promise<RawOutcome>
1014
1116
  recordRevisions(entityRoute: string, recordIdentifier: string, accessProfile?: string | null): Promise<RawOutcome>
@@ -1032,6 +1134,14 @@ export declare class BaseRegistryClient {
1032
1134
  actionTargetConditionsJson(binding: BRegImmediateActionBinding, inputsJson: string): Promise<BRegActionTargetConditions>
1033
1135
  invokeAction(binding: BRegImmediateActionBinding, inputs: JsonObject, idempotencyKey: string, conditions?: BRegActionTargetConditions | null): Promise<CompleteOutcome<BRegActionReceipt>>
1034
1136
  invokeActionJson(binding: BRegImmediateActionBinding, inputsJson: string, idempotencyKey: string, conditions?: BRegActionTargetConditions | null): Promise<JsonOutcome>
1137
+ /** Validate and retain one invocation before any I/O, for recovery after a lost response. */
1138
+ prepareAction(binding: BRegImmediateActionBinding, inputs: JsonObject, idempotencyKey: string, conditions?: BRegActionTargetConditions | null): BRegPreparedAction
1139
+ prepareActionJson(binding: BRegImmediateActionBinding, inputsJson: string, idempotencyKey: string, conditions?: BRegActionTargetConditions | null): BRegPreparedAction
1140
+ /** Revalidate saved evidence against fresh authority and the original inputs and key. Performs no I/O. */
1141
+ recoverAction(binding: BRegImmediateActionBinding, prepared: BRegPreparedAction, inputs: JsonObject, idempotencyKey: string): BRegRecoveredAction
1142
+ recoverActionJson(binding: BRegImmediateActionBinding, prepared: BRegPreparedAction, inputsJson: string, idempotencyKey: string): BRegRecoveredAction
1143
+ executeRecoveredAction(binding: BRegImmediateActionBinding, recovered: BRegRecoveredAction): Promise<CompleteOutcome<BRegActionReceipt>>
1144
+ executeRecoveredActionJson(binding: BRegImmediateActionBinding, recovered: BRegRecoveredAction): Promise<JsonOutcome>
1035
1145
  createRecord(binding: BRegCreateBinding, data: JsonObject, idempotencyKey: string, format?: RecordFormat | null): Promise<CompleteOutcome<RecordEnvelope>>
1036
1146
  prepareCreate(binding: BRegCreateBinding, data: JsonObject, idempotencyKey: string, format?: RecordFormat | null): BRegPreparedCreate
1037
1147
  prepareCreateJson(binding: BRegCreateBinding, dataJson: string, idempotencyKey: string, format?: RecordFormat | null): BRegPreparedCreate
package/breg/client.js CHANGED
@@ -12,9 +12,18 @@ class BaseRegistryClientError extends Error {
12
12
  super(envelope.message);
13
13
  this.name = 'BaseRegistryClientError';
14
14
  this.kind = envelope.kind;
15
- for (const field of ['code', 'planRefusal', 'refusalCode', 'status', 'traceId', 'transportKind', 'tokenKind']) {
15
+ this.outcomeUnknown = envelope.outcomeUnknown === true;
16
+ for (const field of ['code', 'planRefusal', 'refusalCode', 'reasonCode', 'status', 'traceId', 'transportKind', 'tokenKind']) {
16
17
  if (envelope[field] !== undefined && envelope[field] !== null) this[field] = envelope[field];
17
18
  }
19
+ if (envelope.fieldPath !== undefined && envelope.fieldPath !== null) {
20
+ Object.defineProperty(this, 'fieldPath', {
21
+ value: envelope.fieldPath,
22
+ configurable: true,
23
+ enumerable: false,
24
+ writable: true,
25
+ });
26
+ }
18
27
  }
19
28
  }
20
29
 
@@ -52,19 +61,19 @@ function inputError(kind) {
52
61
 
53
62
  function plainDataObject(value, expectedFields) {
54
63
  if (value === null || typeof value !== 'object' || Array.isArray(value) || isProxy(value)) {
55
- throw inputError('invalid_request');
64
+ throw inputError('invalid-request');
56
65
  }
57
66
  const prototype = Object.getPrototypeOf(value);
58
- if (prototype !== Object.prototype && prototype !== null) throw inputError('invalid_request');
67
+ if (prototype !== Object.prototype && prototype !== null) throw inputError('invalid-request');
59
68
  const keys = Reflect.ownKeys(value);
60
69
  if (keys.some((key) => typeof key !== 'string')
61
70
  || keys.length !== expectedFields.length
62
- || keys.some((key) => !expectedFields.includes(key))) throw inputError('invalid_request');
71
+ || keys.some((key) => !expectedFields.includes(key))) throw inputError('invalid-request');
63
72
  const result = Object.create(null);
64
73
  for (const field of expectedFields) {
65
74
  const descriptor = Object.getOwnPropertyDescriptor(value, field);
66
75
  if (!descriptor || !descriptor.enumerable || !Object.hasOwn(descriptor, 'value')) {
67
- throw inputError('invalid_request');
76
+ throw inputError('invalid-request');
68
77
  }
69
78
  result[field] = descriptor.value;
70
79
  }
@@ -73,19 +82,19 @@ function plainDataObject(value, expectedFields) {
73
82
 
74
83
  function webhookHeaders(value) {
75
84
  if (value === null || typeof value !== 'object' || Array.isArray(value) || isProxy(value)) {
76
- throw inputError('invalid_request');
85
+ throw inputError('invalid-request');
77
86
  }
78
87
  const prototype = Object.getPrototypeOf(value);
79
- if (prototype !== Object.prototype && prototype !== null) throw inputError('invalid_request');
88
+ if (prototype !== Object.prototype && prototype !== null) throw inputError('invalid-request');
80
89
  const keys = Reflect.ownKeys(value);
81
90
  if (keys.some((key) => typeof key !== 'string')) {
82
- throw inputError('invalid_request');
91
+ throw inputError('invalid-request');
83
92
  }
84
93
  const result = Object.create(null);
85
94
  for (const name of keys) {
86
95
  const descriptor = Object.getOwnPropertyDescriptor(value, name);
87
96
  if (!descriptor || !descriptor.enumerable || !Object.hasOwn(descriptor, 'value')
88
- || typeof descriptor.value !== 'string') throw inputError('invalid_request');
97
+ || typeof descriptor.value !== 'string') throw inputError('invalid-request');
89
98
  result[name] = descriptor.value;
90
99
  }
91
100
  return result;
@@ -97,14 +106,14 @@ function verifyWebhookDelivery(value) {
97
106
  if (typeof input.method !== 'string' || typeof input.path !== 'string'
98
107
  || !Buffer.isBuffer(input.body) || !Buffer.isBuffer(input.key)
99
108
  || isSharedArrayBuffer(input.body.buffer) || isSharedArrayBuffer(input.key.buffer)) {
100
- throw inputError('invalid_request');
109
+ throw inputError('invalid-request');
101
110
  }
102
111
  input.headers = webhookHeaders(input.headers);
103
112
  input.body = Buffer.from(input.body);
104
113
  input.key = Buffer.from(input.key);
105
114
  return native.verifyWebhookDelivery(input);
106
115
  } catch (error) {
107
- throw normalize(error, 'invalid_request');
116
+ throw normalize(error, 'invalid-request');
108
117
  }
109
118
  }
110
119
 
@@ -176,10 +185,10 @@ function sanitizeArguments(args, jsonIndexes, requiredIndexes) {
176
185
  return args.map((value, index) => {
177
186
  if (!jsonIndexes.has(index)) return value;
178
187
  if (value === undefined || value === null) {
179
- if (requiredIndexes.has(index)) throw inputError('invalid_request');
188
+ if (requiredIndexes.has(index)) throw inputError('invalid-request');
180
189
  return value;
181
190
  }
182
- return cloneJson(value, budget, 0, 'invalid_request');
191
+ return cloneJson(value, budget, 0, 'invalid-request');
183
192
  });
184
193
  }
185
194
 
@@ -190,13 +199,16 @@ function wrapAsync(name, jsonIndexes = [], requiredIndexes = []) {
190
199
  const sanitized = sanitizeArguments(args, new Set(jsonIndexes), new Set(requiredIndexes));
191
200
  return original.apply(this, sanitized).catch((error) => { throw normalize(error); });
192
201
  } catch (error) {
193
- throw normalize(error, 'invalid_request');
202
+ throw normalize(error, 'invalid-request');
194
203
  }
195
204
  };
196
205
  }
197
206
 
198
207
  for (const [method, jsonIndexes, requiredIndexes] of [
199
208
  ['health'], ['ready'], ['openapi'], ['registryMetadata'], ['registryContract'], ['entitySchema'],
209
+ ['statisticsLive'], ['statisticsReleases'], ['statisticsLatestRelease'],
210
+ ['statisticsReleaseVersion'], ['statisticsReleaseSeries'], ['statisticsPublish'],
211
+ ['statisticsWithdraw'],
200
212
  ['recordRevisions'], ['getRecordRevision', [3]],
201
213
  ['getRecord', [2]], ['listRecords', [1]], ['continueList', [0], [0]],
202
214
  ['getGeoJsonRecord', [2]], ['listGeoJsonRecords', [1]], ['continueGeoJsonList', [0], [0]],
@@ -206,7 +218,7 @@ for (const [method, jsonIndexes, requiredIndexes] of [
206
218
  ['listRelationshipRecords', [3]], ['continueRelationshipList', [0], [0]],
207
219
  ['lookupRecord', [2, 3]], ['createRecord', [1], [1]],
208
220
  ['actionTargetConditions', [1], [1]], ['invokeAction', [1], [1]],
209
- ['executeRecoveredCreate'],
221
+ ['executeRecoveredAction'], ['executeRecoveredCreate'],
210
222
  ['patchRecord', [3], [3]], ['batchRecords', [1], [1]], ['tombstoneRecord'],
211
223
  ['executeLifecycleAction'],
212
224
  ['executeRecoveredLifecycleAction'],
@@ -220,13 +232,16 @@ for (const [method, jsonIndexes, requiredIndexes] of [
220
232
  ['listRelationshipRecordsJson', [3]], ['continueRelationshipListJson', [0], [0]],
221
233
  ['lookupRecordJson', [3]], ['createRecordJson'], ['patchRecordJson'], ['executeLifecycleActionJson'],
222
234
  ['actionTargetConditionsJson'], ['invokeActionJson'], ['batchRecordsJson'], ['tombstoneRecordJson'],
223
- ['executeRecoveredCreateJson'], ['executeRecoveredLifecycleActionJson'],
235
+ ['executeRecoveredActionJson'], ['executeRecoveredCreateJson'],
236
+ ['executeRecoveredLifecycleActionJson'],
224
237
  ['uploadAttachmentJson'], ['deleteAttachmentJson'],
225
238
  ['createIngestionRun', [1], [1]], ['listIngestionRuns', [1]],
226
239
  ['readIngestionRun'], ['submitIngestionChunk'], ['cancelIngestionRun'],
227
240
  ]) wrapAsync(method, jsonIndexes, requiredIndexes);
228
241
 
229
242
  for (const [method, jsonIndexes, requiredIndexes] of [
243
+ ['prepareAction', [1], [1]], ['prepareActionJson'],
244
+ ['recoverAction', [2], [2]], ['recoverActionJson'],
230
245
  ['prepareCreate', [1], [1]], ['prepareCreateJson'], ['recoverCreate'],
231
246
  ['prepareLifecycleAction', [1], [1]], ['prepareLifecycleActionJson'],
232
247
  ['recoverLifecycleAction'],
@@ -238,7 +253,7 @@ for (const [method, jsonIndexes, requiredIndexes] of [
238
253
  args, new Set(jsonIndexes), new Set(requiredIndexes),
239
254
  ));
240
255
  } catch (error) {
241
- throw normalize(error, 'invalid_request');
256
+ throw normalize(error, 'invalid-request');
242
257
  }
243
258
  };
244
259
  }
@@ -258,10 +273,10 @@ function preparedClass(Class, label) {
258
273
  fromBytes: {
259
274
  value(bytes) {
260
275
  try {
261
- if (!Buffer.isBuffer(bytes)) throw inputError('invalid_request');
276
+ if (!Buffer.isBuffer(bytes)) throw inputError('invalid-request');
262
277
  return Class.fromBytes(bytes);
263
278
  } catch (error) {
264
- throw normalize(error, 'invalid_request');
279
+ throw normalize(error, 'invalid-request');
265
280
  }
266
281
  },
267
282
  },
@@ -273,6 +288,7 @@ function preparedClass(Class, label) {
273
288
  return Facade;
274
289
  }
275
290
 
291
+ const BRegPreparedAction = preparedClass(native.BRegPreparedAction, 'BRegPreparedAction');
276
292
  const BRegPreparedCreate = preparedClass(native.BRegPreparedCreate, 'BRegPreparedCreate');
277
293
  const BRegPreparedLifecycle = preparedClass(
278
294
  native.BRegPreparedLifecycle, 'BRegPreparedLifecycle',
@@ -281,17 +297,17 @@ const BRegPreparedLifecycle = preparedClass(
281
297
  const withReason = native.BRegLifecycleAction.prototype.withReason;
282
298
  native.BRegLifecycleAction.prototype.withReason = function (reason) {
283
299
  try {
284
- if (typeof reason !== 'string' || !reason.isWellFormed()) throw inputError('invalid_request');
300
+ if (typeof reason !== 'string' || !reason.isWellFormed()) throw inputError('invalid-request');
285
301
  return withReason.call(this, reason);
286
302
  } catch (error) {
287
- throw normalize(error, 'invalid_request');
303
+ throw normalize(error, 'invalid-request');
288
304
  }
289
305
  };
290
306
 
291
307
  const lifecycleActionsJson = native.BaseRegistryClient.prototype.lifecycleActionsJson;
292
308
  native.BaseRegistryClient.prototype.lifecycleActionsJson = function (...args) {
293
309
  try { return lifecycleActionsJson.apply(this, args); }
294
- catch (error) { throw normalize(error, 'invalid_request'); }
310
+ catch (error) { throw normalize(error, 'invalid-request'); }
295
311
  };
296
312
 
297
313
  const lifecycleActions = native.BaseRegistryClient.prototype.lifecycleActions;
@@ -300,7 +316,7 @@ native.BaseRegistryClient.prototype.lifecycleActions = function (...args) {
300
316
  const sanitized = sanitizeArguments(args, new Set([1]), new Set([1]));
301
317
  return lifecycleActions.apply(this, sanitized);
302
318
  } catch (error) {
303
- throw normalize(error, 'invalid_request');
319
+ throw normalize(error, 'invalid-request');
304
320
  }
305
321
  };
306
322
 
@@ -310,7 +326,7 @@ native.BaseRegistryClient.prototype.requestHistory = function (...args) {
310
326
  const sanitized = sanitizeArguments(args, new Set([0]), new Set([0]));
311
327
  return requestHistory.apply(this, sanitized);
312
328
  } catch (error) {
313
- throw normalize(error, 'invalid_request');
329
+ throw normalize(error, 'invalid-request');
314
330
  }
315
331
  };
316
332
 
@@ -321,11 +337,11 @@ for (const name of ['findProposal', 'findApplication']) {
321
337
  const proposalVersion = args[2];
322
338
  if (!Number.isSafeInteger(proposalVersion)
323
339
  || proposalVersion < 1 || proposalVersion > 0xffff_ffff) {
324
- throw inputError('invalid_request');
340
+ throw inputError('invalid-request');
325
341
  }
326
342
  return original.apply(this, args);
327
343
  } catch (error) {
328
- throw normalize(error, 'invalid_request');
344
+ throw normalize(error, 'invalid-request');
329
345
  }
330
346
  };
331
347
  }
@@ -335,7 +351,7 @@ native.BRegAttachmentSlot.prototype.valueIn = function (...args) {
335
351
  try {
336
352
  return valueIn.apply(this, sanitizeArguments(args, new Set([0]), new Set([0])));
337
353
  } catch (error) {
338
- throw normalize(error, 'invalid_request');
354
+ throw normalize(error, 'invalid-request');
339
355
  }
340
356
  };
341
357
 
@@ -345,7 +361,7 @@ for (const name of ['prepareUpload', 'acceptsContentType']) {
345
361
  try {
346
362
  return original.apply(this, args);
347
363
  } catch (error) {
348
- throw normalize(error, 'invalid_request');
364
+ throw normalize(error, 'invalid-request');
349
365
  }
350
366
  };
351
367
  }
@@ -359,20 +375,20 @@ for (const name of [
359
375
  try {
360
376
  return original.apply(this, args);
361
377
  } catch (error) {
362
- throw normalize(error, 'invalid_request');
378
+ throw normalize(error, 'invalid-request');
363
379
  }
364
380
  };
365
381
  }
366
382
 
367
383
  function encodeIngestionChunk(chunkIndex, items, prefixDigest) {
368
384
  try {
369
- if (!Number.isSafeInteger(chunkIndex)) throw inputError('invalid_request');
385
+ if (!Number.isSafeInteger(chunkIndex)) throw inputError('invalid-request');
370
386
  const sanitized = sanitizeArguments(
371
387
  [chunkIndex, items, prefixDigest], new Set([1]), new Set([1]),
372
388
  );
373
389
  return native.encodeIngestionChunk(...sanitized);
374
390
  } catch (error) {
375
- throw normalize(error, 'invalid_request');
391
+ throw normalize(error, 'invalid-request');
376
392
  }
377
393
  }
378
394
 
@@ -381,10 +397,10 @@ function encodeIngestionChunk(chunkIndex, items, prefixDigest) {
381
397
  const ingestionChunkReceipt = native.BaseRegistryClient.prototype.ingestionChunkReceipt;
382
398
  native.BaseRegistryClient.prototype.ingestionChunkReceipt = function (...args) {
383
399
  try {
384
- if (!Number.isSafeInteger(args[2])) throw inputError('invalid_request');
400
+ if (!Number.isSafeInteger(args[2])) throw inputError('invalid-request');
385
401
  return ingestionChunkReceipt.apply(this, args).catch((error) => { throw normalize(error); });
386
402
  } catch (error) {
387
- throw normalize(error, 'invalid_request');
403
+ throw normalize(error, 'invalid-request');
388
404
  }
389
405
  };
390
406
 
@@ -392,11 +408,11 @@ const ingestionPrefixDigestUpdate = native.BRegIngestionPrefixDigest.prototype.u
392
408
  native.BRegIngestionPrefixDigest.prototype.update = function (data) {
393
409
  try {
394
410
  if (!Buffer.isBuffer(data) || isSharedArrayBuffer(data.buffer)) {
395
- throw inputError('invalid_request');
411
+ throw inputError('invalid-request');
396
412
  }
397
413
  return ingestionPrefixDigestUpdate.call(this, data);
398
414
  } catch (error) {
399
- throw normalize(error, 'invalid_request');
415
+ throw normalize(error, 'invalid-request');
400
416
  }
401
417
  };
402
418
 
@@ -445,8 +461,10 @@ module.exports = {
445
461
  BRegActionTargetConditions: native.BRegActionTargetConditions,
446
462
  BRegTombstoneBinding: native.BRegTombstoneBinding,
447
463
  BRegBatchBinding: native.BRegBatchBinding,
464
+ BRegPreparedAction,
448
465
  BRegPreparedCreate,
449
466
  BRegPreparedLifecycle,
467
+ BRegRecoveredAction: native.BRegRecoveredAction,
450
468
  BRegRecoveredCreate: native.BRegRecoveredCreate,
451
469
  BRegRecoveredLifecycle: native.BRegRecoveredLifecycle,
452
470
  BRegIngestionChunk: native.BRegIngestionChunk,