@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 +30 -7
- package/breg/client.d.ts +120 -10
- package/breg/client.js +53 -35
- package/breg/index.d.ts +64 -2
- package/casework/client.d.ts +84 -30
- package/casework/client.js +22 -17
- package/casework/index.d.ts +7 -0
- package/discovery/client.d.ts +9 -52
- package/discovery/client.js +1 -21
- package/discovery/index.d.ts +0 -4
- package/evidence/client.d.ts +1 -1
- package/evidence/index.d.ts +3 -6
- package/index.d.ts +2 -2
- package/index.js +1 -1
- package/messaging/client.d.ts +23 -4
- package/messaging/client.js +32 -21
- package/messaging/index.d.ts +1 -10
- package/native.js +2 -2
- package/package.json +9 -9
- package/scheduling/client.d.ts +226 -0
- package/scheduling/client.js +141 -0
- package/scheduling/index.d.ts +27 -0
- package/scheduling/index.js +3 -0
- package/relay/client.d.ts +0 -460
- package/relay/client.js +0 -172
- package/relay/index.d.ts +0 -59
- package/relay/index.js +0 -3
package/discovery/client.js
CHANGED
|
@@ -55,7 +55,7 @@ function inputError(kind) {
|
|
|
55
55
|
|
|
56
56
|
function localAcceptanceError() {
|
|
57
57
|
return new DiscoveryClientError({
|
|
58
|
-
kind: '
|
|
58
|
+
kind: 'local-acceptance-refused',
|
|
59
59
|
message: 'the relying application refused the advertised service',
|
|
60
60
|
});
|
|
61
61
|
}
|
|
@@ -222,14 +222,6 @@ class DiscoveryClient {
|
|
|
222
222
|
}
|
|
223
223
|
}
|
|
224
224
|
|
|
225
|
-
async searchRelayServices(query) {
|
|
226
|
-
try {
|
|
227
|
-
return await this.#inner.searchRelayServices(requestValue(query));
|
|
228
|
-
} catch (error) {
|
|
229
|
-
throw normalize(error, 'query');
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
|
|
233
225
|
selectExact(response, request) {
|
|
234
226
|
try {
|
|
235
227
|
return this.#inner.selectExact(responseValue(response), requestValue(request));
|
|
@@ -246,9 +238,6 @@ class DiscoveryClient {
|
|
|
246
238
|
return selectEvidenceService(response, request);
|
|
247
239
|
}
|
|
248
240
|
|
|
249
|
-
selectRelayService(response, request) {
|
|
250
|
-
return selectRelayService(response, request);
|
|
251
|
-
}
|
|
252
241
|
}
|
|
253
242
|
|
|
254
243
|
function selectExact(response, request) {
|
|
@@ -278,14 +267,6 @@ function selectEvidenceService(response, request) {
|
|
|
278
267
|
}
|
|
279
268
|
}
|
|
280
269
|
|
|
281
|
-
function selectRelayService(response, request) {
|
|
282
|
-
try {
|
|
283
|
-
return native.selectRelayService(responseValue(response), requestValue(request));
|
|
284
|
-
} catch (error) {
|
|
285
|
-
throw normalize(error, 'query');
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
|
|
289
270
|
function validateSelectionStructure(selection) {
|
|
290
271
|
try {
|
|
291
272
|
return native.validateSelectionStructure(requestValue(selection));
|
|
@@ -323,7 +304,6 @@ module.exports = {
|
|
|
323
304
|
selectEvidenceAlternative,
|
|
324
305
|
selectEvidenceService,
|
|
325
306
|
selectExact,
|
|
326
|
-
selectRelayService,
|
|
327
307
|
validateSelection,
|
|
328
308
|
validateSelectionStructure,
|
|
329
309
|
};
|
package/discovery/index.d.ts
CHANGED
|
@@ -6,11 +6,9 @@ export declare class DiscoveryClient {
|
|
|
6
6
|
resolveEvidenceTypes(request: any): Promise<any>
|
|
7
7
|
searchServices(filters: any): Promise<any>
|
|
8
8
|
searchEvidenceServices(query: any): Promise<any>
|
|
9
|
-
searchRelayServices(query: any): Promise<any>
|
|
10
9
|
selectExact(response: any, request: any): any
|
|
11
10
|
selectEvidenceAlternative(response: any, evidenceTypeListId?: string | undefined | null): any
|
|
12
11
|
selectEvidenceService(response: any, request: any): any
|
|
13
|
-
selectRelayService(response: any, request: any): any
|
|
14
12
|
}
|
|
15
13
|
|
|
16
14
|
export interface DiscoveryClientOptions {
|
|
@@ -29,8 +27,6 @@ export declare function selectEvidenceService(response: any, request: any): any
|
|
|
29
27
|
|
|
30
28
|
export declare function selectExact(response: any, request: any): any
|
|
31
29
|
|
|
32
|
-
export declare function selectRelayService(response: any, request: any): any
|
|
33
|
-
|
|
34
30
|
export declare function validateSelection(selection: any): any
|
|
35
31
|
|
|
36
32
|
export declare function validateSelectionStructure(selection: any): any
|
package/evidence/client.d.ts
CHANGED
|
@@ -351,7 +351,7 @@ export interface EvidenceRequestBatchSpec {
|
|
|
351
351
|
* is `protocol`
|
|
352
352
|
* - `code`: `denied`, `protocol` (optional), `verification`, and any `token`
|
|
353
353
|
* failure whose `tokenKind` is `refused`
|
|
354
|
-
* - `traceId`: `denied`, `
|
|
354
|
+
* - `traceId`: `denied`, `not-available`, `protocol` (all optional)
|
|
355
355
|
* - `retryAfterSeconds`: `denied`, `protocol` (both optional)
|
|
356
356
|
* - `transportKind`: `transport`, and any `token` failure whose `tokenKind`
|
|
357
357
|
* is `transport`
|
package/evidence/index.d.ts
CHANGED
|
@@ -154,11 +154,8 @@ export declare class EvidenceClient {
|
|
|
154
154
|
export declare class PreparedEvidenceRequest {
|
|
155
155
|
/** The nonce this request carries. Retain it with the transaction record. */
|
|
156
156
|
get requestNonce(): string
|
|
157
|
-
/**
|
|
158
|
-
|
|
159
|
-
* it.
|
|
160
|
-
*/
|
|
161
|
-
get policyDocument(): any
|
|
157
|
+
/** The complete enveloped policy, with the subject set as `prepare` left it. */
|
|
158
|
+
get policyDocument(): { apiVersion: 'id.registrystack.org/formats/evidence/verification-policy/v1'; kind: 'EvidenceVerificationPolicy'; [field: string]: unknown }
|
|
162
159
|
/**
|
|
163
160
|
* `"acceptFirstUse"` or `{ pinned: [{ role, binding }, ...] }`, exactly as
|
|
164
161
|
* this request was prepared.
|
|
@@ -178,7 +175,7 @@ export declare class PreparedEvidenceRequestBatch {
|
|
|
178
175
|
/** Independently generated item nonces in request order. */
|
|
179
176
|
get requestNonces(): Array<string>
|
|
180
177
|
/** Independently closed policy documents in request order. */
|
|
181
|
-
get policyDocuments(): Array<
|
|
178
|
+
get policyDocuments(): Array<{ apiVersion: 'id.registrystack.org/formats/evidence/verification-policy/v1'; kind: 'EvidenceVerificationPolicy'; [field: string]: unknown }>
|
|
182
179
|
/** Subject-verification stances in request order. */
|
|
183
180
|
get subjectExpectations(): Array<any>
|
|
184
181
|
/** Number of positional requests in this batch. */
|
package/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as discovery from './discovery/client'
|
|
2
2
|
import * as evidence from './evidence/client'
|
|
3
|
-
import * as relay from './relay/client'
|
|
4
3
|
import * as breg from './breg/client'
|
|
5
4
|
import * as casework from './casework/client'
|
|
6
5
|
import * as messaging from './messaging/client'
|
|
6
|
+
import * as scheduling from './scheduling/client'
|
|
7
7
|
|
|
8
|
-
export { discovery, evidence,
|
|
8
|
+
export { discovery, evidence, breg, casework, messaging, scheduling }
|
package/index.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// consumer imports, and `require()` sees the same six properties either way.
|
|
6
6
|
exports.discovery = require('./discovery/client');
|
|
7
7
|
exports.evidence = require('./evidence/client');
|
|
8
|
-
exports.relay = require('./relay/client');
|
|
9
8
|
exports.breg = require('./breg/client');
|
|
10
9
|
exports.casework = require('./casework/client');
|
|
11
10
|
exports.messaging = require('./messaging/client');
|
|
11
|
+
exports.scheduling = require('./scheduling/client');
|
package/messaging/client.d.ts
CHANGED
|
@@ -14,6 +14,13 @@ export interface MessagingClientConfig {
|
|
|
14
14
|
maxResponseBytes?: SafeInteger | null
|
|
15
15
|
userAgent?: string | null
|
|
16
16
|
trustedRootCertificates?: string | null
|
|
17
|
+
/**
|
|
18
|
+
* How many times a submission whose outcome is unknown is resent,
|
|
19
|
+
* identically and under the same idempotency key, before its error is
|
|
20
|
+
* returned: a whole number from 0 to 2, default 2; 0 sends it once. Any
|
|
21
|
+
* other value is a `configuration` error.
|
|
22
|
+
*/
|
|
23
|
+
maxMutationRetries?: SafeInteger | null
|
|
17
24
|
}
|
|
18
25
|
|
|
19
26
|
export type Channel = 'email' | 'sms'
|
|
@@ -113,10 +120,21 @@ export type MessagingProblemCode =
|
|
|
113
120
|
| 'template.locale-unavailable'
|
|
114
121
|
| 'template.not-found'
|
|
115
122
|
| 'template.render-refused'
|
|
116
|
-
export type MessagingProtocolFailure = '
|
|
123
|
+
export type MessagingProtocolFailure = 'header-bounds' | 'trace-context' | 'media-type' | 'body' | 'problem' | 'status' | 'protocol'
|
|
117
124
|
|
|
118
125
|
export class MessagingClientError extends Error {
|
|
119
|
-
readonly kind: 'configuration' | '
|
|
126
|
+
readonly kind: 'configuration' | 'invalid-request' | 'transport' | 'problem' | 'protocol'
|
|
127
|
+
/**
|
|
128
|
+
* Whether the request may have taken effect although this error was
|
|
129
|
+
* raised: a timeout or broken exchange after sending, an unusable answer,
|
|
130
|
+
* or a 5xx. When true, recover a keyed request by sending it again under
|
|
131
|
+
* the same idempotency key; a new key could apply it twice. False for a
|
|
132
|
+
* configuration or request defect, a connection never established, and
|
|
133
|
+
* every 4xx refusal. It is false for `410 idempotency.expired` too, but
|
|
134
|
+
* there an earlier submission under the key was accepted and its message
|
|
135
|
+
* may have been sent: reconcile that submission before choosing a new key.
|
|
136
|
+
*/
|
|
137
|
+
readonly outcomeUnknown: boolean
|
|
120
138
|
readonly code?: MessagingProblemCode
|
|
121
139
|
readonly title?: string
|
|
122
140
|
readonly detail?: string
|
|
@@ -124,8 +142,9 @@ export class MessagingClientError extends Error {
|
|
|
124
142
|
readonly traceId?: string
|
|
125
143
|
/**
|
|
126
144
|
* Whole seconds a 429 limit refusal asked the caller to wait, from
|
|
127
|
-
* `Retry-After`, at most one day. Absent on every other failure
|
|
128
|
-
* client never waits or retries
|
|
145
|
+
* `Retry-After`, at most one day. Absent on every other failure. The
|
|
146
|
+
* client never waits on a 429 or retries it; the wait is the caller's to
|
|
147
|
+
* honor.
|
|
129
148
|
*/
|
|
130
149
|
readonly retryAfterSeconds?: SafeInteger
|
|
131
150
|
readonly transportKind?: string
|
package/messaging/client.js
CHANGED
|
@@ -12,12 +12,19 @@ class MessagingClientError extends Error {
|
|
|
12
12
|
super(envelope.message);
|
|
13
13
|
this.name = 'MessagingClientError';
|
|
14
14
|
this.kind = envelope.kind;
|
|
15
|
+
this.outcomeUnknown = envelope.outcomeUnknown === true;
|
|
15
16
|
for (const field of ['code', 'title', 'detail', 'status', 'traceId', 'retryAfterSeconds', 'transportKind', 'protocolFailure']) {
|
|
16
17
|
if (envelope[field] !== undefined && envelope[field] !== null) this[field] = envelope[field];
|
|
17
18
|
}
|
|
18
19
|
}
|
|
19
20
|
}
|
|
20
21
|
|
|
22
|
+
const FALLBACK_MESSAGES = {
|
|
23
|
+
configuration: 'Messaging client configuration is invalid',
|
|
24
|
+
'invalid-request': 'Messaging client arguments are invalid',
|
|
25
|
+
protocol: 'Registry Messaging client failed',
|
|
26
|
+
};
|
|
27
|
+
|
|
21
28
|
function normalized(error, fallbackKind) {
|
|
22
29
|
if (error instanceof MessagingClientError) return error;
|
|
23
30
|
if (error instanceof Error && typeof error.message === 'string') {
|
|
@@ -31,49 +38,51 @@ function normalized(error, fallbackKind) {
|
|
|
31
38
|
if (fallbackKind) {
|
|
32
39
|
return new MessagingClientError({
|
|
33
40
|
kind: fallbackKind,
|
|
34
|
-
message: fallbackKind
|
|
35
|
-
|
|
36
|
-
|
|
41
|
+
message: FALLBACK_MESSAGES[fallbackKind],
|
|
42
|
+
// A rejection after the native client took the call may follow an
|
|
43
|
+
// exchange, so it leaves the outcome unknown as a native protocol
|
|
44
|
+
// failure does.
|
|
45
|
+
outcomeUnknown: fallbackKind === 'protocol',
|
|
37
46
|
});
|
|
38
47
|
}
|
|
39
48
|
return error;
|
|
40
49
|
}
|
|
41
50
|
|
|
42
|
-
function cloneJson(value, budget, depth) {
|
|
43
|
-
if (depth > MAX_JSON_DEPTH || ++budget.nodes > MAX_JSON_NODES) throw normalized({},
|
|
51
|
+
function cloneJson(value, budget, depth, kind) {
|
|
52
|
+
if (depth > MAX_JSON_DEPTH || ++budget.nodes > MAX_JSON_NODES) throw normalized({}, kind);
|
|
44
53
|
if (value === null || typeof value === 'boolean') return value;
|
|
45
54
|
if (typeof value === 'string') {
|
|
46
55
|
budget.bytes += Buffer.byteLength(value, 'utf8');
|
|
47
|
-
if (budget.bytes > MAX_JSON_STRING_BYTES) throw normalized({},
|
|
56
|
+
if (budget.bytes > MAX_JSON_STRING_BYTES) throw normalized({}, kind);
|
|
48
57
|
return value;
|
|
49
58
|
}
|
|
50
59
|
if (typeof value === 'number') {
|
|
51
60
|
if (!Number.isFinite(value) || (Number.isInteger(value) && !Number.isSafeInteger(value))) {
|
|
52
|
-
throw normalized({},
|
|
61
|
+
throw normalized({}, kind);
|
|
53
62
|
}
|
|
54
63
|
return value;
|
|
55
64
|
}
|
|
56
65
|
if (value === undefined || typeof value !== 'object' || isProxy(value)) {
|
|
57
|
-
throw normalized({},
|
|
66
|
+
throw normalized({}, kind);
|
|
58
67
|
}
|
|
59
68
|
const array = Array.isArray(value);
|
|
60
69
|
const prototype = Object.getPrototypeOf(value);
|
|
61
70
|
if (array ? prototype !== Array.prototype : prototype !== Object.prototype && prototype !== null) {
|
|
62
|
-
throw normalized({},
|
|
71
|
+
throw normalized({}, kind);
|
|
63
72
|
}
|
|
64
|
-
if (budget.active.has(value)) throw normalized({},
|
|
73
|
+
if (budget.active.has(value)) throw normalized({}, kind);
|
|
65
74
|
budget.active.add(value);
|
|
66
75
|
try {
|
|
67
|
-
if (array) return value.map((member) => cloneJson(member, budget, depth + 1));
|
|
76
|
+
if (array) return value.map((member) => cloneJson(member, budget, depth + 1, kind));
|
|
68
77
|
const result = Object.create(null);
|
|
69
78
|
for (const key of Reflect.ownKeys(value)) {
|
|
70
|
-
if (typeof key !== 'string') throw normalized({},
|
|
79
|
+
if (typeof key !== 'string') throw normalized({}, kind);
|
|
71
80
|
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
72
|
-
if (!descriptor || !Object.hasOwn(descriptor, 'value')) throw normalized({},
|
|
81
|
+
if (!descriptor || !Object.hasOwn(descriptor, 'value')) throw normalized({}, kind);
|
|
73
82
|
if (descriptor.enumerable) {
|
|
74
83
|
budget.bytes += Buffer.byteLength(key, 'utf8');
|
|
75
|
-
if (budget.bytes > MAX_JSON_STRING_BYTES) throw normalized({},
|
|
76
|
-
result[key] = cloneJson(descriptor.value, budget, depth + 1);
|
|
84
|
+
if (budget.bytes > MAX_JSON_STRING_BYTES) throw normalized({}, kind);
|
|
85
|
+
result[key] = cloneJson(descriptor.value, budget, depth + 1, kind);
|
|
77
86
|
}
|
|
78
87
|
}
|
|
79
88
|
return result;
|
|
@@ -82,8 +91,10 @@ function cloneJson(value, budget, depth) {
|
|
|
82
91
|
}
|
|
83
92
|
}
|
|
84
93
|
|
|
85
|
-
|
|
86
|
-
|
|
94
|
+
// A refusal is reported as `kind`: `configuration` for the constructor's
|
|
95
|
+
// settings, `invalid-request` for a method's arguments.
|
|
96
|
+
function sanitize(value, kind) {
|
|
97
|
+
return cloneJson(value, { nodes: 0, bytes: 0, active: new WeakSet() }, 0, kind);
|
|
87
98
|
}
|
|
88
99
|
|
|
89
100
|
const NativeMessagingClient = native.MessagingClient;
|
|
@@ -91,7 +102,7 @@ const NativeMessagingClient = native.MessagingClient;
|
|
|
91
102
|
class MessagingClient {
|
|
92
103
|
constructor(config) {
|
|
93
104
|
try {
|
|
94
|
-
this.native = new NativeMessagingClient(sanitize(config));
|
|
105
|
+
this.native = new NativeMessagingClient(sanitize(config, 'configuration'));
|
|
95
106
|
} catch (error) {
|
|
96
107
|
throw normalized(error, 'configuration');
|
|
97
108
|
}
|
|
@@ -109,11 +120,11 @@ for (const [method, jsonIndexes] of [
|
|
|
109
120
|
MessagingClient.prototype[method] = function (...args) {
|
|
110
121
|
try {
|
|
111
122
|
for (const index of jsonIndexes) {
|
|
112
|
-
if (args[index] !== undefined && args[index] !== null) args[index] = sanitize(args[index]);
|
|
123
|
+
if (args[index] !== undefined && args[index] !== null) args[index] = sanitize(args[index], 'invalid-request');
|
|
113
124
|
}
|
|
114
|
-
return this.native[method](...args).catch((error) => { throw normalized(error); });
|
|
125
|
+
return this.native[method](...args).catch((error) => { throw normalized(error, 'protocol'); });
|
|
115
126
|
} catch (error) {
|
|
116
|
-
throw normalized(error, '
|
|
127
|
+
throw normalized(error, 'invalid-request');
|
|
117
128
|
}
|
|
118
129
|
};
|
|
119
130
|
}
|
package/messaging/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/* eslint-disable */
|
|
3
3
|
|
|
4
4
|
export declare class MessagingClient {
|
|
5
|
-
constructor(config:
|
|
5
|
+
constructor(config: any)
|
|
6
6
|
health(): Promise<MessagingOutcome>
|
|
7
7
|
ready(): Promise<MessagingOutcome>
|
|
8
8
|
submit(token: string, idempotencyKey: string, request: any): Promise<MessagingOutcome>
|
|
@@ -11,15 +11,6 @@ export declare class MessagingClient {
|
|
|
11
11
|
preview(token: string, templateId: string, version: string, request: any): Promise<MessagingOutcome>
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
export interface MessagingClientConfig {
|
|
15
|
-
baseUrl: string
|
|
16
|
-
requestTimeoutMilliseconds?: number
|
|
17
|
-
connectTimeoutMilliseconds?: number
|
|
18
|
-
maxResponseBytes?: number
|
|
19
|
-
userAgent?: string
|
|
20
|
-
trustedRootCertificates?: string
|
|
21
|
-
}
|
|
22
|
-
|
|
23
14
|
export interface MessagingOutcome {
|
|
24
15
|
kind: string
|
|
25
16
|
value: any
|
package/native.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const PACKAGE_VERSION = '0.
|
|
4
|
-
const PRODUCTS = new Set(['discovery', 'evidence', '
|
|
3
|
+
const PACKAGE_VERSION = '0.40.0';
|
|
4
|
+
const PRODUCTS = new Set(['discovery', 'evidence', 'breg', 'casework', 'messaging', 'scheduling']);
|
|
5
5
|
|
|
6
6
|
function target() {
|
|
7
7
|
if (process.platform === 'darwin' && process.arch === 'arm64') return 'darwin-arm64';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@registrystack/client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.40.0",
|
|
4
4
|
"description": "Unified Node.js client for Registry Stack products.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://docs.registrystack.org/reference/client-api/",
|
|
@@ -12,10 +12,10 @@
|
|
|
12
12
|
"registrystack",
|
|
13
13
|
"discovery",
|
|
14
14
|
"evidence",
|
|
15
|
-
"relay",
|
|
16
15
|
"breg",
|
|
17
16
|
"casework",
|
|
18
|
-
"messaging"
|
|
17
|
+
"messaging",
|
|
18
|
+
"scheduling"
|
|
19
19
|
],
|
|
20
20
|
"publishConfig": {
|
|
21
21
|
"access": "public",
|
|
@@ -40,10 +40,10 @@
|
|
|
40
40
|
"native.js",
|
|
41
41
|
"discovery",
|
|
42
42
|
"evidence",
|
|
43
|
-
"relay",
|
|
44
43
|
"breg",
|
|
45
44
|
"casework",
|
|
46
|
-
"messaging"
|
|
45
|
+
"messaging",
|
|
46
|
+
"scheduling"
|
|
47
47
|
],
|
|
48
48
|
"engines": {
|
|
49
49
|
"node": ">=22.12.0"
|
|
@@ -55,12 +55,12 @@
|
|
|
55
55
|
"check:types": "tsc --noEmit --strict --skipLibCheck false --types node --moduleResolution node16 --module node16 --target es2022 index.d.ts __test__/facade.test-d.ts"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
|
-
"@types/node": "22.20.
|
|
58
|
+
"@types/node": "22.20.5",
|
|
59
59
|
"typescript": "6.0.3"
|
|
60
60
|
},
|
|
61
61
|
"optionalDependencies": {
|
|
62
|
-
"@registrystack/client-darwin-arm64": "0.
|
|
63
|
-
"@registrystack/client-linux-arm64-gnu": "0.
|
|
64
|
-
"@registrystack/client-linux-x64-gnu": "0.
|
|
62
|
+
"@registrystack/client-darwin-arm64": "0.40.0",
|
|
63
|
+
"@registrystack/client-linux-arm64-gnu": "0.40.0",
|
|
64
|
+
"@registrystack/client-linux-x64-gnu": "0.40.0"
|
|
65
65
|
}
|
|
66
66
|
}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/** An integer for which `Number.isSafeInteger` is true. */
|
|
2
|
+
export type SafeInteger = number
|
|
3
|
+
/**
|
|
4
|
+
* An RFC 3339 instant. Instants the binding sends are parsed and normalized
|
|
5
|
+
* to UTC before any request; instants it answers are UTC.
|
|
6
|
+
*/
|
|
7
|
+
export type Instant = string
|
|
8
|
+
export type JsonScalar = string | number | boolean | null
|
|
9
|
+
export type JsonValue = JsonScalar | ReadonlyArray<JsonValue> | { readonly [key: string]: JsonValue }
|
|
10
|
+
|
|
11
|
+
export interface SchedulingClientConfig {
|
|
12
|
+
baseUrl: string
|
|
13
|
+
requestTimeoutMilliseconds?: SafeInteger | null
|
|
14
|
+
connectTimeoutMilliseconds?: SafeInteger | null
|
|
15
|
+
maxResponseBytes?: SafeInteger | null
|
|
16
|
+
userAgent?: string | null
|
|
17
|
+
trustedRootCertificates?: string | null
|
|
18
|
+
/**
|
|
19
|
+
* How many times a keyed command (hold, appointment create, reschedule,
|
|
20
|
+
* cancel) whose outcome is unknown is resent, identically and under the
|
|
21
|
+
* same idempotency key, before its error is returned: a whole number from 0
|
|
22
|
+
* to 2, default 2; 0 sends it once. Any other value is a `configuration`
|
|
23
|
+
* error.
|
|
24
|
+
*/
|
|
25
|
+
maxMutationRetries?: SafeInteger | null
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** An opaque record link Scheduling retains with a hold or appointment. */
|
|
29
|
+
export interface ExternalReference {
|
|
30
|
+
product: string
|
|
31
|
+
recordType: string
|
|
32
|
+
identifier: string
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface PartyCounts { recipients: SafeInteger; attendees: SafeInteger }
|
|
36
|
+
|
|
37
|
+
/** One admission: the offering, start, and party a hold or booking asks capacity for. */
|
|
38
|
+
export interface AdmissionRequest {
|
|
39
|
+
offering: string
|
|
40
|
+
start: Instant
|
|
41
|
+
party: PartyCounts
|
|
42
|
+
channel?: string | null
|
|
43
|
+
duplicateKey?: string | null
|
|
44
|
+
policyRevision: SafeInteger
|
|
45
|
+
windowRevision?: SafeInteger | null
|
|
46
|
+
capabilities: ReadonlyArray<string>
|
|
47
|
+
prerequisites: ReadonlyArray<string>
|
|
48
|
+
externalReferences?: ReadonlyArray<ExternalReference>
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** Exactly one of `hold` (confirm a held claim) or `admission` (book directly). */
|
|
52
|
+
export type CreateAppointmentRequest =
|
|
53
|
+
| { hold: string; admission?: null }
|
|
54
|
+
| { admission: AdmissionRequest; hold?: null }
|
|
55
|
+
|
|
56
|
+
export interface RescheduleAppointmentRequest { observedRevision: SafeInteger; admission: AdmissionRequest }
|
|
57
|
+
export interface CancelAppointmentRequest { observedRevision: SafeInteger; reason?: string | null }
|
|
58
|
+
|
|
59
|
+
export interface AvailabilityQuery {
|
|
60
|
+
start?: Instant | null
|
|
61
|
+
end?: Instant | null
|
|
62
|
+
cursor?: string | null
|
|
63
|
+
limit?: SafeInteger | null
|
|
64
|
+
}
|
|
65
|
+
export interface PageQuery { cursor?: string | null; limit?: SafeInteger | null }
|
|
66
|
+
|
|
67
|
+
export interface SchedulingServiceDocument { schedulingId: string; policyRevision: SafeInteger; policyDigest: string }
|
|
68
|
+
export interface ServiceDocument { id: string; label: string }
|
|
69
|
+
export type SchedulingMode = 'exact-time' | 'arrival-window'
|
|
70
|
+
export interface ReminderDocument { minutesBefore: SafeInteger }
|
|
71
|
+
export interface WindowDocument { id: string; revision: SafeInteger; start: Instant; end: Instant; units: SafeInteger }
|
|
72
|
+
export interface OfferingDocument {
|
|
73
|
+
id: string
|
|
74
|
+
service: string
|
|
75
|
+
label: string
|
|
76
|
+
mode: SchedulingMode
|
|
77
|
+
location: string
|
|
78
|
+
leadTimeMinutes: SafeInteger
|
|
79
|
+
horizonDays: SafeInteger
|
|
80
|
+
cancellationCutoffMinutes: SafeInteger
|
|
81
|
+
durationMinutes: SafeInteger | null
|
|
82
|
+
bufferBeforeMinutes: SafeInteger | null
|
|
83
|
+
bufferAfterMinutes: SafeInteger | null
|
|
84
|
+
startIncrementMinutes: SafeInteger | null
|
|
85
|
+
maxRecipients: SafeInteger | null
|
|
86
|
+
window: WindowDocument | null
|
|
87
|
+
reminders: ReadonlyArray<ReminderDocument>
|
|
88
|
+
requiresCapabilities: ReadonlyArray<string>
|
|
89
|
+
prerequisites: ReadonlyArray<string>
|
|
90
|
+
}
|
|
91
|
+
export interface ResourceDocument { resourceId: string; pool: string; capabilities: ReadonlyArray<string>; available: boolean }
|
|
92
|
+
export interface LocationDocument { locationId: string; timezone: string }
|
|
93
|
+
|
|
94
|
+
/** Exact-time offerings answer grid slots; arrival-window offerings answer windows. */
|
|
95
|
+
export type AvailabilityEntry =
|
|
96
|
+
| { kind: 'slot'; start: Instant; end: Instant; free: SafeInteger }
|
|
97
|
+
| { kind: 'window'; window: string; start: Instant; end: Instant; remaining: SafeInteger; channelRemaining: SafeInteger | null }
|
|
98
|
+
|
|
99
|
+
export interface PageDocument<T> { items: ReadonlyArray<T>; nextCursor: string | null }
|
|
100
|
+
|
|
101
|
+
export interface HoldDocument {
|
|
102
|
+
holdId: string
|
|
103
|
+
offering: string
|
|
104
|
+
start: Instant
|
|
105
|
+
end: Instant
|
|
106
|
+
resource: string | null
|
|
107
|
+
units: SafeInteger
|
|
108
|
+
expiresAt: Instant
|
|
109
|
+
policyRevision: SafeInteger
|
|
110
|
+
externalReferences: ReadonlyArray<ExternalReference>
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export type AppointmentState = 'confirmed' | 'cancelled'
|
|
114
|
+
export interface AppointmentDocument {
|
|
115
|
+
appointmentId: string
|
|
116
|
+
offering: string
|
|
117
|
+
start: Instant
|
|
118
|
+
end: Instant
|
|
119
|
+
resource: string | null
|
|
120
|
+
units: SafeInteger
|
|
121
|
+
channel: string | null
|
|
122
|
+
revision: SafeInteger
|
|
123
|
+
state: AppointmentState
|
|
124
|
+
policyRevision: SafeInteger
|
|
125
|
+
createdAt: Instant
|
|
126
|
+
cancelledAt: Instant | null
|
|
127
|
+
externalReferences: ReadonlyArray<ExternalReference>
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export interface AppointmentHistoryEntryDocument {
|
|
131
|
+
eventId: string
|
|
132
|
+
kind: string
|
|
133
|
+
revision: SafeInteger
|
|
134
|
+
occurredAt: Instant
|
|
135
|
+
actor: string | null
|
|
136
|
+
detail: JsonValue
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export interface ExplainDocument {
|
|
140
|
+
offering: string
|
|
141
|
+
start: Instant
|
|
142
|
+
publicCode?: string
|
|
143
|
+
detailedCode?: string
|
|
144
|
+
explanation?: string
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export interface SchedulingOutcome<T> { kind: 'complete'; value: T; traceId: string }
|
|
148
|
+
|
|
149
|
+
/** The closed catalogue: the client answers any other code as a protocol failure. */
|
|
150
|
+
export type SchedulingProblemCode =
|
|
151
|
+
| 'authentication.refused'
|
|
152
|
+
| 'booking.duplicate-active'
|
|
153
|
+
| 'cancellation.cutoff-passed'
|
|
154
|
+
| 'capability.unmatched'
|
|
155
|
+
| 'capacity.exhausted'
|
|
156
|
+
| 'cursor.expired'
|
|
157
|
+
| 'cursor.invalid'
|
|
158
|
+
| 'eligibility.unavailable'
|
|
159
|
+
| 'hold.expired'
|
|
160
|
+
| 'hold.released'
|
|
161
|
+
| 'hook.unavailable'
|
|
162
|
+
| 'horizon.outside'
|
|
163
|
+
| 'idempotency.expired'
|
|
164
|
+
| 'idempotency.key-reused'
|
|
165
|
+
| 'location.closed'
|
|
166
|
+
| 'operation.not-authorized'
|
|
167
|
+
| 'party.capacity-inadequate'
|
|
168
|
+
| 'policy.changed'
|
|
169
|
+
| 'precondition.failed'
|
|
170
|
+
| 'precondition.required'
|
|
171
|
+
| 'prerequisite.missing'
|
|
172
|
+
| 'profile.not-authorized'
|
|
173
|
+
| 'request.body-too-large'
|
|
174
|
+
| 'request.invalid'
|
|
175
|
+
| 'request.method-not-allowed'
|
|
176
|
+
| 'request.not-found'
|
|
177
|
+
| 'request.unprocessable'
|
|
178
|
+
| 'request.unsupported-media-type'
|
|
179
|
+
| 'resource.unavailable'
|
|
180
|
+
| 'revision.mismatch'
|
|
181
|
+
| 'schedule.unpublished'
|
|
182
|
+
| 'service.unavailable'
|
|
183
|
+
export type SchedulingProtocolFailure = 'header-bounds' | 'trace-context' | 'media-type' | 'body' | 'problem' | 'status' | 'protocol'
|
|
184
|
+
|
|
185
|
+
export class SchedulingClientError extends Error {
|
|
186
|
+
readonly kind: 'configuration' | 'invalid-request' | 'transport' | 'problem' | 'protocol'
|
|
187
|
+
/**
|
|
188
|
+
* Whether the request may have taken effect although this error was
|
|
189
|
+
* raised: a timeout or broken exchange after sending, an unusable answer,
|
|
190
|
+
* or a 5xx. When true, recover a keyed request by sending it again under
|
|
191
|
+
* the same idempotency key; a new key could apply it twice. False for a
|
|
192
|
+
* configuration or request defect, a connection never established, and
|
|
193
|
+
* every 4xx refusal. It is false for `410 idempotency.expired` too, but
|
|
194
|
+
* there an earlier attempt under the key was answered and may have
|
|
195
|
+
* committed: read an appointment by its external reference or identifier
|
|
196
|
+
* before choosing a new key. A hold cannot be read and expires on its own,
|
|
197
|
+
* so start a new request.
|
|
198
|
+
*/
|
|
199
|
+
readonly outcomeUnknown: boolean
|
|
200
|
+
readonly code?: SchedulingProblemCode
|
|
201
|
+
readonly title?: string
|
|
202
|
+
readonly detail?: string
|
|
203
|
+
readonly status?: SafeInteger
|
|
204
|
+
readonly traceId?: string
|
|
205
|
+
readonly transportKind?: string
|
|
206
|
+
readonly protocolFailure?: SchedulingProtocolFailure
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export class SchedulingClient {
|
|
210
|
+
constructor(config: SchedulingClientConfig)
|
|
211
|
+
getScheduling(token: string): Promise<SchedulingOutcome<SchedulingServiceDocument>>
|
|
212
|
+
listServices(token: string, cursor?: string | null): Promise<SchedulingOutcome<PageDocument<ServiceDocument>>>
|
|
213
|
+
listOfferings(token: string, cursor?: string | null): Promise<SchedulingOutcome<PageDocument<OfferingDocument>>>
|
|
214
|
+
availability(token: string, offering: string, query?: AvailabilityQuery | null): Promise<SchedulingOutcome<PageDocument<AvailabilityEntry>>>
|
|
215
|
+
explain(token: string, offering: string, start: Instant): Promise<SchedulingOutcome<ExplainDocument>>
|
|
216
|
+
createHold(token: string, idempotencyKey: string, request: AdmissionRequest): Promise<SchedulingOutcome<HoldDocument>>
|
|
217
|
+
releaseHold(token: string, holdId: string): Promise<SchedulingOutcome<null>>
|
|
218
|
+
createAppointment(token: string, idempotencyKey: string, request: CreateAppointmentRequest): Promise<SchedulingOutcome<AppointmentDocument>>
|
|
219
|
+
getAppointment(token: string, appointmentId: string): Promise<SchedulingOutcome<AppointmentDocument>>
|
|
220
|
+
listAppointments(token: string, reference: ExternalReference, page?: PageQuery | null): Promise<SchedulingOutcome<PageDocument<AppointmentDocument>>>
|
|
221
|
+
rescheduleAppointment(token: string, appointmentId: string, idempotencyKey: string, request: RescheduleAppointmentRequest): Promise<SchedulingOutcome<AppointmentDocument>>
|
|
222
|
+
cancelAppointment(token: string, appointmentId: string, idempotencyKey: string, request: CancelAppointmentRequest): Promise<SchedulingOutcome<AppointmentDocument>>
|
|
223
|
+
appointmentHistory(token: string, appointmentId: string, cursor?: string | null): Promise<SchedulingOutcome<PageDocument<AppointmentHistoryEntryDocument>>>
|
|
224
|
+
listResources(token: string, cursor?: string | null): Promise<SchedulingOutcome<PageDocument<ResourceDocument>>>
|
|
225
|
+
listLocations(token: string, cursor?: string | null): Promise<SchedulingOutcome<PageDocument<LocationDocument>>>
|
|
226
|
+
}
|