@registrystack/client 0.0.0 → 0.26.1

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.
@@ -0,0 +1,408 @@
1
+ export type JsonScalar = string | number | boolean | null
2
+ export type JsonValue = JsonScalar | ReadonlyArray<JsonValue> | { readonly [key: string]: JsonValue }
3
+ /** An integer that satisfies `Number.isSafeInteger` and the option's documented bounds. */
4
+ export type SafeInteger = number
5
+
6
+ export interface PrivateJwk {
7
+ readonly kty: string
8
+ readonly kid: string
9
+ readonly alg: string
10
+ readonly [member: string]: JsonValue
11
+ }
12
+
13
+ export interface PrivateKeyJwtConfig {
14
+ tokenEndpoint: string
15
+ clientId: string
16
+ clientKey: PrivateJwk
17
+ audience?: string | null
18
+ assertionLifetimeSeconds?: SafeInteger | null
19
+ refreshMarginSeconds?: SafeInteger | null
20
+ requestTimeoutMilliseconds?: SafeInteger | null
21
+ connectTimeoutMilliseconds?: SafeInteger | null
22
+ userAgent?: string | null
23
+ trustedRootCertificates?: string | null
24
+ }
25
+
26
+ export type RelayAuthorization =
27
+ | { static: string }
28
+ | { privateKeyJwt: PrivateKeyJwtConfig }
29
+
30
+ export interface RelayClientConfig {
31
+ baseUrl: string
32
+ authorization?: RelayAuthorization | null
33
+ requestTimeoutMilliseconds?: SafeInteger | null
34
+ connectTimeoutMilliseconds?: SafeInteger | null
35
+ userAgent?: string | null
36
+ maxResponseBytes?: SafeInteger | null
37
+ trustedRootCertificates?: string | null
38
+ }
39
+
40
+ export type RecordFormat = 'json' | 'json-ld' | 'geojson' | 'json-fg'
41
+
42
+ export interface ResourceListOptions {
43
+ pageSize?: SafeInteger | null
44
+ }
45
+
46
+ export interface ResourceContinuation {
47
+ cursor: string
48
+ }
49
+
50
+ export interface RecordOptions {
51
+ fields?: ReadonlyArray<string> | null
52
+ accessProfile?: string | null
53
+ format?: RecordFormat | null
54
+ }
55
+
56
+ export interface ListOptions extends RecordOptions {
57
+ pageSize?: SafeInteger | null
58
+ filters?: Readonly<Record<string, string>> | null
59
+ }
60
+
61
+ export interface SearchOptions extends RecordOptions {
62
+ pageSize?: SafeInteger | null
63
+ /** `[west, south, east, north]` in WGS84 longitude/latitude degrees. */
64
+ bbox: readonly [number, number, number, number]
65
+ }
66
+
67
+ export type LookupSelector = string | SafeInteger | boolean
68
+ export type LookupSelectors = Readonly<Record<string, LookupSelector>>
69
+
70
+ export interface RecordsRoute {
71
+ kind: 'records'
72
+ resource: string
73
+ }
74
+
75
+ export interface SearchRoute {
76
+ kind: 'search'
77
+ resource: string
78
+ search: string
79
+ }
80
+
81
+ export interface CollectionContinuation<Route extends RecordsRoute | SearchRoute = RecordsRoute | SearchRoute> {
82
+ route: Route
83
+ cursor: string
84
+ format: 'json' | 'json-ld' | 'geojson-rfc7946' | 'json-fg'
85
+ accessProfile?: string
86
+ }
87
+
88
+ export interface SdmxDataRequest {
89
+ agency: string
90
+ resource: string
91
+ /** A three-part `x.y.z` SDMX version. */
92
+ version: string
93
+ key?: string | null
94
+ constraints?: Readonly<Record<string, string>> | null
95
+ offset?: SafeInteger | null
96
+ limit?: SafeInteger | null
97
+ dimensionAtObservation?: string | null
98
+ format?: 'json' | 'csv' | null
99
+ }
100
+
101
+ export interface SdmxStructureRequest {
102
+ kind: 'dataflow' | 'datastructure'
103
+ agency: string
104
+ resource: string
105
+ /** A three-part `x.y.z` SDMX version. */
106
+ version: string
107
+ }
108
+
109
+ export interface ProbeStatus {
110
+ status: string
111
+ }
112
+
113
+ export interface Institution {
114
+ identifier: string
115
+ name: string
116
+ }
117
+
118
+ export interface Product {
119
+ name: string
120
+ version: string
121
+ }
122
+
123
+ export interface ApiBinding {
124
+ name: string
125
+ version: string
126
+ }
127
+
128
+ export interface AlignmentTarget {
129
+ name: string
130
+ version: string
131
+ status: string
132
+ cfrTarget?: string
133
+ }
134
+
135
+ export interface FormatProfileCapability {
136
+ id: string
137
+ uri: string
138
+ crs: string
139
+ conformsTo: ReadonlyArray<string>
140
+ }
141
+
142
+ export interface WireFormatCapability {
143
+ id: string
144
+ mediaType: string
145
+ formatProfiles: ReadonlyArray<FormatProfileCapability>
146
+ }
147
+
148
+ export interface BboxCapability {
149
+ crs: string
150
+ predicate: string
151
+ maximumLongitudeSpanDegrees: number
152
+ maximumLatitudeSpanDegrees: number
153
+ }
154
+
155
+ export interface SpatialQueryCapability {
156
+ bbox: BboxCapability
157
+ }
158
+
159
+ export interface ConsultationCapability {
160
+ family: 'consultation'
161
+ pattern: string
162
+ resourceIdentifier: string
163
+ operationIdentifier: string
164
+ accessProfileIdentifier: string
165
+ isDefault: boolean
166
+ disclosureProfile: string
167
+ schemaReference: string
168
+ semanticModelReference: string
169
+ contextReference: string
170
+ href: string
171
+ wireFormats: ReadonlyArray<WireFormatCapability>
172
+ spatialQuery?: SpatialQueryCapability
173
+ classificationReference?: string
174
+ processingReference?: string
175
+ }
176
+
177
+ export interface SdmxProfile {
178
+ sdmxRestVersion: string
179
+ sdmxDataJsonVersion: string
180
+ sdmxDataCsvVersion: string
181
+ sdmxStructureJsonVersion: string
182
+ }
183
+
184
+ export interface SdmxWireFormat {
185
+ id: string
186
+ mediaType: string
187
+ }
188
+
189
+ export interface SdmxStructureLinks {
190
+ dataflow: string
191
+ datastructure: string
192
+ }
193
+
194
+ export interface AggregateDataCapability {
195
+ family: 'aggregate-data'
196
+ pattern: string
197
+ statisticalDatasetIdentifier: string
198
+ operationIdentifier: string
199
+ profile: SdmxProfile
200
+ wireFormats: ReadonlyArray<SdmxWireFormat>
201
+ href: string
202
+ structureLinks: SdmxStructureLinks
203
+ }
204
+
205
+ export type Capability = ConsultationCapability | AggregateDataCapability
206
+
207
+ export interface ServiceMetadata {
208
+ registryIdentifier: string
209
+ name: string
210
+ authority: Institution
211
+ operator: Institution | null
212
+ authoritativeScope: string
213
+ product: Product
214
+ apiBinding: ApiBinding
215
+ alignmentTargets: ReadonlyArray<AlignmentTarget>
216
+ capabilities: ReadonlyArray<Capability>
217
+ links: { self: string; resources: string; openapi: string }
218
+ }
219
+
220
+ export interface ResourceDocument {
221
+ resourceIdentifier: string
222
+ title: string
223
+ description: string
224
+ semanticClass: string
225
+ enumerationPosture: string
226
+ capabilities: ReadonlyArray<Capability>
227
+ links: { self: string }
228
+ }
229
+
230
+ export interface CursorPageInfo {
231
+ nextCursor: string | null
232
+ }
233
+
234
+ export interface RegistryMetadata {
235
+ registryIdentifier: string
236
+ }
237
+
238
+ export interface ResourceCollection {
239
+ items: ReadonlyArray<ResourceDocument>
240
+ pageInfo: CursorPageInfo
241
+ meta: RegistryMetadata
242
+ }
243
+
244
+ export interface ResourceEnvelope {
245
+ data: ResourceDocument
246
+ meta: RegistryMetadata
247
+ }
248
+
249
+ export interface RegistryRecord {
250
+ registryIdentifier: string
251
+ recordIdentifier: string
252
+ revisionIdentifier: string
253
+ lifecycleState: string
254
+ schemaReference: string
255
+ semanticModelReference: string
256
+ authorityIdentifier: string
257
+ recordedAt: string
258
+ domainData: Readonly<Record<string, JsonValue>>
259
+ '@id'?: string
260
+ '@type'?: string
261
+ }
262
+
263
+ export interface SourceRevision {
264
+ profile: string
265
+ status: string
266
+ value: string | null
267
+ }
268
+
269
+ export interface RecordLinks {
270
+ self: string
271
+ context: string
272
+ schema: string
273
+ semanticModel: string
274
+ }
275
+
276
+ export interface RecordMetadata {
277
+ operationIdentifier: string
278
+ accessProfile: string
279
+ family: string
280
+ pattern: string
281
+ disclosureProfile: string
282
+ contractRevision: string
283
+ sourceRevision: SourceRevision
284
+ selectedFields: ReadonlyArray<string>
285
+ links: RecordLinks
286
+ }
287
+
288
+ export interface RecordEnvelope {
289
+ data: RegistryRecord
290
+ meta: RecordMetadata
291
+ '@context'?: string
292
+ }
293
+
294
+ export interface RecordCollection {
295
+ items: ReadonlyArray<RegistryRecord>
296
+ pageInfo: CursorPageInfo
297
+ meta: RecordMetadata
298
+ '@context'?: string
299
+ }
300
+
301
+ export interface GeoJsonFeature {
302
+ type: string
303
+ id: string
304
+ geometry: JsonValue
305
+ properties: RegistryRecord
306
+ meta?: RecordMetadata
307
+ conformsTo?: ReadonlyArray<string>
308
+ featureType?: string
309
+ coordRefSys?: string
310
+ }
311
+
312
+ export interface GeoJsonFeatureCollection {
313
+ type: string
314
+ features: ReadonlyArray<GeoJsonFeature>
315
+ pageInfo: CursorPageInfo
316
+ meta: RecordMetadata
317
+ conformsTo?: ReadonlyArray<string>
318
+ featureType?: string
319
+ coordRefSys?: string
320
+ }
321
+
322
+ export type RecordResponse = RecordEnvelope | GeoJsonFeature
323
+ export type RecordCollectionResponse = RecordCollection | GeoJsonFeatureCollection
324
+
325
+ export interface CompleteOutcome<T> {
326
+ kind: 'complete'
327
+ value: T
328
+ traceId: string
329
+ etag?: string
330
+ }
331
+
332
+ export interface NotModifiedOutcome {
333
+ kind: 'notModified'
334
+ etag: string
335
+ traceId: string
336
+ }
337
+
338
+ export type Outcome<T> = CompleteOutcome<T> | NotModifiedOutcome
339
+
340
+ export interface ResourcePageCompleteOutcome {
341
+ kind: 'complete'
342
+ value: ResourceCollection
343
+ continuation?: ResourceContinuation
344
+ traceId: string
345
+ etag?: string
346
+ }
347
+
348
+ export type ResourcePageOutcome = ResourcePageCompleteOutcome | NotModifiedOutcome
349
+
350
+ export interface CollectionPageCompleteOutcome {
351
+ kind: 'complete'
352
+ value: RecordCollectionResponse
353
+ continuation?: CollectionContinuation
354
+ traceId: string
355
+ etag?: string
356
+ }
357
+
358
+ export type CollectionPageOutcome = CollectionPageCompleteOutcome | NotModifiedOutcome
359
+
360
+ export interface RawCompleteOutcome {
361
+ kind: 'complete'
362
+ body: Buffer
363
+ mediaType: string
364
+ traceId: string
365
+ etag?: string
366
+ }
367
+
368
+ export type RawOutcome = RawCompleteOutcome | NotModifiedOutcome
369
+
370
+ export interface RelayClientFailure extends Error {
371
+ readonly kind: string
372
+ readonly code?: string
373
+ readonly status?: number
374
+ readonly traceId?: string
375
+ readonly retryAfterSeconds?: number
376
+ readonly transportKind?: string
377
+ readonly tokenKind?: string
378
+ }
379
+
380
+ export declare class RelayClientError extends Error implements RelayClientFailure {
381
+ readonly kind: string
382
+ readonly code?: string
383
+ readonly status?: number
384
+ readonly traceId?: string
385
+ readonly retryAfterSeconds?: number
386
+ readonly transportKind?: string
387
+ readonly tokenKind?: string
388
+ }
389
+
390
+ export declare class RelayClient {
391
+ constructor(config: RelayClientConfig)
392
+ health(): Promise<CompleteOutcome<ProbeStatus>>
393
+ ready(): Promise<CompleteOutcome<ProbeStatus>>
394
+ openapi(etag?: string | null): Promise<RawOutcome>
395
+ serviceMetadata(etag?: string | null): Promise<Outcome<ServiceMetadata>>
396
+ resources(options?: ResourceListOptions | null, etag?: string | null): Promise<ResourcePageOutcome>
397
+ continueResources(continuation: ResourceContinuation, etag?: string | null): Promise<ResourcePageOutcome>
398
+ resource(resource: string, etag?: string | null): Promise<Outcome<ResourceEnvelope>>
399
+ listRecords(resource: string, options?: ListOptions | null, etag?: string | null): Promise<CollectionPageOutcome>
400
+ continueListRecords(continuation: CollectionContinuation<RecordsRoute>, etag?: string | null): Promise<CollectionPageOutcome>
401
+ readRecord(resource: string, recordIdentifier: string, options?: RecordOptions | null, etag?: string | null): Promise<Outcome<RecordResponse>>
402
+ lookup(resource: string, lookup: string, selectors: LookupSelectors, options?: RecordOptions | null, etag?: string | null): Promise<Outcome<RecordResponse>>
403
+ search(resource: string, search: string, options: SearchOptions, etag?: string | null): Promise<CollectionPageOutcome>
404
+ continueSearch(continuation: CollectionContinuation<SearchRoute>, etag?: string | null): Promise<CollectionPageOutcome>
405
+ artifact(artifactIdentifier: string, etag?: string | null): Promise<RawOutcome>
406
+ sdmxData(request: SdmxDataRequest, etag?: string | null): Promise<RawOutcome>
407
+ sdmxStructure(request: SdmxStructureRequest, etag?: string | null): Promise<RawOutcome>
408
+ }
@@ -0,0 +1,172 @@
1
+ 'use strict';
2
+
3
+ const { types: { isProxy } } = require('node:util');
4
+ const native = require('./index');
5
+
6
+ const MAX_JSON_DEPTH = 128;
7
+ const MAX_JSON_NODES = 100_000;
8
+ const MAX_JSON_STRING_BYTES = 4 * 1024 * 1024;
9
+
10
+ class RelayClientError extends Error {
11
+ constructor(envelope) {
12
+ super(envelope.message);
13
+ this.name = 'RelayClientError';
14
+ this.kind = envelope.kind;
15
+ for (const field of ['code', 'status', 'traceId', 'retryAfterSeconds', 'transportKind', 'tokenKind']) {
16
+ if (envelope[field] !== undefined && envelope[field] !== null) this[field] = envelope[field];
17
+ }
18
+ }
19
+ }
20
+
21
+ function normalize(error, fallbackKind) {
22
+ if (error instanceof RelayClientError) return error;
23
+ if (error instanceof Error && typeof error.message === 'string') {
24
+ try {
25
+ const envelope = JSON.parse(error.message);
26
+ if (envelope && typeof envelope === 'object' && typeof envelope.kind === 'string') {
27
+ return new RelayClientError(envelope);
28
+ }
29
+ } catch {
30
+ // napi argument conversion errors are not mapped Rust error envelopes.
31
+ }
32
+ }
33
+ if (fallbackKind) {
34
+ return new RelayClientError({
35
+ kind: fallbackKind,
36
+ message: fallbackKind === 'configuration'
37
+ ? 'Relay client configuration is invalid'
38
+ : 'Relay client arguments are invalid',
39
+ });
40
+ }
41
+ return error;
42
+ }
43
+
44
+ function inputError(kind) {
45
+ return new RelayClientError({
46
+ kind,
47
+ message: kind === 'configuration'
48
+ ? 'Relay client configuration is invalid'
49
+ : 'Relay client arguments are invalid',
50
+ });
51
+ }
52
+
53
+ function chargeString(value, budget, kind) {
54
+ budget.stringBytes += Buffer.byteLength(value, 'utf8');
55
+ if (budget.stringBytes > MAX_JSON_STRING_BYTES) throw inputError(kind);
56
+ }
57
+
58
+ function cloneJson(value, budget, depth, allowUndefined, kind) {
59
+ if (depth > MAX_JSON_DEPTH) throw inputError(kind);
60
+ budget.nodes += 1;
61
+ if (budget.nodes > MAX_JSON_NODES) throw inputError(kind);
62
+
63
+ if (value === undefined) {
64
+ if (allowUndefined) return undefined;
65
+ throw inputError(kind);
66
+ }
67
+ if (value === null || typeof value === 'boolean') return value;
68
+ if (typeof value === 'string') {
69
+ chargeString(value, budget, kind);
70
+ return value;
71
+ }
72
+ if (typeof value === 'number') {
73
+ if (!Number.isFinite(value)) throw inputError(kind);
74
+ return value;
75
+ }
76
+ if (typeof value !== 'object' || isProxy(value)) throw inputError(kind);
77
+
78
+ const prototype = Object.getPrototypeOf(value);
79
+ const array = Array.isArray(value);
80
+ if (array ? prototype !== Array.prototype : prototype !== Object.prototype && prototype !== null) {
81
+ throw inputError(kind);
82
+ }
83
+ if (budget.active.has(value)) throw inputError(kind);
84
+ budget.active.add(value);
85
+
86
+ try {
87
+ const keys = Reflect.ownKeys(value);
88
+ if (keys.some((key) => typeof key === 'symbol')) throw inputError(kind);
89
+
90
+ if (array) {
91
+ if (value.length + budget.nodes > MAX_JSON_NODES) throw inputError(kind);
92
+ const clone = new Array(value.length);
93
+ let elementCount = 0;
94
+ for (const key of keys) {
95
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
96
+ if (!descriptor || !Object.hasOwn(descriptor, 'value')) throw inputError(kind);
97
+ if (key === 'length') continue;
98
+ chargeString(key, budget, kind);
99
+ const index = Number(key);
100
+ if (!descriptor.enumerable || !Number.isInteger(index) || index < 0
101
+ || index >= value.length || String(index) !== key) {
102
+ throw inputError(kind);
103
+ }
104
+ clone[index] = cloneJson(descriptor.value, budget, depth + 1, false, kind);
105
+ elementCount += 1;
106
+ }
107
+ if (elementCount !== value.length) throw inputError(kind);
108
+ return clone;
109
+ }
110
+
111
+ const clone = Object.create(null);
112
+ for (const key of keys) {
113
+ chargeString(key, budget, kind);
114
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
115
+ if (!descriptor || !Object.hasOwn(descriptor, 'value')) throw inputError(kind);
116
+ if (!descriptor.enumerable) continue;
117
+ clone[key] = cloneJson(descriptor.value, budget, depth + 1, false, kind);
118
+ }
119
+ return clone;
120
+ } finally {
121
+ budget.active.delete(value);
122
+ }
123
+ }
124
+
125
+ function cloneArguments(args, kind, requiredJsonArguments = new Set()) {
126
+ const budget = { nodes: 0, stringBytes: 0, active: new WeakSet() };
127
+ return args.map((value, index) => (
128
+ cloneJson(value, budget, 0, !requiredJsonArguments.has(index), kind)
129
+ ));
130
+ }
131
+
132
+ function wrapAsync(prototype, name, requiredJsonArguments) {
133
+ const original = prototype[name];
134
+ prototype[name] = function (...args) {
135
+ try {
136
+ const clonedArgs = cloneArguments(args, 'invalid_request', requiredJsonArguments);
137
+ return original.apply(this, clonedArgs).catch((error) => { throw normalize(error); });
138
+ } catch (error) {
139
+ throw normalize(error, 'invalid_request');
140
+ }
141
+ };
142
+ }
143
+
144
+ const METHODS = [
145
+ 'health', 'ready', 'openapi', 'serviceMetadata', 'resources', 'continueResources', 'resource',
146
+ 'listRecords', 'continueListRecords', 'readRecord', 'lookup', 'search', 'continueSearch',
147
+ 'artifact', 'sdmxData', 'sdmxStructure',
148
+ ];
149
+ const REQUIRED_JSON_ARGUMENTS = {
150
+ continueResources: new Set([0]),
151
+ continueListRecords: new Set([0]),
152
+ lookup: new Set([2]),
153
+ search: new Set([2]),
154
+ continueSearch: new Set([0]),
155
+ sdmxData: new Set([0]),
156
+ sdmxStructure: new Set([0]),
157
+ };
158
+ for (const method of METHODS) {
159
+ wrapAsync(native.RelayClient.prototype, method, REQUIRED_JSON_ARGUMENTS[method]);
160
+ }
161
+
162
+ class RelayClient extends native.RelayClient {
163
+ constructor(config) {
164
+ try {
165
+ super(...cloneArguments([config], 'configuration', new Set([0])));
166
+ } catch (error) {
167
+ throw normalize(error, 'configuration');
168
+ }
169
+ }
170
+ }
171
+
172
+ module.exports = { RelayClient, RelayClientError };
@@ -0,0 +1,58 @@
1
+ /* auto-generated by NAPI-RS */
2
+ /* eslint-disable */
3
+ export declare class RelayClient {
4
+ constructor(configValue: any)
5
+ health(): Promise<CompleteOutcome>
6
+ ready(): Promise<CompleteOutcome>
7
+ openapi(etag?: string | undefined | null): Promise<RawCompleteOutcome | NotModifiedOutcome>
8
+ serviceMetadata(etag?: string | undefined | null): Promise<CompleteOutcome | NotModifiedOutcome>
9
+ resources(options?: any | undefined | null, etag?: string | undefined | null): Promise<ResourcePageOutcome | NotModifiedOutcome>
10
+ continueResources(continuation: any, etag?: string | undefined | null): Promise<ResourcePageOutcome | NotModifiedOutcome>
11
+ resource(resource: string, etag?: string | undefined | null): Promise<CompleteOutcome | NotModifiedOutcome>
12
+ listRecords(resource: string, options?: any | undefined | null, etag?: string | undefined | null): Promise<CollectionPageOutcome | NotModifiedOutcome>
13
+ continueListRecords(continuation: any, etag?: string | undefined | null): Promise<CollectionPageOutcome | NotModifiedOutcome>
14
+ readRecord(resource: string, recordIdentifier: string, options?: any | undefined | null, etag?: string | undefined | null): Promise<CompleteOutcome | NotModifiedOutcome>
15
+ lookup(resource: string, lookup: string, selectors: any, options?: any | undefined | null, etag?: string | undefined | null): Promise<CompleteOutcome | NotModifiedOutcome>
16
+ search(resource: string, search: string, options: any, etag?: string | undefined | null): Promise<CollectionPageOutcome | NotModifiedOutcome>
17
+ continueSearch(continuation: any, etag?: string | undefined | null): Promise<CollectionPageOutcome | NotModifiedOutcome>
18
+ artifact(artifactIdentifier: string, etag?: string | undefined | null): Promise<RawCompleteOutcome | NotModifiedOutcome>
19
+ sdmxData(requestValue: any, etag?: string | undefined | null): Promise<RawCompleteOutcome | NotModifiedOutcome>
20
+ sdmxStructure(requestValue: any, etag?: string | undefined | null): Promise<RawCompleteOutcome | NotModifiedOutcome>
21
+ }
22
+
23
+ export interface CollectionPageOutcome {
24
+ kind: string
25
+ value: any
26
+ continuation?: any
27
+ traceId: string
28
+ etag?: string
29
+ }
30
+
31
+ export interface CompleteOutcome {
32
+ kind: string
33
+ value: any
34
+ traceId: string
35
+ etag?: string
36
+ }
37
+
38
+ export interface NotModifiedOutcome {
39
+ kind: string
40
+ etag: string
41
+ traceId: string
42
+ }
43
+
44
+ export interface RawCompleteOutcome {
45
+ kind: string
46
+ body: Buffer
47
+ mediaType: string
48
+ traceId: string
49
+ etag?: string
50
+ }
51
+
52
+ export interface ResourcePageOutcome {
53
+ kind: string
54
+ value: any
55
+ continuation?: any
56
+ traceId: string
57
+ etag?: string
58
+ }
package/relay/index.js ADDED
@@ -0,0 +1,3 @@
1
+ 'use strict';
2
+
3
+ module.exports = require('../native').load('relay');