@registrystack/client 0.43.0 → 0.45.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,12 @@
1
1
  # @registrystack/client
2
2
 
3
3
  One versioned Node.js package for the Discovery, Evidence, Base Registry
4
- Engine, Casework, Messaging, and Scheduling client APIs in Registry Stack.
4
+ Engine, Casework, Messaging, Scheduling, and Coordinator client APIs in Registry Stack.
5
+
6
+ Coordinator joins the client roster at v0.44.0. Its imports below require a
7
+ Coordinator-enabled v0.44.0 candidate or published package; published v0.43.0
8
+ contains the earlier six products. Check the version-specific release assets
9
+ before installing. Source integration does not establish publication.
5
10
 
6
11
  ## Install
7
12
 
@@ -11,13 +16,13 @@ npm install "@registrystack/client@<version>"
11
16
 
12
17
  Requires Node.js 24.11 or newer. Supported targets are macOS arm64, Linux
13
18
  arm64 with glibc, and Linux x64 with glibc; installing the package pulls in
14
- one platform-specific optional dependency containing all six native
19
+ one platform-specific optional dependency containing all seven native
15
20
  bindings.
16
21
 
17
22
  ## Usage
18
23
 
19
24
  ```js
20
- const { discovery, evidence, breg, casework, messaging, scheduling } = require('@registrystack/client');
25
+ const { discovery, evidence, breg, casework, messaging, scheduling, coordinator } = require('@registrystack/client');
21
26
 
22
27
  const registry = new breg.BaseRegistryClient({
23
28
  baseUrl: 'https://registry.example.invalid/',
@@ -31,6 +36,9 @@ const messages = new messaging.MessagingClient({
31
36
  const appointments = new scheduling.SchedulingClient({
32
37
  baseUrl: 'https://scheduling.example.invalid/',
33
38
  });
39
+ const workflows = new coordinator.CoordinatorClient({
40
+ baseUrl: 'https://coordinator.example.invalid/',
41
+ });
34
42
  ```
35
43
 
36
44
  ## Products
