@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/breg/index.d.ts CHANGED
@@ -15,27 +15,33 @@ export declare class BaseRegistryClient {
15
15
  statisticsPublish(dataset: string, period: string, status: string, accessProfile: string, idempotencyKey: string): Promise<RawOutcome>
16
16
  statisticsWithdraw(dataset: string, period: string, version: number, reason: string, accessProfile: string, idempotencyKey: string): Promise<RawOutcome>
17
17
  registryContract(accessProfile?: string | undefined | null): Promise<BRegMetadata>
18
- entitySchema(recordTypeIdentifier: string, accessProfile?: string | undefined | null): Promise<RawOutcome>
18
+ recordSchema(recordTypeIdentifier: string, accessProfile?: string | undefined | null): Promise<RawOutcome>
19
19
  /** Retrieve one bounded first page of record revisions as inert JSON. */
20
- recordRevisions(entityRoute: string, recordIdentifier: string, accessProfile?: string | undefined | null): Promise<RawOutcome>
20
+ recordRevisions(recordRoute: string, recordIdentifier: string, accessProfile?: string | undefined | null): Promise<RawOutcome>
21
21
  /** Retrieve one exact retained revision as validated inert record JSON. */
22
- getRecordRevision(entityRoute: string, recordIdentifier: string, revision: number, options?: any | undefined | null): Promise<RawOutcome>
23
- getRecord(entityRoute: string, recordIdentifier: string, options?: any | undefined | null): Promise<CompleteOutcome>
24
- listRecords(entityRoute: string, options?: any | undefined | null): Promise<PageOutcome>
22
+ getRecordRevision(recordRoute: string, recordIdentifier: string, revision: number, options?: any | undefined | null): Promise<RawOutcome>
23
+ /**
24
+ * Read the first revision of one record as the compact
25
+ * `{recordType, recordId, revision, createdAt}` JSON, or null when the
26
+ * caller may not read it.
27
+ */
28
+ eventRecordCreationRevision(recordRoute: string, recordIdentifier: string, accessProfile?: string | undefined | null): Promise<string | null>
29
+ getRecord(recordRoute: string, recordIdentifier: string, options?: any | undefined | null): Promise<CompleteOutcome>
30
+ listRecords(recordRoute: string, options?: any | undefined | null): Promise<PageOutcome>
25
31
  continueList(value: any): Promise<PageOutcome>
26
- getGeoJsonRecord(entityRoute: string, recordIdentifier: string, options?: any | undefined | null): Promise<CompleteOutcome>
27
- listGeoJsonRecords(entityRoute: string, options?: any | undefined | null): Promise<PageOutcome>
32
+ getGeoJsonRecord(recordRoute: string, recordIdentifier: string, options?: any | undefined | null): Promise<CompleteOutcome>
33
+ listGeoJsonRecords(recordRoute: string, options?: any | undefined | null): Promise<PageOutcome>
28
34
  continueGeoJsonList(value: any): Promise<PageOutcome>
29
- listCurrentRecords(entityRoute: string, options?: any | undefined | null): Promise<PageOutcome>
35
+ listCurrentRecords(recordRoute: string, options?: any | undefined | null): Promise<PageOutcome>
30
36
  continueCurrentList(value: any): Promise<PageOutcome>
31
- listRecordsAsOf(entityRoute: string, options?: any | undefined | null): Promise<PageOutcome>
37
+ listRecordsAsOf(recordRoute: string, options?: any | undefined | null): Promise<PageOutcome>
32
38
  continueAsOfList(value: any): Promise<PageOutcome>
33
- listSnapshotRecords(entityRoute: string, options?: any | undefined | null): Promise<PageOutcome>
39
+ listSnapshotRecords(recordRoute: string, options?: any | undefined | null): Promise<PageOutcome>
34
40
  continueSnapshotList(value: any): Promise<PageOutcome>
35
- listRelationshipRecords(entityRoute: string, recordIdentifier: string, pathRoute: string, options?: any | undefined | null): Promise<PageOutcome>
41
+ listRelationshipRecords(recordRoute: string, recordIdentifier: string, pathRoute: string, options?: any | undefined | null): Promise<PageOutcome>
36
42
  continueRelationshipList(value: any): Promise<PageOutcome>
37
- lookupRecord(entityRoute: string, selector: string, values?: any | undefined | null, options?: any | undefined | null): Promise<CompleteOutcome>
38
- startProposal(binding: BRegActionBinding, inputsJson: string, key: string): Promise<BRegProposal>
43
+ lookupRecord(recordRoute: string, selector: string, values?: any | undefined | null, options?: any | undefined | null): Promise<CompleteOutcome>
44
+ startProposal(binding: BRegActionBinding, inputs: any, key: string): Promise<BRegProposal>
39
45
  readProposal(proposal: BRegProposal): Promise<BRegProposal>
40
46
  readProposalSubmission(proposal: BRegProposal, version: number): Promise<CompleteOutcome>
41
47
  getProposal(binding: BRegProposalGetBinding, id: string): Promise<BRegProposal>
@@ -47,8 +53,12 @@ export declare class BaseRegistryClient {
47
53
  readProposalReviewContextBatch(binding: BRegProposalReviewBinding, ids: Array<string>): Promise<CompleteOutcome>
48
54
  uploadProposalAttachment(proposal: BRegProposal, slot: string, contentType: string, bytes: Buffer, key: string): Promise<BRegProposal>
49
55
  deleteProposalAttachment(proposal: BRegProposal, slot: string, key: string): Promise<BRegProposal>
50
- listProposals(collection: BRegProposalCollection, queryJson: string): Promise<ProposalPage>
51
- prepareProposal(proposal: BRegProposal, operation: string, bodyJson: string, key: string): BRegPreparedProposal
56
+ listProposals(collection: BRegProposalCollection, query: any): Promise<ProposalPage>
57
+ prepareProposal(proposal: BRegProposal, operation: string, body: any, key: string): BRegPreparedProposal
58
+ /** Prepare a transition from exact JSON through the same lifecycle authority. */
59
+ prepareProposalJson(proposal: BRegProposal, operation: string, bodyJson: string, key: string): BRegPreparedProposal
60
+ /** List through the same metadata-selected collection with an exact JSON query. */
61
+ listProposalsJson(collection: BRegProposalCollection, queryJson: string): Promise<ProposalPage>
52
62
  recoverProposal(proposal: BRegProposal, attempt: BRegPreparedProposal): BRegPreparedProposal
53
63
  executeProposal(attempt: BRegPreparedProposal): Promise<BRegProposal>
54
64
  /** Fetch opaque target conditions for one metadata-selected action. */
@@ -58,7 +68,7 @@ export declare class BaseRegistryClient {
58
68
  /**
59
69
  * Invoke one metadata-selected immediate action. An invocation whose
60
70
  * outcome is unknown is resent identically under the same key, at most
61
- * `maxMutationRetries` times.
71
+ * `maximumMutationRetries` times.
62
72
  */
63
73
  invokeAction(binding: BRegActionBinding, inputs: any, idempotencyKey: string, conditions?: BRegActionTargetConditions | undefined | null): Promise<CompleteOutcome>
64
74
  /**
@@ -75,7 +85,7 @@ export declare class BaseRegistryClient {
75
85
  /**
76
86
  * Explicitly send a recovered invocation under its original key. An
77
87
  * invocation whose outcome is unknown is resent identically under that
78
- * key, at most `maxMutationRetries` times.
88
+ * key, at most `maximumMutationRetries` times.
79
89
  */
80
90
  executeRecoveredAction(binding: BRegActionBinding, recovered: BRegRecoveredAction): Promise<CompleteOutcome>
81
91
  /** Execute a recovered proposal start with its exact original request and key. */
@@ -91,7 +101,7 @@ export declare class BaseRegistryClient {
91
101
  /**
92
102
  * Execute one metadata-selected atomic batch. A batch whose outcome is
93
103
  * unknown is resent identically under the same key, at most
94
- * `maxMutationRetries` times.
104
+ * `maximumMutationRetries` times.
95
105
  */
96
106
  batchRecords(binding: BRegBatchBinding, request: any, idempotencyKey: string): Promise<CompleteOutcome>
97
107
  /**
@@ -99,42 +109,42 @@ export declare class BaseRegistryClient {
99
109
  * run request names the access profile, which the client selects for the
100
110
  * exchange.
101
111
  */
102
- createIngestionRun(entityRoute: string, request: any): Promise<CompleteOutcome>
103
- /** Read one bounded page of ingestion runs for one entity route. */
104
- listIngestionRuns(entityRoute: string, query?: any | undefined | null): Promise<CompleteOutcome>
112
+ createIngestionRun(recordRoute: string, request: any): Promise<CompleteOutcome>
113
+ /** Read one bounded page of ingestion runs for one record route. */
114
+ listIngestionRuns(recordRoute: string, query?: any | undefined | null): Promise<CompleteOutcome>
105
115
  /** Read the current durable state of one ingestion run. */
106
- readIngestionRun(entityRoute: string, runId: string, accessProfile?: string | undefined | null): Promise<CompleteOutcome>
116
+ readIngestionRun(recordRoute: string, runId: string, accessProfile?: string | undefined | null): Promise<CompleteOutcome>
107
117
  /**
108
118
  * Submit one bounded chunk of an open ingestion run under the run's
109
119
  * access profile. A resubmitted chunk replays its retained receipt
110
120
  * instead of executing twice.
111
121
  */
112
- submitIngestionChunk(entityRoute: string, runId: string, chunk: BRegIngestionChunk, profileId: string): Promise<CompleteOutcome>
122
+ submitIngestionChunk(recordRoute: string, runId: string, chunk: BRegIngestionChunk, profileId: string): Promise<CompleteOutcome>
113
123
  /** Cancel an open ingestion run. Committed chunks stay committed. */
114
- cancelIngestionRun(entityRoute: string, runId: string, accessProfile?: string | undefined | null): Promise<CompleteOutcome>
124
+ cancelIngestionRun(recordRoute: string, runId: string, accessProfile?: string | undefined | null): Promise<CompleteOutcome>
115
125
  /**
116
126
  * Read the retained receipt of one committed chunk under the run's
117
127
  * access profile. An erased receipt answers with the
118
128
  * `ingestion.receipt_erased` problem instead.
119
129
  */
120
- ingestionChunkReceipt(entityRoute: string, runId: string, chunkIndex: number, profileId: string): Promise<CompleteOutcome>
130
+ ingestionChunkReceipt(recordRoute: string, runId: string, chunkIndex: number, profileId: string): Promise<CompleteOutcome>
121
131
  /** Tombstone one record against its current strong ETag. */
122
132
  tombstoneRecord(binding: BRegTombstoneBinding, recordIdentifier: string, etag: string, idempotencyKey: string, formatValue?: string | undefined | null): Promise<CompleteOutcome>
123
- getRecordJson(entityRoute: string, recordIdentifier: string, options?: any | undefined | null): Promise<JsonOutcome>
124
- listRecordsJson(entityRoute: string, options?: any | undefined | null): Promise<JsonOutcome>
133
+ getRecordJson(recordRoute: string, recordIdentifier: string, options?: any | undefined | null): Promise<JsonOutcome>
134
+ listRecordsJson(recordRoute: string, options?: any | undefined | null): Promise<JsonOutcome>
125
135
  continueListJson(value: any): Promise<JsonOutcome>
126
- getGeoJsonRecordJson(entityRoute: string, recordIdentifier: string, options?: any | undefined | null): Promise<JsonOutcome>
127
- listGeoJsonRecordsJson(entityRoute: string, options?: any | undefined | null): Promise<JsonOutcome>
136
+ getGeoJsonRecordJson(recordRoute: string, recordIdentifier: string, options?: any | undefined | null): Promise<JsonOutcome>
137
+ listGeoJsonRecordsJson(recordRoute: string, options?: any | undefined | null): Promise<JsonOutcome>
128
138
  continueGeoJsonListJson(value: any): Promise<JsonOutcome>
129
- listCurrentRecordsJson(entityRoute: string, options?: any | undefined | null): Promise<JsonOutcome>
139
+ listCurrentRecordsJson(recordRoute: string, options?: any | undefined | null): Promise<JsonOutcome>
130
140
  continueCurrentListJson(value: any): Promise<JsonOutcome>
131
- listRecordsAsOfJson(entityRoute: string, options?: any | undefined | null): Promise<JsonOutcome>
141
+ listRecordsAsOfJson(recordRoute: string, options?: any | undefined | null): Promise<JsonOutcome>
132
142
  continueAsOfListJson(value: any): Promise<JsonOutcome>
133
- listSnapshotRecordsJson(entityRoute: string, options?: any | undefined | null): Promise<JsonOutcome>
143
+ listSnapshotRecordsJson(recordRoute: string, options?: any | undefined | null): Promise<JsonOutcome>
134
144
  continueSnapshotListJson(value: any): Promise<JsonOutcome>
135
- listRelationshipRecordsJson(entityRoute: string, recordIdentifier: string, pathRoute: string, options?: any | undefined | null): Promise<JsonOutcome>
145
+ listRelationshipRecordsJson(recordRoute: string, recordIdentifier: string, pathRoute: string, options?: any | undefined | null): Promise<JsonOutcome>
136
146
  continueRelationshipListJson(value: any): Promise<JsonOutcome>
137
- lookupRecordJson(entityRoute: string, selector: string, valuesJson?: string | undefined | null, options?: any | undefined | null): Promise<JsonOutcome>
147
+ lookupRecordJson(recordRoute: string, selector: string, valuesJson?: string | undefined | null, options?: any | undefined | null): Promise<JsonOutcome>
138
148
  /** Fetch opaque target conditions from exact action-input JSON. */
139
149
  actionTargetConditionsJson(binding: BRegActionBinding, inputsJson: string): Promise<BRegActionTargetConditions>
140
150
  /** Read field-guard availability from exact action-input JSON. */
@@ -207,6 +217,8 @@ export declare class BRegIngestionPrefixDigest {
207
217
  export type IngestionPrefixDigest = BRegIngestionPrefixDigest
208
218
 
209
219
  export declare class BRegMetadata {
220
+ /** The event record descriptor declared for one record type, as JSON text. */
221
+ eventRecordDescriptor(recordType: string): string
210
222
  /** Read-only capability inventory for each exact Action/profile pair. */
211
223
  get proposalActions(): any
212
224
  /** Caller-filtered inert descriptors. Selectors below remain the only authority constructors. */
@@ -328,6 +340,22 @@ export interface CompleteOutcome {
328
340
  */
329
341
  export declare function encodeIngestionChunk(chunkIndex: number, items: any, prefixDigest: string): BRegIngestionChunk
330
342
 
343
+ /**
344
+ * Project one record revision into the event record view. The input is the
345
+ * JSON arguments document of the Rust projection; the result is the view
346
+ * document as JSON text.
347
+ */
348
+ export declare function eventRecordView(argumentsJson: string): string
349
+
350
+ /** Exact BReg hook request supplied by a receiver. */
351
+ export interface HookDeliveryInput {
352
+ method: string
353
+ path: string
354
+ headers: Record<string, string>
355
+ body: Buffer
356
+ key: Buffer
357
+ }
358
+
331
359
  /** Validated product result serialized before the JavaScript number boundary. */
332
360
  export interface JsonOutcome {
333
361
  kind: string
@@ -364,8 +392,8 @@ export interface RawOutcome {
364
392
  reprDigest?: string
365
393
  }
366
394
 
367
- /** Authenticated BReg webhook metadata and exact body. */
368
- export interface VerifiedWebhookDelivery {
395
+ /** Authenticated BReg hook metadata and exact body. */
396
+ export interface VerifiedHookDelivery {
369
397
  id: string
370
398
  source: string
371
399
  type: string
@@ -378,14 +406,5 @@ export interface VerifiedWebhookDelivery {
378
406
  body: Buffer
379
407
  }
380
408
 
381
- /** Verify a BReg Version 1 webhook signature without applying receiver policy. */
382
- export declare function verifyWebhookDelivery(input: WebhookDeliveryInput): VerifiedWebhookDelivery
383
-
384
- /** Exact BReg webhook request supplied by a receiver. */
385
- export interface WebhookDeliveryInput {
386
- method: string
387
- path: string
388
- headers: Record<string, string>
389
- body: Buffer
390
- key: Buffer
391
- }
409
+ /** Verify a BReg Version 1 hook signature without applying receiver policy. */
410
+ export declare function verifyHookDelivery(input: HookDeliveryInput): VerifiedHookDelivery
@@ -8,11 +8,11 @@ export type JsonObject = { readonly [key: string]: JsonValue }
8
8
 
9
9
  export interface CaseworkClientConfig {
10
10
  baseUrl: string
11
- requestTimeoutMilliseconds?: SafeInteger | null
12
- connectTimeoutMilliseconds?: SafeInteger | null
13
- maxResponseBytes?: SafeInteger | null
14
- userAgent?: string | null
15
- trustedRootCertificates?: string | null
11
+ attemptTimeoutMilliseconds?: SafeInteger
12
+ connectTimeoutMilliseconds?: SafeInteger
13
+ maximumResponseBytes?: SafeInteger
14
+ userAgent?: string
15
+ trustedRootCertificates?: string
16
16
  /**
17
17
  * How many times an idempotency-keyed mutation whose outcome is unknown is
18
18
  * resent, identically and under the same key, before its error is
@@ -20,7 +20,7 @@ export interface CaseworkClientConfig {
20
20
  * unkeyed operations, and review request create and cancel are never
21
21
  * resent. Any other value is a `configuration` error.
22
22
  */
23
- maxMutationRetries?: SafeInteger | null
23
+ maximumMutationRetries?: SafeInteger
24
24
  }
25
25
 
26
26
  export type PageStatus = 'complete' | 'budget-exhausted' | 'source-unavailable'
@@ -72,7 +72,7 @@ export type DirectoryTargetPage = Page<DirectoryMember>
72
72
  export interface QueueRecord { id: string; label: string }
73
73
  export type RoutingPredicate = { equals: JsonValue } | { oneOf: ReadonlyArray<JsonValue> }
74
74
  export interface RoutingCondition { stage?: string; fields?: Readonly<Record<string, RoutingPredicate>> }
75
- export interface RoutingRule { id: string; because: string; when: RoutingCondition; queue: string }
75
+ export interface RoutingRule { id: string; label?: string; because: string; when: RoutingCondition; queue: string }
76
76
  export type WorkingWeekday = 'monday' | 'tuesday' | 'wednesday' | 'thursday' | 'friday' | 'saturday' | 'sunday'
77
77
  export interface CalendarPolicy { id: string; timezone: string; workingWeekdays: ReadonlyArray<WorkingWeekday>; holidaySet: string }
78
78
  export interface WorkingDays { workingDays: SafeInteger }
@@ -189,7 +189,7 @@ export class CaseworkClientError extends Error {
189
189
  readonly traceId?: string
190
190
  readonly validation?: {
191
191
  readonly path: string
192
- readonly reason: 'policy-not-allowed' | 'reference-invalid' | 'object-required' | 'maximum-bytes-exceeded' | 'maximum-depth-exceeded' | 'schema-mismatch' | 'outcome-not-declared' | 'reason-required' | 'text-invalid' | 'result-not-declared' | 'result-required' | 'field-not-declared' | 'constraint-invalid' | 'constraint-violated' | 'public-reason-required' | 'public-reason-not-declared' | 'approval-outcome-differs'
192
+ readonly reason: 'binding-invalid' | 'field-required' | 'policy-not-allowed' | 'reference-invalid' | 'object-required' | 'maximum-bytes-exceeded' | 'maximum-depth-exceeded' | 'schema-mismatch' | 'outcome-not-declared' | 'reason-required' | 'text-invalid' | 'result-not-declared' | 'result-required' | 'field-not-declared' | 'constraint-invalid' | 'constraint-violated' | 'public-reason-required' | 'public-reason-not-declared' | 'approval-outcome-differs'
193
193
  /** Outcome identifiers the review policy declares for the requested settlement when an outcome is refused; empty otherwise. */
194
194
  readonly allowed: ReadonlyArray<string>
195
195
  }
@@ -364,15 +364,16 @@ export interface ReviewAccountabilityRecord {
364
364
  occurredAt: string; retainedUntil: string
365
365
  decisionReceipt?: ReviewDecisionReceipt
366
366
  }
367
- export interface ReviewStagePolicy { id: string; queue: string; decidingProfiles: ReadonlyArray<string>; requiredApprovals: SafeInteger; excludeInitiator?: boolean; excludePreviousStageReviewers?: boolean }
367
+ export interface ReviewStagePolicy { id: string; label?: string; queue: string; decidingProfiles: ReadonlyArray<string>; requiredApprovals: SafeInteger; negativeDecisions?: 'settle' | 'advise'; excludeInitiator?: boolean; excludePreviousStageReviewers?: boolean }
368
368
  export interface ReviewRetentionPolicy { terminalRetentionDays: SafeInteger; accountabilityRetentionDays: SafeInteger }
369
369
  export interface ReviewContextContract { id: string; revision: ContentDigest; schemaDigest: ContentDigest }
370
370
  export type ReviewContextPolicy = { mode: 'submitted' } | { mode: 'current-source'; provider: string; contract: ReviewContextContract }
371
371
  export type ReviewContextCapability = 'human-display' | 'service-status' | 'task-grant-context' | 'routing-context'
372
372
  export interface ReviewContextProviderPolicy { id: string; capabilities: ReadonlyArray<ReviewContextCapability>; sourceNamespace: string; deploymentRef: string; serviceProfiles?: Partial<Record<ReviewContextCapability, string>> }
373
- export interface ReviewPolicy { id: string; version: string; purpose: 'approval' | 'answer'; context: ReviewContextPolicy; routing?: ReadonlyArray<RoutingRule>; stages: ReadonlyArray<ReviewStagePolicy>; clocks?: ReadonlyArray<string>; retention: ReviewRetentionPolicy; displaySchema: JsonValue; resultSchema?: JsonValue; outcomes?: ReadonlyArray<{ id: string; label: string; settlement: 'approved' | 'rejected' | 'changes-requested' | 'answered'; reasonRequired: boolean; publicReason: 'required' | 'optional' | 'none'; resultRequired?: boolean }> }
373
+ export interface ReviewPolicy { id: string; label?: string; version: string; purpose: 'approval' | 'answer'; context: ReviewContextPolicy; routing?: ReadonlyArray<RoutingRule>; stages: ReadonlyArray<ReviewStagePolicy>; clocks?: ReadonlyArray<string>; retention: ReviewRetentionPolicy; displaySchema: JsonValue; resultSchema?: JsonValue; outcomes?: ReadonlyArray<{ id: string; label: string; settlement: 'approved' | 'rejected' | 'changes-requested' | 'answered'; reasonRequired: boolean; publicReason: 'required' | 'optional' | 'none'; resultRequired?: boolean }> }
374
374
  export interface ReviewPolicyClosure {
375
375
  identity: PolicyBinding
376
+ label?: string
376
377
  purpose: 'approval' | 'answer'
377
378
  context: ReviewContextPolicy
378
379
  routing?: ReadonlyArray<RoutingRule>
@@ -85,12 +85,50 @@ function sanitize(value, kind) {
85
85
  return cloneJson(value, { nodes: 0, bytes: 0, active: new WeakSet() }, 0, kind);
86
86
  }
87
87
 
88
+ function configurationValue(config) {
89
+ if (!config || typeof config !== 'object' || Array.isArray(config) || isProxy(config)) {
90
+ throw normalized({}, 'configuration');
91
+ }
92
+ const prototype = Object.getPrototypeOf(config);
93
+ if (prototype !== Object.prototype && prototype !== null) {
94
+ throw normalized({}, 'configuration');
95
+ }
96
+ const allowed = new Set([
97
+ 'baseUrl',
98
+ 'attemptTimeoutMilliseconds',
99
+ 'connectTimeoutMilliseconds',
100
+ 'maximumResponseBytes',
101
+ 'userAgent',
102
+ 'trustedRootCertificates',
103
+ 'maximumMutationRetries',
104
+ ]);
105
+ const copy = Object.create(null);
106
+ for (const key of Reflect.ownKeys(config)) {
107
+ if (typeof key !== 'string' || !allowed.has(key)) throw normalized({}, 'configuration');
108
+ const descriptor = Object.getOwnPropertyDescriptor(config, key);
109
+ if (!descriptor || !descriptor.enumerable || !Object.hasOwn(descriptor, 'value')) {
110
+ throw normalized({}, 'configuration');
111
+ }
112
+ const value = descriptor.value;
113
+ if (key === 'baseUrl' || key === 'userAgent' || key === 'trustedRootCertificates') {
114
+ if (typeof value !== 'string') throw normalized({}, 'configuration');
115
+ copy[key] = value;
116
+ } else {
117
+ if (!Number.isSafeInteger(value) || value < 0 || value > 0xffff_ffff) {
118
+ throw normalized({}, 'configuration');
119
+ }
120
+ copy[key] = value;
121
+ }
122
+ }
123
+ return copy;
124
+ }
125
+
88
126
  const NativeCaseworkClient = native.CaseworkClient;
89
127
 
90
128
  class CaseworkClient {
91
129
  constructor(config) {
92
130
  try {
93
- this.native = new NativeCaseworkClient(sanitize(config, 'configuration'));
131
+ this.native = new NativeCaseworkClient(configurationValue(config));
94
132
  } catch (error) {
95
133
  throw normalized(error, 'configuration');
96
134
  }
@@ -55,16 +55,16 @@ export declare class CaseworkClient {
55
55
 
56
56
  export interface CaseworkClientConfig {
57
57
  baseUrl: string
58
- requestTimeoutMilliseconds?: number
58
+ attemptTimeoutMilliseconds?: number
59
59
  connectTimeoutMilliseconds?: number
60
- maxResponseBytes?: number
60
+ maximumResponseBytes?: number
61
61
  userAgent?: string
62
62
  trustedRootCertificates?: string
63
63
  /**
64
64
  * How many times a keyed mutation whose outcome is unknown is resent under
65
65
  * the same idempotency key: 0 to 2, default 2, and 0 disables the resend.
66
66
  */
67
- maxMutationRetries?: number
67
+ maximumMutationRetries?: number
68
68
  }
69
69
 
70
70
  export interface CaseworkOutcome {
@@ -0,0 +1,18 @@
1
+ {
2
+ "schemaVersion": "registry-stack.sdk-compatibility.v1",
3
+ "sdkPackage": {
4
+ "name": "registry-stack-client",
5
+ "version": "0.45.0"
6
+ },
7
+ "namespaces": {
8
+ "discovery": {
9
+ "testedServerBaseline": "0.45.0",
10
+ "compatibleServerPatchLine": "0.45.x",
11
+ "responseCompatibility": {
12
+ "additiveObjectMembers": "ignored-after-duplicate-key-rejection",
13
+ "unknownProblemCodes": "http-status-only",
14
+ "proof": "registry-discovery-client::client::tests::real_client_ignores_additive_response_members_at_every_response_level"
15
+ }
16
+ }
17
+ }
18
+ }
@@ -0,0 +1,248 @@
1
+ /** An integer for which `Number.isSafeInteger` is true. */
2
+ export type SafeInteger = number
3
+ /** A lowercase hyphenated UUID, checked before any request is sent. */
4
+ export type RunId = string
5
+ /** An RFC 3339 instant returned by Coordinator. */
6
+ export type Instant = string
7
+ export type JsonScalar = string | number | boolean | null
8
+ export type JsonValue = JsonScalar | ReadonlyArray<JsonValue> | { readonly [key: string]: JsonValue }
9
+
10
+ export interface CoordinatorClientConfig {
11
+ baseUrl: string
12
+ attemptTimeoutMilliseconds?: SafeInteger
13
+ connectTimeoutMilliseconds?: SafeInteger
14
+ maximumResponseBytes?: SafeInteger
15
+ userAgent?: string
16
+ /** Additional trust roots for the deployment, as PEM text. */
17
+ trustedRootCertificates?: string
18
+ /**
19
+ * How many times an admission whose outcome is unknown is resent,
20
+ * identically and under the same idempotency key, before its error is
21
+ * returned: a whole number from 0 to 2, default 2; 0 sends it once. Any
22
+ * other value is a `configuration` error.
23
+ */
24
+ maximumMutationRetries?: SafeInteger
25
+ }
26
+
27
+ export interface StartRunRequest { workflow: string; workflowRevision: string; input: JsonValue }
28
+
29
+ /** The active compiled contract under current start authority. */
30
+ export interface WorkflowContract {
31
+ workflow: string
32
+ workflowRevision: string
33
+ input: JsonValue
34
+ outcomes: { readonly [name: string]: JsonValue }
35
+ }
36
+
37
+ export interface RunStatus {
38
+ runId: RunId
39
+ workflow: string
40
+ workflowRevision: string
41
+
42
+ bindingDigest: string
43
+ step: string
44
+ state: string
45
+ outcome?: string | null
46
+ output?: JsonValue | null
47
+ failureCode?: string | null
48
+ /** Where a refused call input left its operation contract, as an RFC 6901 pointer that names no value. */
49
+ failurePath?: string | null
50
+ admittedAt: Instant
51
+ deadlineAt: Instant
52
+ nextDueAt?: Instant | null
53
+ uncertain: boolean
54
+ restoreReviewRequired: boolean
55
+ cancelRequested: boolean
56
+ authoredCancelRequested: boolean
57
+ }
58
+
59
+ export interface StepStatus {
60
+ step: string
61
+ state: string
62
+ generation: SafeInteger
63
+ attempt: SafeInteger
64
+ nextDueAt?: Instant | null
65
+ leaseExpiresAt?: Instant | null
66
+ commandPrepared: boolean
67
+ uncertain: boolean
68
+ receiptExpired: boolean
69
+ failureCode?: string | null
70
+ /** Where a refused call input left its operation contract, as an RFC 6901 pointer that names no value. */
71
+ failurePath?: string | null
72
+ /** What a person needs to clear a hold: for `in-force-ambiguous`, the two records in force and the date. */
73
+ holdDetail?: HoldDetail
74
+ }
75
+
76
+ /** The records and date behind a held step. */
77
+ export interface HoldDetail {
78
+ date: string
79
+ recordIdentifiers: string[]
80
+ }
81
+
82
+ export type RetryBlockReason =
83
+ | 'not-recoverable'
84
+ | 'deadline-reached'
85
+ | 'receipt-expired'
86
+ | 'binding-changed'
87
+ | 'other-binding-live'
88
+ | 'snapshot-incompatible'
89
+ | 'cancelled'
90
+ | 'restore-hold'
91
+ | 'restore-review-required'
92
+ | 'payload-erased'
93
+ | 'evaluation-uncertain'
94
+
95
+ /** Coordinator-authored operation identifier. */
96
+ export type OperationId = string
97
+ export type OperationEffect = 'read' | 'mutation' | 'evaluation'
98
+ export type OperationKeyRequirement = 'none' | 'required'
99
+ export type OperationRecovery = 'read-again' | 'same-command-and-receipt' | 'same-command' | 'hold-after-dispatch'
100
+
101
+ /** Pinned public contract metadata. It does not establish current authority. */
102
+ export interface OperationIdentity {
103
+ id: OperationId
104
+ version: SafeInteger
105
+ product: string
106
+ effect: OperationEffect
107
+ keyRequirement: OperationKeyRequirement
108
+ requiresPreparation: boolean
109
+ recovery: OperationRecovery
110
+ readReceipt: boolean
111
+ }
112
+
113
+ export interface RecoveryStatus {
114
+ retryAllowed: boolean
115
+ reason?: RetryBlockReason | null
116
+ operation?: OperationIdentity
117
+ }
118
+
119
+ export type EffectState = 'accepted' | 'unknown'
120
+ export interface EffectStatus {
121
+ step: string
122
+ operation: OperationIdentity
123
+ operationRevision: string
124
+ state: EffectState
125
+ }
126
+ /**
127
+ * The latest answered read of a followed BReg Proposal. It carries no
128
+ * Proposal input and names no person. `stateSince` is when Coordinator first
129
+ * saw the current state and turn, not when BReg entered it.
130
+ */
131
+ export interface LastObservation {
132
+ state: string
133
+ turn?: string
134
+ submissionVersion: SafeInteger
135
+ handoffRefusal?: string
136
+ observedAt: Instant
137
+ stateSince: Instant
138
+ }
139
+ export interface WaitStatus {
140
+ step: string
141
+ acceptedStep: string
142
+ completion: string
143
+ completionRevision: string
144
+ timeoutAt: Instant
145
+ nextObservationAt: Instant | null
146
+ notBefore: Instant
147
+ minimumIntervalSeconds: SafeInteger
148
+ observations: SafeInteger
149
+ observationLimit: SafeInteger
150
+ /** What the latest answered read of a followed BReg Proposal showed. */
151
+ lastObservation?: LastObservation
152
+ /** The operator's "Open the request" link, when the deployment configures one. */
153
+ requestLink?: string
154
+ }
155
+
156
+ export interface RunInspection {
157
+ run: RunStatus
158
+ steps: ReadonlyArray<StepStatus>
159
+ effects: ReadonlyArray<EffectStatus>
160
+ waits: ReadonlyArray<WaitStatus>
161
+ recovery: RecoveryStatus
162
+ }
163
+
164
+ export type RunListState =
165
+ | 'running'
166
+ | 'finished'
167
+ | 'failed'
168
+ | 'cancelled'
169
+ | 'cancelled-after-effect'
170
+ | 'expired'
171
+ | 'attention'
172
+ | 'cancel-requested'
173
+
174
+ /** Whose turn a followed BReg Proposal showed at its last answered read. */
175
+ export type ProposalTurn = 'party' | 'official' | 'nobody'
176
+
177
+ /** One stable page of runs the caller may read, newest admission first. */
178
+ export interface RunList { runs: ReadonlyArray<RunStatus>; nextCursor?: string }
179
+
180
+ /** The runtime accepted a same-command retry; the worker has not run it yet. */
181
+ export interface RetryScheduled { runId: RunId; status: 'retry-scheduled' }
182
+
183
+ export interface CoordinatorOutcome<T> { kind: 'complete'; value: T }
184
+ export type CoordinatorProtocolFailure = 'header-bounds' | 'media-type' | 'body' | 'problem' | 'status' | 'protocol'
185
+
186
+ export class CoordinatorClientError extends Error {
187
+ readonly kind: 'configuration' | 'invalid-request' | 'transport' | 'problem' | 'protocol'
188
+ /**
189
+ * Whether the call may have taken effect although this error was raised:
190
+ * a timeout or broken exchange after sending, an unusable answer, or a
191
+ * 5xx. When true for `start`, recover by sending the same workflow, revision, and input
192
+ * again under the same idempotency key; a new key could admit a second
193
+ * run. When true for `retrySame` or `cancel`, which take no key and are
194
+ * never resent, read the run before asking again. False for a
195
+ * configuration or request defect, a connection never established, and
196
+ * every 4xx refusal.
197
+ */
198
+ readonly outcomeUnknown: boolean
199
+ /**
200
+ * The `family.reason` code of the RFC 9457 problem document the service
201
+ * answered, such as `run.not-visible`, present only when `kind` is
202
+ * `'problem'`. The service's title and detail are never copied.
203
+ */
204
+ readonly code?: string
205
+ readonly status?: SafeInteger
206
+ readonly transportKind?: string
207
+ readonly protocolFailure?: CoordinatorProtocolFailure
208
+ }
209
+
210
+ export class CoordinatorClient {
211
+ constructor(config: CoordinatorClientConfig)
212
+ /**
213
+ * Admit `{workflow, workflowRevision, input}` under the caller's key. Fresh
214
+ * starts must match the active revision. Recover unknown admissions with the
215
+ * original revision even after activation changes. An unknown outcome is resent with
216
+ * the same key and body at most `maximumMutationRetries` times; a 4xx is never
217
+ * resent. The key is scoped to the caller and the workflow, so the same key
218
+ * under two workflows starts two runs, and an allowed workflow the deployment does
219
+ * not serve is refused with 404 `workflow.not-served`, a known outcome never resent.
220
+ */
221
+ start(token: string, idempotencyKey: string, request: StartRunRequest): Promise<CoordinatorOutcome<RunStatus>>
222
+ /** Discover the active typed contract under current start authority; starts no run. */
223
+ workflow(token: string, workflow: string): Promise<CoordinatorOutcome<WorkflowContract>>
224
+ status(token: string, runId: RunId): Promise<CoordinatorOutcome<RunStatus>>
225
+ inspect(token: string, runId: RunId): Promise<CoordinatorOutcome<RunInspection>>
226
+ /** Read the original operation's receipt and update recovery state. Never resubmits the operation. */
227
+ reconcile(token: string, runId: RunId, reason: string): Promise<CoordinatorOutcome<RunInspection>>
228
+ /**
229
+ * Read one stable page of caller-visible runs. Pass `nextCursor` unchanged
230
+ * with the same caller, `state`, `attention`, `proposal`, and `turn`
231
+ * values. `attention: true` selects the effective states `attention` and
232
+ * `failed`. `proposal` selects runs waiting on that BReg Proposal; `turn`
233
+ * selects runs whose Proposal wait last showed that turn.
234
+ */
235
+ list(token: string, limit: SafeInteger, cursor?: string | null, state?: RunListState | null, attention?: boolean | null, proposal?: string | null, turn?: ProposalTurn | null): Promise<CoordinatorOutcome<RunList>>
236
+ /**
237
+ * Schedule the run's saved command again, unchanged, when its inspection
238
+ * allows a retry. Takes no idempotency key, so it is sent exactly once. `reason` is
239
+ * 1 to 256 bytes without control characters, checked before sending.
240
+ */
241
+ retrySame(token: string, runId: RunId, reason: string): Promise<CoordinatorOutcome<RetryScheduled>>
242
+ /**
243
+ * Stop further progression. Never undoes a product effect. Takes no
244
+ * idempotency key, so it is sent exactly once. `reason` is 1 to 256 bytes
245
+ * without control characters, checked before sending.
246
+ */
247
+ cancel(token: string, runId: RunId, reason: string): Promise<CoordinatorOutcome<RunStatus>>
248
+ }