@@ -48,9 +56,22 @@ const appointments = new scheduling.SchedulingClient({
48
56
  - `scheduling`: Registry Scheduling, published offerings, availability,
49
57
  holds, and appointments over operator-anchored supply.
50
58
 
59
+ - `coordinator`: Registry Coordinator, workflow contracts, admission, run status,
60
+ inspection, and operator recovery. It is optional for direct product composition.
61
+
51
62
  Each product remains in its own namespace because its routing,
52
63
  authentication, errors, and verification rules are different.
53
64
 
65
+ ## Compatibility metadata
66
+
67
+ The package includes the tested server baseline and compatible patch line for
68
+ the Discovery namespace. Read the version-matched record through the exported
69
+ JSON path:
70
+
71
+ ```js
72
+ const compatibility = require('@registrystack/client/compatibility.json');
73
+ ```
74
+
54
75
  ## TypeScript
55
76
 
56
77
  A TypeScript consumer also needs the Node type definitions, and must name
@@ -90,7 +111,7 @@ for the full rules.
90
111
 
91
112
  A keyed BReg, Casework, Messaging, or Scheduling mutation whose outcome is
92
113
  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
114
+ `maximumMutationRetries` times, a client option: 0 to 2, default 2, and 0 sends it
94
115
  once. Casework review-request create and cancel are excluded from this retry.
95
116
  Reads, unkeyed calls, and every 4xx refusal are never resent. When the returned error
96
117
  still reports `outcomeUnknown`, the mutation may have taken effect: recover by
@@ -100,12 +121,12 @@ attempt under the key was answered and may have committed: reconcile that
100
121
  attempt before choosing a new key.
101
122
  See [Unknown outcomes](https://docs.registrystack.org/reference/client-api/#unknown-outcomes-and-the-same-key-retry).
102
123
 
103
- `breg.verifyWebhookDelivery({ method, path, headers, body, key })` authenticates
104
- the exact bytes of one Version 1 webhook delivery. The result returns
124
+ `breg.verifyHookDelivery({ method, path, headers, body, key })` authenticates
125
+ the exact bytes of one Version 1 hook delivery. The result returns
105
126
  `deliveryTime` and `idempotencyKey`; the receiver must bound clock skew and
106
127
  deduplicate once-only effects on authenticated `source` plus `id`, or on an
107
128
  application business key. See
108
- [Verify a webhook delivery](https://docs.registrystack.org/reference/client-api/#verify-a-webhook-delivery)
129
+ [Verify a hook delivery](https://docs.registrystack.org/reference/client-api/#verify-a-hook-delivery)
109
130
  for a receiver example.
110
131
 
111
132
  ## Versioning
@@ -163,3 +184,12 @@ without the cursor after `410 review.result-expired`.
163
184
  ## License
164
185
 
165
186
  Apache-2.0
187
+
188
+ Coordinator joins the seven-product roster at v0.44.0. The source facade also
189
+ contains held `render` and `@registrystack/client/render` namespaces. Default
190
+ assembly omits Render; `--include-render` adds it to an explicit local candidate
191
+ and does not authorize publication. Render takes a token or a resource-bound provider with
192
+ `bearerToken()` and performs one bounded render exchange. A correlation key is
193
+ not a durable idempotency promise. `outcomeUnknown` and `transportKind` preserve
194
+ whether an exchange may have completed; provider errors keep their own class.
195
+ Coordinator is optional.
package/breg/client.d.ts CHANGED
@@ -7,7 +7,7 @@ export type JsonObject = { readonly [key: string]: JsonValue }
7
7
  /** An integer that satisfies `Number.isSafeInteger` and the option's documented bounds. */
8
8
  export type SafeInteger = number
9
9
 
10
- export type WebhookVerificationRefusalCode =
10
+ export type HookVerificationRefusalCode =
11
11
  | 'missing-header'
12
12
  | 'invalid-delivery-time'
13
13
  | 'duplicate-header'
@@ -17,7 +17,7 @@ export type WebhookVerificationRefusalCode =
17
17
  | 'signature-mismatch'
18
18
  | 'unsupported-version'
19
19
 
20
- export interface WebhookDeliveryInput {
20
+ export interface HookDeliveryInput {
21
21
  method: string
22
22
  path: string
23
23
  headers: Readonly<Record<string, string>>
@@ -27,7 +27,7 @@ export interface WebhookDeliveryInput {
27
27
  key: Buffer
28
28
  }
29
29
 
30
- export interface VerifiedWebhookDelivery {
30
+ export interface VerifiedHookDelivery {
31
31
  readonly id: string
32
32
  readonly source: string
33
33
  readonly type: string
@@ -41,10 +41,21 @@ export interface VerifiedWebhookDelivery {
41
41
  }
42
42
 
43
43
  /**
44
- * Authenticate one exact Base Registry Engine Version 1 webhook delivery.
44
+ * Authenticate one exact Base Registry Engine Version 1 hook delivery.
45
45
  * Apply delivery-time skew and idempotency policy before acting on the body.
46
46
  */
47
- export declare function verifyWebhookDelivery(input: WebhookDeliveryInput): VerifiedWebhookDelivery
47
+ export declare function verifyHookDelivery(input: HookDeliveryInput): VerifiedHookDelivery
48
+
49
+ /**
50
+ * Project one record revision into the event record view. `argumentsJson` is a
51
+ * JSON object with `registryRevision`, `recordType`, `descriptor`, `record`
52
+ * and optional `creationRevision`, `actionReceipts` and
53
+ * `proposalApplications`. The result is the view document as JSON text.
54
+ * Failures carry kind `event-record` and one of the codes `not-an-event-record`,
55
+ * `unsupported-version`, `malformed-descriptor`, `wrong-record-evidence`,
56
+ * `revision-mismatch`, `incompatible-metadata` or `invalid-input`.
57
+ */
58
+ export declare function eventRecordView(argumentsJson: string): string
48
59
 
49
60
  export interface PrivateJwk {
50
61
  readonly kty: string
@@ -62,24 +73,24 @@ export interface PrivateKeyJwtConfig {
62
73
  * authentication). Defaults to the token endpoint URL. This is not the
63
74
  * `resource` of the token request.
64
75
  */
65
- audience?: string | null
76
+ audience?: string
66
77
  /**
67
78
  * The RFC 8707 resource indicator the token is requested for: the resource
68
79
  * server's registered identifier, not a URL to fetch.
69
80
  */
70
- resource?: string | null
81
+ resource?: string
71
82
  /**
72
83
  * The scopes requested for the token, sent as one space-delimited `scope`
73
84
  * parameter. A requested scope may narrow the client's registered
74
85
  * permission set; it can never widen it.
75
86
  */
76
- scopes?: ReadonlyArray<string> | null
77
- assertionLifetimeSeconds?: SafeInteger | null
78
- refreshMarginSeconds?: SafeInteger | null
79
- requestTimeoutMilliseconds?: SafeInteger | null
80
- connectTimeoutMilliseconds?: SafeInteger | null
81
- userAgent?: string | null
82
- trustedRootCertificates?: string | null
87
+ scopes?: ReadonlyArray<string>
88
+ assertionLifetimeSeconds?: SafeInteger
89
+ refreshMarginSeconds?: SafeInteger
90
+ attemptTimeoutMilliseconds?: SafeInteger
91
+ connectTimeoutMilliseconds?: SafeInteger
92
+ userAgent?: string
93
+ trustedRootCertificates?: string
83
94
  }
84
95
 
85
96
  /** OAuth credentials are returned to the caller. Keep them out of logs and persistence. */
@@ -98,7 +109,7 @@ export interface ExchangeContext {
98
109
  audience: string
99
110
  generation: string
100
111
  deadlineSeconds: SafeInteger
101
- grantId?: string | null
112
+ grantId?: string
102
113
  }
103
114
 
104
115
  export type ExchangePrivateKeyJwtConfig = PrivateKeyJwtConfig & {
@@ -118,10 +129,10 @@ export interface RemoteExchangeSource {
118
129
  bootstrap: ExchangePrivateKeyJwtConfig
119
130
  bootstrapResource: string
120
131
  bootstrapScope: string
121
- requestTimeoutMilliseconds?: SafeInteger | null
122
- connectTimeoutMilliseconds?: SafeInteger | null
123
- userAgent?: string | null
124
- trustedRootCertificates?: string | null
132
+ attemptTimeoutMilliseconds?: SafeInteger
133
+ connectTimeoutMilliseconds?: SafeInteger
134
+ userAgent?: string
135
+ trustedRootCertificates?: string
125
136
  }
126
137
 
127
138
  export type ExchangeAuthorizationConfig =
@@ -135,12 +146,12 @@ export type BaseRegistryAuthorization =
135
146
 
136
147
  export interface BaseRegistryClientConfig {
137
148
  baseUrl: string
138
- authorization?: BaseRegistryAuthorization | null
139
- requestTimeoutMilliseconds?: SafeInteger | null
140
- connectTimeoutMilliseconds?: SafeInteger | null
141
- maxResponseBytes?: SafeInteger | null
142
- userAgent?: string | null
143
- trustedRootCertificates?: string | null
149
+ authorization?: BaseRegistryAuthorization
150
+ attemptTimeoutMilliseconds?: SafeInteger
151
+ connectTimeoutMilliseconds?: SafeInteger
152
+ maximumResponseBytes?: SafeInteger
153
+ userAgent?: string
154
+ trustedRootCertificates?: string
144
155
  /**
145
156
  * How many times a keyed mutation (create, patch, attachment upload or
146
157
  * delete, lifecycle action, immediate action, batch, tombstone, statistics
@@ -149,7 +160,7 @@ export interface BaseRegistryClientConfig {
149
160
  * number from 0 to 2, default 2; 0 sends it once. Any other value is a
150
161
  * `configuration` error.
151
162
  */
152
- maxMutationRetries?: SafeInteger | null
163
+ maximumMutationRetries?: SafeInteger
153
164
  }
154
165
 
155
166
  export type RecordFormat = 'json' | 'json-ld'
@@ -227,7 +238,7 @@ export interface ListContinuation {
227
238
  accessProfile?: string | null
228
239
  registryIdentifier: string
229
240
  datasetIdentifier: string
230
- entityTypeIdentifier: string
241
+ recordTypeIdentifier: string
231
242
  }
232
243
  export type CurrentListContinuation = ListContinuation
233
244
  export interface AsOfListContinuation extends ListContinuation { asOf: string }
@@ -255,7 +266,7 @@ export interface RegistryRecord {
255
266
  export interface RecordMetadata {
256
267
  registryIdentifier: string
257
268
  datasetIdentifier: string
258
- entityTypeIdentifier: string
269
+ recordTypeIdentifier: string
259
270
  readonly [member: string]: JsonValue | undefined
260
271
  }
261
272
 
@@ -473,6 +484,7 @@ export interface BRegProposalActionDescriptor {
473
484
  readonly accessProfile: string
474
485
  readonly operations: ReadonlyArray<string>
475
486
  readonly readableInputs: ReadonlyArray<string>
487
+ readonly readableContextFields: ReadonlyArray<string>
476
488
  }
477
489
 
478
490
  export interface BRegActionAttachmentDescriptor {
@@ -536,7 +548,7 @@ export interface BRegActionReceipt {
536
548
 
537
549
  export type BRegActionAvailability =
538
550
  | { readonly available: true; readonly observedRevision: number }
539
- | { readonly available: false; readonly observedRevision: number; readonly reason: 'guard-not-satisfied'; readonly recovery: 'none' }
551
+ | { readonly available: false; readonly observedRevision: number; readonly reason: 'guard-not-satisfied'; readonly guardReason?: string; readonly recovery: 'none' }
540
552
  | { readonly available: null; readonly observedRevision: number; readonly reason: 'input-required'; readonly recovery: 'correct-input'; readonly missingInputs: ReadonlyArray<string> }
541
553
  | { readonly available: null; readonly observedRevision: null; readonly reason: 'not-disclosed'; readonly recovery: 'none' }
542
554
 
@@ -547,8 +559,8 @@ export interface BRegBatchCreateItem {
547
559
  export interface BRegBatchPatchItem {
548
560
  readonly operation: 'patch'
549
561
  readonly recordIdentifier: string
550
- readonly etag: string
551
- readonly operations: ReadonlyArray<PatchOperation | RemovePatchOperation>
562
+ readonly ifMatch: string
563
+ readonly patch: ReadonlyArray<PatchOperation | RemovePatchOperation>
552
564
  }
553
565
  export type BRegBatchItem = BRegBatchCreateItem | BRegBatchPatchItem
554
566
  export type BRegChangeContext =
@@ -571,10 +583,10 @@ export interface BRegBatchReceipt {
571
583
  readonly snapshot: string
572
584
  readonly results: ReadonlyArray<{
573
585
  readonly operation: 'create' | 'patch'
574
- readonly id: string
575
- readonly revision: SafeInteger
586
+ readonly recordIdentifier: string
587
+ readonly revisionIdentifier: string
576
588
  readonly etag: string
577
- readonly data: Readonly<Record<string, JsonValue>>
589
+ readonly domainData: Readonly<Record<string, JsonValue>>
578
590
  }>
579
591
  }
580
592
 
@@ -795,6 +807,8 @@ export declare class BRegMetadata {
795
807
  selectAction(actionIdentifier: string, expectedProfile: string): BRegActionBinding
796
808
  selectTombstone(recordTypeIdentifier: string, expectedProfile: string): BRegTombstoneBinding
797
809
  selectBatch(recordTypeIdentifier: string, expectedProfile: string): BRegBatchBinding
810
+ /** The event record descriptor declared for a record type, as JSON text. */
811
+ eventRecordDescriptor(recordType: string): string
798
812
  }
799
813
 
800
814
  /** Bounded declared identifiers; absent when any referenced field is unreadable. */
@@ -815,6 +829,7 @@ export interface BaseRegistryClientFailure extends Error {
815
829
  readonly code?: string
816
830
  readonly refusalCode?: string
817
831
  readonly reasonCode?: string
832
+ readonly guardReason?: string
818
833
  readonly fieldPath?: string
819
834
  readonly constraint?: BRegConstraintViolation
820
835
  readonly status?: number
@@ -842,6 +857,7 @@ export declare class BaseRegistryClientError extends Error implements BaseRegist
842
857
  readonly code?: string
843
858
  readonly refusalCode?: string
844
859
  readonly reasonCode?: string
860
+ readonly guardReason?: string
845
861
  readonly fieldPath?: string
846
862
  readonly constraint?: BRegConstraintViolation
847
863
  readonly status?: number
@@ -865,13 +881,24 @@ export declare class BaseRegistryClientError extends Error implements BaseRegist
865
881
  }
866
882
 
867
883
  export declare class BaseRegistryClient {
868
- startProposal(binding: BRegActionBinding, inputsJson: string, key: string): Promise<BRegProposal>
884
+ startProposal(binding: BRegActionBinding, inputs: JsonObject, key: string): Promise<BRegProposal>
869
885
  getProposal(binding: BRegProposalGetBinding, id: string): Promise<BRegProposal>
870
886
  readProposal(proposal: BRegProposal): Promise<BRegProposal>
871
887
  /** Read one retained submission version under the access profile of the Proposal's self link. */
872
888
  readProposalSubmission(proposal: BRegProposal, version: number): Promise<CompleteOutcome<BRegProposalSubmission>>
873
- listProposals(collection: BRegProposalCollection, queryJson: string): Promise<BRegProposalPage>
874
- prepareProposal(proposal: BRegProposal, operation: BRegProposalTransition, bodyJson: string, key: string): BRegPreparedProposal
889
+ listProposals(collection: BRegProposalCollection, query: JsonObject): Promise<BRegProposalPage>
890
+ /** Exact JSON query; retains the metadata-selected collection and bounded pagination. */
891
+ listProposalsJson(collection: BRegProposalCollection, queryJson: string): Promise<BRegProposalPage>
892
+ /**
893
+ * Bind an available transition without I/O. Throws locally when the operation
894
+ * is not a legal transition from the Proposal's observed state; `cancel` is
895
+ * prepared only for a Draft or Submitted Proposal, so cancelling an Applied or
896
+ * Cancelled Proposal never reaches the server. Call the HTTP route directly to
897
+ * exercise the server's terminal-state refusal.
898
+ */
899
+ prepareProposal(proposal: BRegProposal, operation: BRegProposalTransition, body: JsonObject, key: string): BRegPreparedProposal
900
+ /** Exact JSON body; preserves integer values and the same lifecycle authority and recovery contract. */
901
+ prepareProposalJson(proposal: BRegProposal, operation: BRegProposalTransition, bodyJson: string, key: string): BRegPreparedProposal
875
902
  recoverProposal(proposal: BRegProposal, attempt: BRegPreparedProposal): BRegPreparedProposal
876
903
  executeProposal(attempt: BRegPreparedProposal): Promise<BRegProposal>
877
904
  constructor(config: BaseRegistryClientConfig)
@@ -879,6 +906,12 @@ export declare class BaseRegistryClient {
879
906
  ready(): Promise<CompleteOutcome<ProbeStatus>>
880
907
  openapi(accessProfile?: string | null): Promise<RawOutcome>
881
908
  registryMetadata(accessProfile?: string | null): Promise<RawOutcome>
909
+ /**
910
+ * The first revision of a record as
911
+ * `{recordType, recordId, revision, createdAt}` JSON text, or null when the
912
+ * caller may not read it (403 or 404).
913
+ */
914
+ eventRecordCreationRevision(recordRoute: string, recordIdentifier: string, accessProfile?: string | null): Promise<string | null>
882
915
  statisticsLive(dataset: string, from?: string | null, to?: string | null, accessProfile?: string | null, format?: StatisticsFormat | null): Promise<RawOutcome>
883
916
  statisticsReleases(dataset: string, top?: SafeInteger | null, skipToken?: string | null, accessProfile?: string | null): Promise<RawOutcome>
884
917
  statisticsLatestRelease(dataset: string, period: string, selection: StatisticsReleaseSelection, accessProfile?: string | null, format?: StatisticsFormat | null): Promise<RawOutcome>
@@ -887,24 +920,24 @@ export declare class BaseRegistryClient {
887
920
  statisticsPublish(dataset: string, period: string, status: StatisticsReleaseStatus, accessProfile: string, idempotencyKey: string): Promise<RawOutcome>
888
921
  statisticsWithdraw(dataset: string, period: string, version: SafeInteger, reason: StatisticsWithdrawalReason, accessProfile: string, idempotencyKey: string): Promise<RawOutcome>
889
922
  registryContract(accessProfile?: string | null): Promise<BRegMetadata>
890
- entitySchema(recordTypeIdentifier: string, accessProfile?: string | null): Promise<RawOutcome>
891
- recordRevisions(entityRoute: string, recordIdentifier: string, accessProfile?: string | null): Promise<RawOutcome>
892
- getRecordRevision(entityRoute: string, recordIdentifier: string, revision: SafeInteger, options?: RecordProjectionOptions | null): Promise<RawOutcome>
893
- getRecord(entityRoute: string, recordIdentifier: string, options?: RecordOptions | null): Promise<CompleteOutcome<RecordEnvelope>>
894
- listRecords(entityRoute: string, options?: ListOptions | null): Promise<PageOutcome>
923
+ recordSchema(recordTypeIdentifier: string, accessProfile?: string | null): Promise<RawOutcome>
924
+ recordRevisions(recordRoute: string, recordIdentifier: string, accessProfile?: string | null): Promise<RawOutcome>
925
+ getRecordRevision(recordRoute: string, recordIdentifier: string, revision: SafeInteger, options?: RecordProjectionOptions | null): Promise<RawOutcome>
926
+ getRecord(recordRoute: string, recordIdentifier: string, options?: RecordOptions | null): Promise<CompleteOutcome<RecordEnvelope>>
927
+ listRecords(recordRoute: string, options?: ListOptions | null): Promise<PageOutcome>
895
928
  continueList(continuation: ListContinuation): Promise<PageOutcome>
896
- getGeoJsonRecord(entityRoute: string, recordIdentifier: string, options?: GeoJsonOptions | null): Promise<CompleteOutcome<GeoJsonFeature>>
897
- listGeoJsonRecords(entityRoute: string, options?: GeoJsonListOptions | null): Promise<PageOutcome<GeoJsonFeatureCollection, GeoJsonListContinuation>>
929
+ getGeoJsonRecord(recordRoute: string, recordIdentifier: string, options?: GeoJsonOptions | null): Promise<CompleteOutcome<GeoJsonFeature>>
930
+ listGeoJsonRecords(recordRoute: string, options?: GeoJsonListOptions | null): Promise<PageOutcome<GeoJsonFeatureCollection, GeoJsonListContinuation>>
898
931
  continueGeoJsonList(continuation: GeoJsonListContinuation): Promise<PageOutcome<GeoJsonFeatureCollection, GeoJsonListContinuation>>
899
- listCurrentRecords(entityRoute: string, options?: CollectionOptions | null): Promise<PageOutcome<RecordCollection, CurrentListContinuation>>
932
+ listCurrentRecords(recordRoute: string, options?: CollectionOptions | null): Promise<PageOutcome<RecordCollection, CurrentListContinuation>>
900
933
  continueCurrentList(continuation: CurrentListContinuation): Promise<PageOutcome<RecordCollection, CurrentListContinuation>>
901
- listRecordsAsOf(entityRoute: string, options: AsOfListOptions): Promise<PageOutcome<RecordCollection, AsOfListContinuation>>
934
+ listRecordsAsOf(recordRoute: string, options: AsOfListOptions): Promise<PageOutcome<RecordCollection, AsOfListContinuation>>
902
935
  continueAsOfList(continuation: AsOfListContinuation): Promise<PageOutcome<RecordCollection, AsOfListContinuation>>
903
- listSnapshotRecords(entityRoute: string, options?: SnapshotListOptions | null): Promise<PageOutcome<RecordCollection, SnapshotListContinuation>>
936
+ listSnapshotRecords(recordRoute: string, options?: SnapshotListOptions | null): Promise<PageOutcome<RecordCollection, SnapshotListContinuation>>
904
937
  continueSnapshotList(continuation: SnapshotListContinuation): Promise<PageOutcome<RecordCollection, SnapshotListContinuation>>
905
- listRelationshipRecords(entityRoute: string, recordIdentifier: string, pathRoute: string, options?: CollectionOptions | null): Promise<PageOutcome<RecordCollection, RelationshipListContinuation>>
938
+ listRelationshipRecords(recordRoute: string, recordIdentifier: string, pathRoute: string, options?: CollectionOptions | null): Promise<PageOutcome<RecordCollection, RelationshipListContinuation>>
906
939
  continueRelationshipList(continuation: RelationshipListContinuation): Promise<PageOutcome<RecordCollection, RelationshipListContinuation>>
907
- lookupRecord(entityRoute: string, selector: string, values?: JsonObject | null, options?: RecordProjectionOptions | null): Promise<CompleteOutcome<RecordEnvelope>>
940
+ lookupRecord(recordRoute: string, selector: string, values?: JsonObject | null, options?: RecordProjectionOptions | null): Promise<CompleteOutcome<RecordEnvelope>>
908
941
  actionTargetConditions(binding: BRegActionBinding, inputs: JsonObject): Promise<BRegActionTargetConditions>
909
942
  actionTargetConditionsJson(binding: BRegActionBinding, inputsJson: string): Promise<BRegActionTargetConditions>
910
943
  actionAvailability(binding: BRegActionBinding, targetInput: string, inputs: JsonObject): Promise<CompleteOutcome<BRegActionAvailability>>
@@ -937,36 +970,36 @@ export declare class BaseRegistryClient {
937
970
  patchRecord(binding: BRegPatchBinding, recordIdentifier: string, etag: string, operations: ReadonlyArray<PatchOperation | RemovePatchOperation>, idempotencyKey: string, format?: RecordFormat | null): Promise<CompleteOutcome<RecordEnvelope>>
938
971
  batchRecords(binding: BRegBatchBinding, request: BRegBatchInput, idempotencyKey: string): Promise<CompleteOutcome<BRegBatchReceipt>>
939
972
  batchRecordsJson(binding: BRegBatchBinding, requestJson: string, idempotencyKey: string): Promise<JsonOutcome>
940
- createIngestionRun(entityRoute: string, request: BRegIngestionRunInput): Promise<CompleteOutcome<BRegIngestionRun>>
941
- listIngestionRuns(entityRoute: string, query?: BRegIngestionRunListInput | null): Promise<CompleteOutcome<BRegIngestionRunPage>>
942
- readIngestionRun(entityRoute: string, runId: string, accessProfile?: string | null): Promise<CompleteOutcome<BRegIngestionRun>>
943
- submitIngestionChunk(entityRoute: string, runId: string, chunk: BRegIngestionChunk, profileId: string): Promise<CompleteOutcome<BRegIngestionChunkSubmission>>
944
- cancelIngestionRun(entityRoute: string, runId: string, accessProfile?: string | null): Promise<CompleteOutcome<BRegIngestionRun>>
945
- ingestionChunkReceipt(entityRoute: string, runId: string, chunkIndex: SafeInteger, profileId: string): Promise<CompleteOutcome<BRegIngestionChunkReceipt>>
973
+ createIngestionRun(recordRoute: string, request: BRegIngestionRunInput): Promise<CompleteOutcome<BRegIngestionRun>>
974
+ listIngestionRuns(recordRoute: string, query?: BRegIngestionRunListInput | null): Promise<CompleteOutcome<BRegIngestionRunPage>>
975
+ readIngestionRun(recordRoute: string, runId: string, accessProfile?: string | null): Promise<CompleteOutcome<BRegIngestionRun>>
976
+ submitIngestionChunk(recordRoute: string, runId: string, chunk: BRegIngestionChunk, profileId: string): Promise<CompleteOutcome<BRegIngestionChunkSubmission>>
977
+ cancelIngestionRun(recordRoute: string, runId: string, accessProfile?: string | null): Promise<CompleteOutcome<BRegIngestionRun>>
978
+ ingestionChunkReceipt(recordRoute: string, runId: string, chunkIndex: SafeInteger, profileId: string): Promise<CompleteOutcome<BRegIngestionChunkReceipt>>
946
979
  tombstoneRecord(binding: BRegTombstoneBinding, recordIdentifier: string, etag: string, idempotencyKey: string, format?: RecordFormat | null): Promise<CompleteOutcome<RecordEnvelope>>
947
980
  tombstoneRecordJson(binding: BRegTombstoneBinding, recordIdentifier: string, etag: string, idempotencyKey: string, format?: RecordFormat | null): Promise<JsonOutcome>
948
- getRecordJson(entityRoute: string, recordIdentifier: string, options?: RecordOptions | null): Promise<JsonOutcome>
949
- listRecordsJson(entityRoute: string, options?: ListOptions | null): Promise<JsonOutcome>
981
+ getRecordJson(recordRoute: string, recordIdentifier: string, options?: RecordOptions | null): Promise<JsonOutcome>
982
+ listRecordsJson(recordRoute: string, options?: ListOptions | null): Promise<JsonOutcome>
950
983
  continueListJson(continuation: ListContinuation): Promise<JsonOutcome>
951
- getGeoJsonRecordJson(entityRoute: string, recordIdentifier: string, options?: GeoJsonOptions | null): Promise<JsonOutcome>
952
- listGeoJsonRecordsJson(entityRoute: string, options?: GeoJsonListOptions | null): Promise<JsonOutcome<GeoJsonListContinuation>>
984
+ getGeoJsonRecordJson(recordRoute: string, recordIdentifier: string, options?: GeoJsonOptions | null): Promise<JsonOutcome>
985
+ listGeoJsonRecordsJson(recordRoute: string, options?: GeoJsonListOptions | null): Promise<JsonOutcome<GeoJsonListContinuation>>
953
986
  continueGeoJsonListJson(continuation: GeoJsonListContinuation): Promise<JsonOutcome<GeoJsonListContinuation>>
954
- listCurrentRecordsJson(entityRoute: string, options?: CollectionOptions | null): Promise<JsonOutcome<CurrentListContinuation>>
987
+ listCurrentRecordsJson(recordRoute: string, options?: CollectionOptions | null): Promise<JsonOutcome<CurrentListContinuation>>
955
988
  continueCurrentListJson(continuation: CurrentListContinuation): Promise<JsonOutcome<CurrentListContinuation>>
956
- listRecordsAsOfJson(entityRoute: string, options: AsOfListOptions): Promise<JsonOutcome<AsOfListContinuation>>
989
+ listRecordsAsOfJson(recordRoute: string, options: AsOfListOptions): Promise<JsonOutcome<AsOfListContinuation>>
957
990
  continueAsOfListJson(continuation: AsOfListContinuation): Promise<JsonOutcome<AsOfListContinuation>>
958
- listSnapshotRecordsJson(entityRoute: string, options?: SnapshotListOptions | null): Promise<JsonOutcome<SnapshotListContinuation>>
991
+ listSnapshotRecordsJson(recordRoute: string, options?: SnapshotListOptions | null): Promise<JsonOutcome<SnapshotListContinuation>>
959
992
  continueSnapshotListJson(continuation: SnapshotListContinuation): Promise<JsonOutcome<SnapshotListContinuation>>
960
- listRelationshipRecordsJson(entityRoute: string, recordIdentifier: string, pathRoute: string, options?: CollectionOptions | null): Promise<JsonOutcome<RelationshipListContinuation>>
993
+ listRelationshipRecordsJson(recordRoute: string, recordIdentifier: string, pathRoute: string, options?: CollectionOptions | null): Promise<JsonOutcome<RelationshipListContinuation>>
961
994
  continueRelationshipListJson(continuation: RelationshipListContinuation): Promise<JsonOutcome<RelationshipListContinuation>>
962
- lookupRecordJson(entityRoute: string, selector: string, valuesJson?: string | null, options?: RecordProjectionOptions | null): Promise<JsonOutcome>
995
+ lookupRecordJson(recordRoute: string, selector: string, valuesJson?: string | null, options?: RecordProjectionOptions | null): Promise<JsonOutcome>
963
996
  createRecordJson(binding: BRegCreateBinding, dataJson: string, idempotencyKey: string, format?: RecordFormat | null): Promise<JsonOutcome>
964
997
  patchRecordJson(binding: BRegPatchBinding, recordIdentifier: string, etag: string, operationsJson: string, idempotencyKey: string, format?: RecordFormat | null): Promise<JsonOutcome>
965
998
  }
966
999
 
967
1000
  export type BRegProposalTransition = 'edit' | 'submit' | 'revise' | 'rebase' | 'retry' | 'cancel' | 'apply'
968
- export type BRegAvailabilityReason = 'pending-review' | 'review-rejected' | 'review-changes-requested' | 'review-ended' | 'stale-revision' | 'contract-changed' | 'dependency-outage' | 'invalid-input' | 'already-applied'
969
- export type BRegRecoveryHint = 'refresh' | 'revise' | 'retry' | 'correct-input' | 'receipt-only'
1001
+ export type BRegAvailabilityReason = 'pending-review' | 'review-rejected' | 'review-changes-requested' | 'review-ended' | 'stale-revision' | 'package-changed' | 'dependency-outage' | 'invalid-input' | 'already-applied'
1002
+ export type BRegRecoveryHint = 'refresh' | 'revise' | 'retry' | 'rebase' | 'correct-input' | 'receipt-only'
970
1003
  export type BRegAvailability =
971
1004
  | { readonly available: true; readonly observedRevision: number }
972
1005
  | { readonly available: false; readonly observedRevision: number; readonly reason: BRegAvailabilityReason; readonly recovery: BRegRecoveryHint }
@@ -985,8 +1018,8 @@ export interface BRegProposalApplication {
985
1018
  export interface BRegProposalApplicationStatus {
986
1019
  readonly state: 'awaiting-review' | 'pending' | 'applying' | 'blocked' | 'applied' | 'cancelled' | 'rejected'
987
1020
  readonly mode: 'automatic' | 'manual'
988
- readonly reason?: 'contract-changed' | 'dependency-outage' | 'lease-expired' | 'application-refused' | 'attempts-exhausted'
989
- readonly recovery?: 'retry' | 'correct-input'
1021
+ readonly reason?: 'package-changed' | 'dependency-outage' | 'lease-expired' | 'application-refused' | 'attempts-exhausted'
1022
+ readonly recovery?: 'retry' | 'rebase' | 'correct-input'
990
1023
  readonly automaticRetry?: {readonly scheduled: boolean; readonly attempts: number; readonly maximumAttempts: number}
991
1024
  }
992
1025
  export interface BRegProposalReviewDocument {
@@ -995,6 +1028,8 @@ export interface BRegProposalReviewDocument {
995
1028
  readonly subject: {readonly source: string; readonly subjectType: 'proposal'; readonly id: string; readonly version: string; readonly digest: string}
996
1029
  readonly context: {readonly reference: string; readonly contract?: {readonly id: string; readonly revision: string; readonly schemaDigest: string}; readonly fields?: Readonly<Record<string, JsonValue>>}
997
1030
  readonly requestId?: string
1031
+ /** Status reads only: where the submission stands with the Review provider. `reason` is present exactly when `state` is `failed`. */
1032
+ readonly handoff?: {readonly state: 'pending' | 'accepted' | 'failed' | 'withdrawn'; readonly reason?: 'remote-refused' | 'producer-identity-mismatch' | 'review-acceptance-changed' | 'review-policy-changed' | 'submission-recovery-expired' | 'operator-closed' | 'unspecified'}
998
1033
  readonly authority?: string; readonly policy?: {readonly id: string; readonly version: string; readonly digest: string}
999
1034
  readonly result?: {readonly state: 'pending' | 'approved' | 'rejected' | 'changes-requested' | 'answered' | 'cancelled' | 'superseded' | 'expired'; readonly resultId?: string; readonly completedAt?: string; readonly availableUntil?: string}
1000
1035
  }
@@ -1002,13 +1037,16 @@ export interface BRegProposalReviewDocument {
1002
1037
  export type BRegProposalTurn = 'party' | 'official' | 'nobody'
1003
1038
  /** The review decision on one submission. The public reason is the only reviewer text BReg serves. */
1004
1039
  export interface BRegProposalDecision { readonly status: 'approved' | 'rejected' | 'changes-requested' | 'answered'; readonly decidedAt: string; readonly publicReason?: string }
1040
+ /** Why the review authority refused to take a submission. BReg names only these codes and never the authority's own text. */
1041
+ export interface BRegProposalHandoffRefusal { readonly code: 'review.initiator-required' | 'review.initiator-excluded' | 'review.policy-mismatch' | 'review.refused' }
1005
1042
  export interface BRegProposalSubmission {
1006
1043
  readonly id: string; readonly actionId: string; readonly submissionVersion: number; readonly current: boolean; readonly effectDigest: string
1007
1044
  readonly review: NonNullable<BRegProposalReviewDocument['result']> | null
1008
1045
  readonly application: (Omit<BRegProposalApplicationStatus, 'mode'> & {readonly mode?: BRegProposalApplicationStatus['mode']; readonly applicationId?: string; readonly appliedBy?: string; readonly appliedAt?: string}) | null
1009
1046
  readonly decision?: BRegProposalDecision
1047
+ readonly handoffRefusal?: BRegProposalHandoffRefusal
1010
1048
  }
1011
- export interface BRegProposalDocument { readonly id: string; readonly actionId: string; readonly actionRevision: string; readonly submissionVersion: number; readonly revision: number; readonly state: 'draft' | 'submitted' | 'cancelled' | 'applied' | 'rejected'; readonly turn?: BRegProposalTurn; readonly decision?: BRegProposalDecision; readonly title?: string; readonly input?: JsonObject; readonly blockedReason?: 'package-changed'; readonly effectDigest?: string; readonly application?: BRegProposalApplication; readonly applicationStatus?: BRegProposalApplicationStatus; readonly links: Readonly<Partial<Record<BRegProposalTransition | 'self' | 'reviewContext' | 'reviewStatus', BRegProposalLink>>>; readonly attachments?: Readonly<Record<string, BRegProposalAttachment>> }
1049
+ export interface BRegProposalDocument { readonly id: string; readonly actionId: string; readonly actionRevision: string; readonly submissionVersion: number; readonly revision: number; readonly state: 'draft' | 'submitted' | 'cancelled' | 'applied' | 'rejected'; readonly createdAt?: string; readonly turn?: BRegProposalTurn; readonly decision?: BRegProposalDecision; readonly handoffRefusal?: BRegProposalHandoffRefusal; readonly title?: string; readonly input?: JsonObject; readonly blockedReason?: 'package-changed'; readonly effectDigest?: string; readonly application?: BRegProposalApplication; readonly applicationStatus?: BRegProposalApplicationStatus; readonly links: Readonly<Partial<Record<BRegProposalTransition | 'self' | 'reviewContext' | 'reviewStatus', BRegProposalLink>>>; readonly attachments?: Readonly<Record<string, BRegProposalAttachment>> }
1012
1050
  export declare class BRegProposal { private constructor(); private readonly __opaque: void; readonly identifier: string; readonly actionIdentifier: string; readonly documentJson: string; readonly inputJson?: string | null }
1013
1051
  export declare class BRegProposalGetBinding { private constructor(); private readonly __opaque: void }
1014
1052
  export declare class BRegProposalReviewBinding { private constructor(); private readonly __opaque: void }
package/breg/client.js CHANGED
@@ -16,7 +16,7 @@ class BaseRegistryClientError extends Error {
16
16
  for (const field of ['code', 'refusalCode', 'reasonCode', 'status', 'traceId', 'transportKind', 'tokenKind']) {
17
17
  if (envelope[field] !== undefined && envelope[field] !== null) this[field] = envelope[field];
18
18
  }
19
- for (const field of ['fieldPath', 'constraint']) {
19
+ for (const field of ['fieldPath', 'constraint', 'guardReason']) {
20
20
  if (envelope[field] !== undefined && envelope[field] !== null) {
21
21
  Object.defineProperty(this, field, {
22
22
  value: envelope[field],
@@ -82,7 +82,7 @@ function plainDataObject(value, expectedFields) {
82
82
  return result;
83
83
  }
84
84
 
85
- function webhookHeaders(value) {
85
+ function hookHeaders(value) {
86
86
  if (value === null || typeof value !== 'object' || Array.isArray(value) || isProxy(value)) {
87
87
  throw inputError('invalid-request');
88
88
  }
@@ -102,7 +102,7 @@ function webhookHeaders(value) {
102
102
  return result;
103
103
  }
104
104
 
105
- function verifyWebhookDelivery(value) {
105
+ function verifyHookDelivery(value) {
106
106
  try {
107
107
  const input = plainDataObject(value, ['method', 'path', 'headers', 'body', 'key']);
108
108
  if (typeof input.method !== 'string' || typeof input.path !== 'string'
@@ -110,10 +110,19 @@ function verifyWebhookDelivery(value) {
110
110
  || isSharedArrayBuffer(input.body.buffer) || isSharedArrayBuffer(input.key.buffer)) {
111
111
  throw inputError('invalid-request');
112
112
  }
113
- input.headers = webhookHeaders(input.headers);
113
+ input.headers = hookHeaders(input.headers);
114
114
  input.body = Buffer.from(input.body);
115
115
  input.key = Buffer.from(input.key);
116
- return native.verifyWebhookDelivery(input);
116
+ return native.verifyHookDelivery(input);
117
+ } catch (error) {
118
+ throw normalize(error, 'invalid-request');
119
+ }
120
+ }
121
+
122
+ function eventRecordView(argumentsJson) {
123
+ try {
124
+ if (typeof argumentsJson !== 'string') throw inputError('invalid-request');
125
+ return native.eventRecordView(argumentsJson);
117
126
  } catch (error) {
118
127
  throw normalize(error, 'invalid-request');
119
128
  }
@@ -207,11 +216,11 @@ function wrapAsync(name, jsonIndexes = [], requiredIndexes = []) {
207
216
  }
208
217
 
209
218
  for (const [method, jsonIndexes, requiredIndexes] of [
210
- ['health'], ['ready'], ['openapi'], ['registryMetadata'], ['registryContract'], ['entitySchema'],
219
+ ['health'], ['ready'], ['openapi'], ['registryMetadata'], ['registryContract'], ['recordSchema'],
211
220
  ['statisticsLive'], ['statisticsReleases'], ['statisticsLatestRelease'],
212
221
  ['statisticsReleaseVersion'], ['statisticsReleaseSeries'], ['statisticsPublish'],
213
222
  ['statisticsWithdraw'],
214
- ['recordRevisions'], ['getRecordRevision', [3]],
223
+ ['recordRevisions'], ['getRecordRevision', [3]], ['eventRecordCreationRevision'],
215
224
  ['getRecord', [2]], ['listRecords', [1]], ['continueList', [0], [0]],
216
225
  ['getGeoJsonRecord', [2]], ['listGeoJsonRecords', [1]], ['continueGeoJsonList', [0], [0]],
217
226
  ['listCurrentRecords', [1]], ['continueCurrentList', [0], [0]],
@@ -223,7 +232,7 @@ for (const [method, jsonIndexes, requiredIndexes] of [
223
232
  ['invokeAction', [1], [1]],
224
233
  ['executeRecoveredAction'], ['executeRecoveredProposalStart'], ['executeRecoveredCreate'],
225
234
  ['patchRecord', [3], [3]], ['batchRecords', [1], [1]], ['tombstoneRecord'],
226
- ['startProposal'], ['readProposal'], ['readProposalSubmission'], ['getProposal'], ['listProposals'], ['executeProposal'],
235
+ ['startProposal', [1], [1]], ['readProposal'], ['readProposalSubmission'], ['getProposal'], ['listProposals', [1], [1]], ['executeProposal'], ['listProposalsJson'],
227
236
  ['downloadProposalAttachment'], ['uploadProposalAttachment'], ['deleteProposalAttachment'],
228
237
  ['readProposalReviewStatus'], ['readProposalReviewContext'],
229
238
  ['readProposalReviewContextBatch', [1], [1]],
@@ -247,7 +256,7 @@ for (const [method, jsonIndexes, requiredIndexes] of [
247
256
  ['prepareAction', [1], [1]], ['prepareActionJson'],
248
257
  ['recoverAction', [2], [2]], ['recoverActionJson'],
249
258
  ['prepareCreate', [1], [1]], ['prepareCreateJson'], ['recoverCreate'],
250
- ['prepareProposal'], ['recoverProposal'],
259
+ ['prepareProposal', [2], [2]], ['prepareProposalJson'], ['recoverProposal'],
251
260
  ]) {
252
261
  const original = native.BaseRegistryClient.prototype[method];
253
262
  native.BaseRegistryClient.prototype[method] = function (...args) {
@@ -298,7 +307,7 @@ const BRegPreparedProposal = preparedClass(native.BRegPreparedProposal, 'BRegPre
298
307
  for (const name of [
299
308
  'selectCreate', 'selectPatch',
300
309
  'selectAction', 'selectTombstone', 'selectBatch', 'selectProposals', 'selectProposalGet',
301
- 'selectProposalReviewContext', 'selectProposalReviewStatus',
310
+ 'selectProposalReviewContext', 'selectProposalReviewStatus', 'eventRecordDescriptor',
302
311
  ]) {
303
312
  const original = native.BRegMetadata.prototype[name];
304
313
  native.BRegMetadata.prototype[name] = function (...args) {
@@ -373,7 +382,8 @@ class PrivateKeyJwt {
373
382
  }
374
383
 
375
384
  module.exports = {
376
- verifyWebhookDelivery,
385
+ verifyHookDelivery,
386
+ eventRecordView,
377
387
  PrivateKeyJwt,
378
388
  BaseRegistryClient,
379
389
  BaseRegistryClientError,