datomic-client-js 0.1.10 → 0.1.12
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/.github/workflows/publish.yml +60 -0
- package/.github/workflows/test.yml +34 -0
- package/CHANGELOG.md +5 -1
- package/README.md +4 -2
- package/package.json +7 -7
- package/src/pro.js +27 -4
- package/src/shared.js +1106 -843
- package/debug.js +0 -8
- package/transactor.properties +0 -9
- package/x +0 -1
package/src/shared.js
CHANGED
|
@@ -1,32 +1,31 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
let chans = require(
|
|
4
|
-
let crypto = require(
|
|
5
|
-
let http = require(
|
|
6
|
-
let https = require(
|
|
7
|
-
let jsedn = require(
|
|
8
|
-
let query = require(
|
|
9
|
-
let transit = require(
|
|
10
|
-
let
|
|
11
|
-
let tx = require('./tx.js');
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
let chans = require("./channel");
|
|
4
|
+
let crypto = require("crypto");
|
|
5
|
+
let http = require("http");
|
|
6
|
+
let https = require("https");
|
|
7
|
+
let jsedn = require("jsedn");
|
|
8
|
+
let query = require("./query.js");
|
|
9
|
+
let transit = require("transit-js");
|
|
10
|
+
let tx = require("./tx.js");
|
|
12
11
|
|
|
13
12
|
function getState(v) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
if (v instanceof Db || v instanceof Connection) {
|
|
14
|
+
return v.getState();
|
|
15
|
+
} else {
|
|
16
|
+
return v;
|
|
17
|
+
}
|
|
19
18
|
}
|
|
20
19
|
|
|
21
20
|
function getRequestContext(v) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
if (v instanceof Db || v instanceof Connection) {
|
|
22
|
+
return v.getRequestContext();
|
|
23
|
+
} else {
|
|
24
|
+
return v;
|
|
25
|
+
}
|
|
27
26
|
}
|
|
28
27
|
|
|
29
|
-
const uuidTag = new jsedn.Tag(
|
|
28
|
+
const uuidTag = new jsedn.Tag("uuid");
|
|
30
29
|
jsedn.setTagAction(uuidTag, (v) => new jsedn.Tagged(uuidTag, v));
|
|
31
30
|
|
|
32
31
|
/**
|
|
@@ -36,11 +35,11 @@ jsedn.setTagAction(uuidTag, (v) => new jsedn.Tagged(uuidTag, v));
|
|
|
36
35
|
* @constructor UUID
|
|
37
36
|
*/
|
|
38
37
|
function UUID(s) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
if (uuidPat.exec(s) != null) {
|
|
39
|
+
this.rep = s;
|
|
40
|
+
} else {
|
|
41
|
+
throw new Error("invalid UUID string");
|
|
42
|
+
}
|
|
44
43
|
}
|
|
45
44
|
|
|
46
45
|
/**
|
|
@@ -50,17 +49,17 @@ function UUID(s) {
|
|
|
50
49
|
* @constructor BigInt
|
|
51
50
|
*/
|
|
52
51
|
function BigInt(i) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
52
|
+
if (typeof i == "number") {
|
|
53
|
+
this.rep = Math.floor(i).toString();
|
|
54
|
+
} else if (typeof i == "string" && /[0-9]+/.exec(i) != null) {
|
|
55
|
+
this.rep = i;
|
|
56
|
+
} else {
|
|
57
|
+
throw new Error("invalid integer");
|
|
58
|
+
}
|
|
60
59
|
}
|
|
61
60
|
|
|
62
61
|
BigInt.prototype.toString = function () {
|
|
63
|
-
|
|
62
|
+
return this.rep;
|
|
64
63
|
};
|
|
65
64
|
|
|
66
65
|
/**
|
|
@@ -70,77 +69,77 @@ BigInt.prototype.toString = function () {
|
|
|
70
69
|
* @constructor BigDec
|
|
71
70
|
*/
|
|
72
71
|
function BigDec(d) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
72
|
+
if (typeof d == "number") {
|
|
73
|
+
this.rep = d.toString();
|
|
74
|
+
} else if (typeof d == "string" && /^[0-9]+(\.[0-9]+)?$/.exec(d) != null) {
|
|
75
|
+
this.rep = d;
|
|
76
|
+
} else {
|
|
77
|
+
throw new Error("invalid integer");
|
|
78
|
+
}
|
|
80
79
|
}
|
|
81
80
|
|
|
82
81
|
BigDec.prototype.toString = function () {
|
|
83
|
-
|
|
82
|
+
return this.rep;
|
|
84
83
|
};
|
|
85
84
|
|
|
86
85
|
function convertAnomaly(anom) {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
86
|
+
if (transit.isMap(anom)) {
|
|
87
|
+
let ret = {};
|
|
88
|
+
anom.forEach((v, k) => {
|
|
89
|
+
if (transit.isKeyword(k)) {
|
|
90
|
+
k = k._name;
|
|
91
|
+
}
|
|
92
|
+
if (transit.isKeyword(v)) {
|
|
93
|
+
v = v._name;
|
|
94
|
+
}
|
|
95
|
+
ret[k] = v;
|
|
96
|
+
});
|
|
97
|
+
return ret;
|
|
98
|
+
} else {
|
|
99
|
+
return anom;
|
|
100
|
+
}
|
|
102
101
|
}
|
|
103
102
|
|
|
104
103
|
function AnomalyError(anomaly) {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
104
|
+
let anom = convertAnomaly(anomaly);
|
|
105
|
+
this.name = "AnomalyError";
|
|
106
|
+
this.message = JSON.stringify(anom);
|
|
107
|
+
this.anomaly = anom;
|
|
108
|
+
this.stack = new Error().stack;
|
|
110
109
|
}
|
|
111
110
|
|
|
112
|
-
AnomalyError.prototype = new Error;
|
|
111
|
+
AnomalyError.prototype = new Error();
|
|
113
112
|
|
|
114
113
|
function isAnomaly(m) {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
114
|
+
if (m == null) {
|
|
115
|
+
return false;
|
|
116
|
+
} else if (transit.isMap(m)) {
|
|
117
|
+
return m.get(transit.keyword("cognitect.anomalies/category")) !== undefined;
|
|
118
|
+
} else if (typeof m == "object") {
|
|
119
|
+
return m["cognitect.anomalies/category"] !== undefined;
|
|
120
|
+
} else {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
124
123
|
}
|
|
125
124
|
|
|
126
125
|
function anom(m) {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
126
|
+
if (isAnomaly(m)) {
|
|
127
|
+
return m;
|
|
128
|
+
}
|
|
130
129
|
}
|
|
131
130
|
|
|
132
131
|
function selectKeys(o, keys) {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
}
|
|
140
|
-
return result;
|
|
141
|
-
} else {
|
|
142
|
-
return o;
|
|
132
|
+
if (typeof o == "object") {
|
|
133
|
+
let result = {};
|
|
134
|
+
for (let k in o) {
|
|
135
|
+
if (keys.indexOf(k) >= 0) {
|
|
136
|
+
result[k] = o[k];
|
|
137
|
+
}
|
|
143
138
|
}
|
|
139
|
+
return result;
|
|
140
|
+
} else {
|
|
141
|
+
return o;
|
|
142
|
+
}
|
|
144
143
|
}
|
|
145
144
|
|
|
146
145
|
/**
|
|
@@ -149,32 +148,41 @@ function selectKeys(o, keys) {
|
|
|
149
148
|
* @constructor Db
|
|
150
149
|
*/
|
|
151
150
|
function Db(client, conn, info) {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
151
|
+
this.client = client;
|
|
152
|
+
this.conn = conn;
|
|
153
|
+
this.info = info;
|
|
155
154
|
}
|
|
156
155
|
|
|
157
|
-
const dbContextKeys = [
|
|
158
|
-
|
|
156
|
+
const dbContextKeys = [
|
|
157
|
+
"dbName",
|
|
158
|
+
"databaseId",
|
|
159
|
+
"t",
|
|
160
|
+
"nextT",
|
|
161
|
+
"asOf",
|
|
162
|
+
"since",
|
|
163
|
+
"history",
|
|
164
|
+
"nextToken",
|
|
165
|
+
];
|
|
166
|
+
const stateKeys = ["t", "nextT"];
|
|
159
167
|
|
|
160
|
-
Db.prototype.toQueryArg = function() {
|
|
161
|
-
|
|
168
|
+
Db.prototype.toQueryArg = function () {
|
|
169
|
+
return selectKeys(this.info, dbContextKeys);
|
|
162
170
|
};
|
|
163
171
|
|
|
164
172
|
Db.prototype.getClient = function () {
|
|
165
|
-
|
|
173
|
+
return this.client;
|
|
166
174
|
};
|
|
167
175
|
|
|
168
|
-
Db.prototype.getConn = function() {
|
|
169
|
-
|
|
176
|
+
Db.prototype.getConn = function () {
|
|
177
|
+
return this.conn;
|
|
170
178
|
};
|
|
171
179
|
|
|
172
|
-
Db.prototype.getState = function() {
|
|
173
|
-
|
|
180
|
+
Db.prototype.getState = function () {
|
|
181
|
+
return selectKeys(this.info, stateKeys);
|
|
174
182
|
};
|
|
175
183
|
|
|
176
184
|
Db.prototype.getRequestContext = function () {
|
|
177
|
-
|
|
185
|
+
return selectKeys(this.info, dbContextKeys);
|
|
178
186
|
};
|
|
179
187
|
|
|
180
188
|
/**
|
|
@@ -182,9 +190,9 @@ Db.prototype.getRequestContext = function () {
|
|
|
182
190
|
* @param t The database t query as of.
|
|
183
191
|
* @returns {Db} The new Db.
|
|
184
192
|
*/
|
|
185
|
-
Db.prototype.asOf = function(t) {
|
|
186
|
-
|
|
187
|
-
|
|
193
|
+
Db.prototype.asOf = function (t) {
|
|
194
|
+
let m = Object.assign({}, this.info, { asOf: t });
|
|
195
|
+
return new Db(this.client, this.conn, m);
|
|
188
196
|
};
|
|
189
197
|
|
|
190
198
|
/**
|
|
@@ -211,7 +219,7 @@ Db.prototype.asOf = function(t) {
|
|
|
211
219
|
* datoms.
|
|
212
220
|
*/
|
|
213
221
|
Db.prototype.datoms = function (m) {
|
|
214
|
-
|
|
222
|
+
return this.client.chunkedAsyncOp(this.conn, keyword("datoms"), this, m);
|
|
215
223
|
};
|
|
216
224
|
|
|
217
225
|
/**
|
|
@@ -219,8 +227,8 @@ Db.prototype.datoms = function (m) {
|
|
|
219
227
|
*
|
|
220
228
|
* @returns {Promise<*>} The promise that will yield the stats.
|
|
221
229
|
*/
|
|
222
|
-
Db.prototype.dbStats = function() {
|
|
223
|
-
|
|
230
|
+
Db.prototype.dbStats = function () {
|
|
231
|
+
return this.client.asyncOp(this.conn, keyword("db-stats"), this, null);
|
|
224
232
|
};
|
|
225
233
|
|
|
226
234
|
/**
|
|
@@ -229,8 +237,8 @@ Db.prototype.dbStats = function() {
|
|
|
229
237
|
* @returns {Db} The new history database value.
|
|
230
238
|
*/
|
|
231
239
|
Db.prototype.history = function () {
|
|
232
|
-
|
|
233
|
-
|
|
240
|
+
let m = Object.assign({}, this.info, { history: true });
|
|
241
|
+
return new Db(this.client, this.conn, m);
|
|
234
242
|
};
|
|
235
243
|
|
|
236
244
|
/**
|
|
@@ -253,7 +261,7 @@ Db.prototype.history = function () {
|
|
|
253
261
|
* @returns {Promise<channel.Channel>} The promise that yields the channel, or an error.
|
|
254
262
|
*/
|
|
255
263
|
Db.prototype.indexRange = function (m) {
|
|
256
|
-
|
|
264
|
+
return this.client.chunkedAsyncOp(this.conn, keyword("index-range"), this, m);
|
|
257
265
|
};
|
|
258
266
|
|
|
259
267
|
/**
|
|
@@ -271,7 +279,7 @@ Db.prototype.indexRange = function (m) {
|
|
|
271
279
|
* @returns {Promise<Object>} The pulled value.
|
|
272
280
|
*/
|
|
273
281
|
Db.prototype.pull = function (m) {
|
|
274
|
-
|
|
282
|
+
return this.client.asyncOp(this.conn, keyword("pull"), this, m);
|
|
275
283
|
};
|
|
276
284
|
|
|
277
285
|
/**
|
|
@@ -281,9 +289,9 @@ Db.prototype.pull = function (m) {
|
|
|
281
289
|
* @param t The t value.
|
|
282
290
|
* @returns {Db} The new database value.
|
|
283
291
|
*/
|
|
284
|
-
Db.prototype.since = function(t) {
|
|
285
|
-
|
|
286
|
-
|
|
292
|
+
Db.prototype.since = function (t) {
|
|
293
|
+
let m = Object.assign({}, this.info, { since: t });
|
|
294
|
+
return new Db(this.client, this.conn, m);
|
|
287
295
|
};
|
|
288
296
|
|
|
289
297
|
/**
|
|
@@ -296,7 +304,7 @@ Db.prototype.since = function(t) {
|
|
|
296
304
|
* @returns {Promise<Object>} A promise yielding the transaction result.
|
|
297
305
|
*/
|
|
298
306
|
Db.prototype.with = function (m) {
|
|
299
|
-
|
|
307
|
+
return this.client.asyncOp(this.conn, ":with", this, m);
|
|
300
308
|
};
|
|
301
309
|
|
|
302
310
|
/**
|
|
@@ -305,65 +313,65 @@ Db.prototype.with = function (m) {
|
|
|
305
313
|
* @constructor Connection
|
|
306
314
|
*/
|
|
307
315
|
function Connection(client, state, info, refreshInterval, lastRefresh) {
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
316
|
+
this.client = client;
|
|
317
|
+
this.state = state;
|
|
318
|
+
this.info = info;
|
|
319
|
+
this.refreshInterval = refreshInterval;
|
|
320
|
+
this.lastRefresh = lastRefresh;
|
|
313
321
|
}
|
|
314
322
|
|
|
315
323
|
function get_in(m, ...ks) {
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
}
|
|
324
|
+
let ret = m;
|
|
325
|
+
for (const k of ks) {
|
|
326
|
+
ret = ret[k];
|
|
327
|
+
if (ret == null) {
|
|
328
|
+
break;
|
|
322
329
|
}
|
|
323
|
-
|
|
330
|
+
}
|
|
331
|
+
return ret;
|
|
324
332
|
}
|
|
325
333
|
|
|
326
|
-
Connection.prototype.advanceT = function(db) {
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
334
|
+
Connection.prototype.advanceT = function (db) {
|
|
335
|
+
let newState = this.state;
|
|
336
|
+
let thisT = this.state.t;
|
|
337
|
+
if (thisT === undefined) {
|
|
338
|
+
thisT = -1;
|
|
339
|
+
}
|
|
340
|
+
db = transitToJs(db);
|
|
341
|
+
if (db.t > thisT) {
|
|
342
|
+
newState = selectKeys(db, stateKeys);
|
|
343
|
+
}
|
|
344
|
+
this.state = newState;
|
|
345
|
+
return this;
|
|
338
346
|
};
|
|
339
347
|
|
|
340
|
-
Connection.prototype.status = function() {
|
|
341
|
-
|
|
348
|
+
Connection.prototype.status = function () {
|
|
349
|
+
return this.client.asyncOp(null, ":status", this, this.info);
|
|
342
350
|
};
|
|
343
351
|
|
|
344
352
|
Connection.prototype.isStale = function () {
|
|
345
|
-
|
|
353
|
+
return Date.now() > this.lastRefresh + this.refreshInterval;
|
|
346
354
|
};
|
|
347
355
|
|
|
348
356
|
Connection.prototype.getClient = function () {
|
|
349
|
-
|
|
357
|
+
return this.client;
|
|
350
358
|
};
|
|
351
359
|
|
|
352
360
|
Connection.prototype.getConn = function () {
|
|
353
|
-
|
|
361
|
+
return this;
|
|
354
362
|
};
|
|
355
363
|
|
|
356
364
|
Connection.prototype.getRequestContext = function () {
|
|
357
|
-
|
|
365
|
+
return Object.assign({}, this.state, this.info);
|
|
358
366
|
};
|
|
359
367
|
|
|
360
|
-
Connection.prototype.getState = function() {
|
|
361
|
-
|
|
368
|
+
Connection.prototype.getState = function () {
|
|
369
|
+
return this.state;
|
|
362
370
|
};
|
|
363
371
|
|
|
364
|
-
Connection.prototype.getServerType = function() {
|
|
365
|
-
|
|
366
|
-
}
|
|
372
|
+
Connection.prototype.getServerType = function () {
|
|
373
|
+
return get_in(this, "client", "spi", "serverType");
|
|
374
|
+
};
|
|
367
375
|
|
|
368
376
|
/**
|
|
369
377
|
* Sync with the most recent transaction on the server, and return
|
|
@@ -372,19 +380,19 @@ Connection.prototype.getServerType = function() {
|
|
|
372
380
|
* @returns {Promise<Db>} The Db synced with the server.
|
|
373
381
|
*/
|
|
374
382
|
Connection.prototype.recentDb = function () {
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
383
|
+
if (this.isStale()) {
|
|
384
|
+
this.status().then(function (status) {
|
|
385
|
+
if (isAnomaly(status)) {
|
|
386
|
+
return status;
|
|
387
|
+
} else {
|
|
388
|
+
this.advanceT(status);
|
|
389
|
+
this.lastRefresh = Date.now();
|
|
390
|
+
return Connection.this.db();
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
} else {
|
|
394
|
+
return Promise.resolve(this.db());
|
|
395
|
+
}
|
|
388
396
|
};
|
|
389
397
|
|
|
390
398
|
/**
|
|
@@ -394,11 +402,11 @@ Connection.prototype.recentDb = function () {
|
|
|
394
402
|
* @returns {Db} The database.
|
|
395
403
|
*/
|
|
396
404
|
Connection.prototype.db = function () {
|
|
397
|
-
|
|
405
|
+
return new Db(this.client, this, getRequestContext(this));
|
|
398
406
|
};
|
|
399
407
|
|
|
400
408
|
Connection.prototype.log = function () {
|
|
401
|
-
|
|
409
|
+
return { log: this.info["database-id"] };
|
|
402
410
|
};
|
|
403
411
|
|
|
404
412
|
/**
|
|
@@ -427,7 +435,7 @@ Connection.prototype.log = function () {
|
|
|
427
435
|
* @returns {Promise<channel.Channel>} The promise yielding the channel of results.
|
|
428
436
|
*/
|
|
429
437
|
Connection.prototype.q = function (m) {
|
|
430
|
-
|
|
438
|
+
return this.client.chunkedAsyncOp(this, transit.keyword("q"), this, m);
|
|
431
439
|
};
|
|
432
440
|
|
|
433
441
|
/**
|
|
@@ -437,11 +445,11 @@ Connection.prototype.q = function (m) {
|
|
|
437
445
|
* @returns {Promise<Db>} The promise that yields the synced database.
|
|
438
446
|
*/
|
|
439
447
|
Connection.prototype.sync = function (t) {
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
448
|
+
if (typeof t != "number") {
|
|
449
|
+
throw new Error("t must be a number");
|
|
450
|
+
}
|
|
451
|
+
this.advanceT({ t: t });
|
|
452
|
+
return Promise.resolve(this.db());
|
|
445
453
|
};
|
|
446
454
|
|
|
447
455
|
/**
|
|
@@ -462,7 +470,7 @@ Connection.prototype.sync = function (t) {
|
|
|
462
470
|
* @returns {Promise<channel.Channel>} The promise that yields the channel of chunks.
|
|
463
471
|
*/
|
|
464
472
|
Connection.prototype.txRange = function (m) {
|
|
465
|
-
|
|
473
|
+
return this.client.chunkedAsyncOp(this, transit.keyword("tx-range"), this, m);
|
|
466
474
|
};
|
|
467
475
|
|
|
468
476
|
/**
|
|
@@ -478,7 +486,7 @@ Connection.prototype.txRange = function (m) {
|
|
|
478
486
|
* @returns {*}
|
|
479
487
|
*/
|
|
480
488
|
Connection.prototype.transact = function (m) {
|
|
481
|
-
|
|
489
|
+
return this.client.asyncOp(this, transit.keyword("transact"), this, m);
|
|
482
490
|
};
|
|
483
491
|
|
|
484
492
|
/**
|
|
@@ -488,826 +496,1081 @@ Connection.prototype.transact = function (m) {
|
|
|
488
496
|
* @returns {Promise<Db>} The promise that yields the db.
|
|
489
497
|
*/
|
|
490
498
|
Connection.prototype.withDb = function () {
|
|
491
|
-
|
|
499
|
+
return this.client.asyncOp(this, transit.keyword("with-db"), this, null);
|
|
492
500
|
};
|
|
493
501
|
|
|
494
502
|
// Client
|
|
495
503
|
|
|
496
504
|
function Client(spi) {
|
|
497
|
-
|
|
505
|
+
this.spi = spi;
|
|
498
506
|
}
|
|
499
507
|
|
|
500
|
-
const transactorTrust =
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
508
|
+
const transactorTrust =
|
|
509
|
+
"-----BEGIN CERTIFICATE-----\n" +
|
|
510
|
+
"MIICTzCCAbigAwIBAgIETyWfxDANBgkqhkiG9w0BAQUFADBsMRAwDgYDVQQGEwdV\n" +
|
|
511
|
+
"bmtub3duMRAwDgYDVQQIEwdVbmtub3duMRAwDgYDVQQHEwdVbmtub3duMRAwDgYD\n" +
|
|
512
|
+
"VQQKEwdVbmtub3duMRAwDgYDVQQLEwdVbmtub3duMRAwDgYDVQQDEwdVbmtub3du\n" +
|
|
513
|
+
"MB4XDTEyMDEyOTE5MzYzNloXDTIyMDEyNjE5MzYzNlowbDEQMA4GA1UEBhMHVW5r\n" +
|
|
514
|
+
"bm93bjEQMA4GA1UECBMHVW5rbm93bjEQMA4GA1UEBxMHVW5rbm93bjEQMA4GA1UE\n" +
|
|
515
|
+
"ChMHVW5rbm93bjEQMA4GA1UECxMHVW5rbm93bjEQMA4GA1UEAxMHVW5rbm93bjCB\n" +
|
|
516
|
+
"nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1E7f8OfsClwj9+pN2N0KbmZKt7+I\n" +
|
|
517
|
+
"xlRVNBldjaZfwjJEnea2pY9c9e+UveneuGugG2hOA/pICy3gmZyBTVUeXIOSdBEq\n" +
|
|
518
|
+
"CRvoJtk7FkmueWMY8ioZ0ygtSofTipPzYO9gDW032K3Z+bVmy9xj15K2aapRGeqF\n" +
|
|
519
|
+
"p38jQWVRdOoHJqsCAwEAATANBgkqhkiG9w0BAQUFAAOBgQDTX5KkZSY1gp6/+8/w\n" +
|
|
520
|
+
"vopGEFdwMt+CE8JTVlCh/xMTU5C3qxRqJNstP2IzhgdGKbl24nwafh8jUrC5EzDR\n" +
|
|
521
|
+
"CnQL0zx9KwImGqNGkszSimgfijxDRHDT6Ig15Bg07y4HxJgZNjxnIkNgjM7NgYzk\n" +
|
|
522
|
+
"QPBwyiyvf3HQDczNlFxUwVZVQQ==\n" +
|
|
523
|
+
"-----END CERTIFICATE-----";
|
|
515
524
|
|
|
516
525
|
function ExpBackoff(start, max, factor) {
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
526
|
+
this.value = start / factor;
|
|
527
|
+
this.factor = factor;
|
|
528
|
+
this.max = max;
|
|
520
529
|
}
|
|
521
530
|
|
|
522
|
-
ExpBackoff.prototype.backOff = function(error) {
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
531
|
+
ExpBackoff.prototype.backOff = function (error) {
|
|
532
|
+
let newValue = this.value * this.factor;
|
|
533
|
+
this.value = newValue;
|
|
534
|
+
if (newValue < this.max) {
|
|
535
|
+
return new Promise((resolve) => {
|
|
536
|
+
setTimeout(() => {
|
|
537
|
+
resolve(null);
|
|
538
|
+
}, newValue);
|
|
539
|
+
});
|
|
540
|
+
} else {
|
|
541
|
+
return Promise.reject(error);
|
|
542
|
+
}
|
|
532
543
|
};
|
|
533
544
|
|
|
534
545
|
function LinearBackoff(timeout, count) {
|
|
535
|
-
|
|
536
|
-
|
|
546
|
+
this.timeout = timeout;
|
|
547
|
+
this.count = count;
|
|
537
548
|
}
|
|
538
549
|
|
|
539
|
-
LinearBackoff.prototype.backOff = function(error) {
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
550
|
+
LinearBackoff.prototype.backOff = function (error) {
|
|
551
|
+
this.count = this.count - 1;
|
|
552
|
+
if (this.count > 0) {
|
|
553
|
+
let to = this.timeout;
|
|
554
|
+
return new Promise((resolve) => {
|
|
555
|
+
setTimeout(() => {
|
|
556
|
+
resolve(null);
|
|
557
|
+
}, to);
|
|
558
|
+
});
|
|
559
|
+
} else {
|
|
560
|
+
return Promise.reject(error);
|
|
561
|
+
}
|
|
549
562
|
};
|
|
550
563
|
|
|
551
564
|
function sendWithRetry(httpRequest, requestContext, spi, timeout) {
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
565
|
+
let signParams = spi.getSignParams(httpRequest, requestContext);
|
|
566
|
+
if (signParams == null) {
|
|
567
|
+
signParams = spi.refreshSignParams(httpRequest, requestContext);
|
|
568
|
+
} else {
|
|
569
|
+
signParams = Promise.resolve(signParams);
|
|
570
|
+
}
|
|
571
|
+
let uBackoff = new ExpBackoff(100, 400, 2);
|
|
572
|
+
let bBackoff = new LinearBackoff(10000, 6);
|
|
573
|
+
return doSendWithRetry(
|
|
574
|
+
httpRequest,
|
|
575
|
+
requestContext,
|
|
576
|
+
spi,
|
|
577
|
+
timeout,
|
|
578
|
+
signParams,
|
|
579
|
+
uBackoff,
|
|
580
|
+
bBackoff,
|
|
581
|
+
);
|
|
561
582
|
}
|
|
562
583
|
|
|
563
|
-
const retriableCategories = [
|
|
584
|
+
const retriableCategories = [
|
|
585
|
+
"cognitect.anomalies/unavailable",
|
|
586
|
+
"cognitect.anomalies/interrupted",
|
|
587
|
+
"cognitect.anomalies/fault",
|
|
588
|
+
];
|
|
564
589
|
const idempotentOps = [
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
590
|
+
"datomic.catalog/resolve-db",
|
|
591
|
+
"datomic.catalog/list-dbs",
|
|
592
|
+
"datoms",
|
|
593
|
+
"datomic.client.protocol/db-stats",
|
|
594
|
+
"datomic.client.protocol/index-range",
|
|
595
|
+
"datomic.client.protocol/next",
|
|
596
|
+
"datomic.client.protocol/pull",
|
|
597
|
+
"datomic.client.protocol/q",
|
|
598
|
+
"datomic.client.protocol/status",
|
|
599
|
+
"datomic.client.protocol/tx-range",
|
|
600
|
+
"datomic.client.protocol/with",
|
|
601
|
+
"datomic.client.protocol/with-db",
|
|
577
602
|
];
|
|
578
603
|
|
|
579
604
|
function retryAnom(category, op) {
|
|
580
|
-
|
|
605
|
+
return (
|
|
606
|
+
retriableCategories.indexOf(category) >= 0 && idempotentOps.indexOf(op) >= 0
|
|
607
|
+
);
|
|
581
608
|
}
|
|
582
609
|
|
|
583
|
-
function doSendWithRetry(
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
610
|
+
function doSendWithRetry(
|
|
611
|
+
httpRequest,
|
|
612
|
+
requestContext,
|
|
613
|
+
spi,
|
|
614
|
+
timeout,
|
|
615
|
+
signParams,
|
|
616
|
+
uBackoff,
|
|
617
|
+
bBackoff,
|
|
618
|
+
) {
|
|
619
|
+
let execRequest = function (signParams) {
|
|
620
|
+
let signedRequest = signRequest(httpRequest, signParams);
|
|
621
|
+
signedRequest.timeout = timeout;
|
|
622
|
+
let tlsConfig = spi.getTlsConfig ? spi.getTlsConfig() : null;
|
|
623
|
+
if (tlsConfig) {
|
|
624
|
+
// Use custom CA if provided, otherwise use default transactor trust anchor
|
|
625
|
+
signedRequest.ca = tlsConfig.ca || transactorTrust;
|
|
626
|
+
signedRequest.checkServerIdentity = function (_, __) {};
|
|
627
|
+
|
|
628
|
+
if (tlsConfig.validation === 'strict') {
|
|
629
|
+
signedRequest.rejectUnauthorized = true;
|
|
630
|
+
} else {
|
|
631
|
+
// 'allow-expired' or 'none': allow connection, we'll verify manually for 'allow-expired'
|
|
632
|
+
signedRequest.rejectUnauthorized = false;
|
|
633
|
+
}
|
|
634
|
+
} else if (spi.usePrivateTrustAnchor && spi.usePrivateTrustAnchor()) {
|
|
635
|
+
// Fallback for SPIs without getTlsConfig (e.g., cloud)
|
|
636
|
+
signedRequest.ca = transactorTrust;
|
|
637
|
+
signedRequest.checkServerIdentity = function (_, __) {};
|
|
638
|
+
signedRequest.rejectUnauthorized = false;
|
|
639
|
+
}
|
|
640
|
+
if (spi.getAgent() != null) {
|
|
641
|
+
signedRequest.agent = spi.getAgent();
|
|
642
|
+
}
|
|
643
|
+
return new Promise((resolve, reject) => {
|
|
644
|
+
let cb = (response) => {
|
|
645
|
+
// For 'allow-expired' mode, verify the only cert error is expiration
|
|
646
|
+
if (tlsConfig && tlsConfig.validation === 'allow-expired') {
|
|
647
|
+
let authError = response.socket.authorizationError;
|
|
648
|
+
if (authError && authError !== 'CERT_HAS_EXPIRED') {
|
|
649
|
+
reject(new Error(`Certificate validation failed: ${authError}`));
|
|
650
|
+
return;
|
|
651
|
+
}
|
|
593
652
|
}
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
response.on('data', (chunk) => {
|
|
598
|
-
response.bodyData = response.bodyData + chunk;
|
|
599
|
-
});
|
|
600
|
-
response.on('end', () => {
|
|
601
|
-
resolve(response);
|
|
602
|
-
});
|
|
603
|
-
};
|
|
604
|
-
let req;
|
|
605
|
-
if (signedRequest.scheme === 'http') {
|
|
606
|
-
req = http.request(signedRequest, cb);
|
|
607
|
-
} else {
|
|
608
|
-
req = https.request(signedRequest, cb);
|
|
609
|
-
}
|
|
610
|
-
req.on('timeout', () => {
|
|
611
|
-
reject(new AnomalyError({
|
|
612
|
-
'cognitect.anomalies/category': 'cognitect.anomalies/interrupted',
|
|
613
|
-
'cognitect.anomalies/message': 'request timed out'
|
|
614
|
-
}))
|
|
615
|
-
});
|
|
616
|
-
req.on('error', (error) => {
|
|
617
|
-
reject(error);
|
|
618
|
-
});
|
|
619
|
-
if (signedRequest.body != null) {
|
|
620
|
-
req.write(signedRequest.body);
|
|
621
|
-
}
|
|
622
|
-
req.end();
|
|
653
|
+
response.bodyData = "";
|
|
654
|
+
response.on("data", (chunk) => {
|
|
655
|
+
response.bodyData = response.bodyData + chunk;
|
|
623
656
|
});
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
657
|
+
response.on("end", () => {
|
|
658
|
+
resolve(response);
|
|
659
|
+
});
|
|
660
|
+
};
|
|
661
|
+
let req;
|
|
662
|
+
if (signedRequest.scheme === "http") {
|
|
663
|
+
req = http.request(signedRequest, cb);
|
|
664
|
+
} else {
|
|
665
|
+
req = https.request(signedRequest, cb);
|
|
666
|
+
}
|
|
667
|
+
req.on("timeout", () => {
|
|
668
|
+
reject(
|
|
669
|
+
new AnomalyError({
|
|
670
|
+
"cognitect.anomalies/category": "cognitect.anomalies/interrupted",
|
|
671
|
+
"cognitect.anomalies/message": "request timed out",
|
|
672
|
+
}),
|
|
673
|
+
);
|
|
674
|
+
});
|
|
675
|
+
req.on("error", (error) => {
|
|
676
|
+
reject(error);
|
|
677
|
+
});
|
|
678
|
+
if (signedRequest.body != null) {
|
|
679
|
+
req.write(signedRequest.body);
|
|
680
|
+
}
|
|
681
|
+
req.end();
|
|
682
|
+
});
|
|
683
|
+
};
|
|
684
|
+
let handleResponse = function (response) {
|
|
685
|
+
let reader = transit.reader("json");
|
|
686
|
+
let body = null;
|
|
687
|
+
if (response.headers["content-type"] === "application/transit+json") {
|
|
688
|
+
body = reader.read(response.bodyData);
|
|
689
|
+
}
|
|
690
|
+
if (isAnomaly(body)) {
|
|
691
|
+
throw new AnomalyError(body);
|
|
692
|
+
} else if (response.statusCode >= 500) {
|
|
693
|
+
let cat = "cognitect.anomalies/fault";
|
|
694
|
+
if (response.statusCode >= 502 && response.statusCode <= 504) {
|
|
695
|
+
cat = "cognitect.anomalies/unavailable";
|
|
696
|
+
}
|
|
697
|
+
throw new AnomalyError({
|
|
698
|
+
"cognitect.anomalies/category": cat,
|
|
699
|
+
status: response.statusCode,
|
|
700
|
+
headers: response.headers,
|
|
701
|
+
body: response.bodyData,
|
|
702
|
+
});
|
|
703
|
+
} else if (response.statusCode >= 400) {
|
|
704
|
+
let cat = "cognitect.anomalies/incorrect";
|
|
705
|
+
if (response.statusCode === 403) {
|
|
706
|
+
cat = "cognitect.anomalies/forbidden";
|
|
707
|
+
}
|
|
708
|
+
if (response.statusCode === 429) {
|
|
709
|
+
cat = "cognitect.anomalies/busy";
|
|
710
|
+
}
|
|
711
|
+
throw new AnomalyError({
|
|
712
|
+
"cognitect.anomalies/category": cat,
|
|
713
|
+
status: response.statusCode,
|
|
714
|
+
headers: response.headers,
|
|
715
|
+
body: response.bodyData,
|
|
716
|
+
});
|
|
717
|
+
} else {
|
|
718
|
+
response.body = body;
|
|
719
|
+
return response;
|
|
720
|
+
}
|
|
721
|
+
};
|
|
722
|
+
let catchError = function (error) {
|
|
723
|
+
if (error instanceof AnomalyError) {
|
|
724
|
+
let cat = error.anomaly["cognitect.anomalies/category"];
|
|
725
|
+
if (cat === "cognitect.anomalies/busy") {
|
|
726
|
+
bBackoff.backOff(error).then(() => {
|
|
727
|
+
return doSendWithRetry(
|
|
728
|
+
httpRequest,
|
|
729
|
+
requestContext,
|
|
730
|
+
spi,
|
|
731
|
+
timeout,
|
|
732
|
+
signParams,
|
|
733
|
+
uBackoff,
|
|
734
|
+
bBackoff,
|
|
735
|
+
);
|
|
736
|
+
});
|
|
737
|
+
} else if (cat === "cognitect.anomalies/forbidden") {
|
|
738
|
+
return signParams.then((oldSignParams) => {
|
|
739
|
+
return spi
|
|
740
|
+
.refreshSignParams(httpRequest, requestContext)
|
|
741
|
+
.then((newSignParams) => {
|
|
742
|
+
let equal = true;
|
|
743
|
+
for (let k in newSignParams) {
|
|
744
|
+
if (
|
|
745
|
+
newSignParams.hasOwnProperty(k) &&
|
|
746
|
+
oldSignParams.hasOwnProperty(k)
|
|
747
|
+
) {
|
|
748
|
+
let v1 = newSignParams[k];
|
|
749
|
+
let v2 = oldSignParams[k];
|
|
750
|
+
if (v1 !== v2) {
|
|
751
|
+
equal = false;
|
|
752
|
+
break;
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
if (equal) {
|
|
696
757
|
throw error;
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
758
|
+
} else {
|
|
759
|
+
return doSendWithRetry(
|
|
760
|
+
httpRequest,
|
|
761
|
+
requestContext,
|
|
762
|
+
spi,
|
|
763
|
+
timeout,
|
|
764
|
+
Promise.resolve(newSignParams),
|
|
765
|
+
uBackoff,
|
|
766
|
+
bBackoff,
|
|
767
|
+
);
|
|
768
|
+
}
|
|
769
|
+
});
|
|
770
|
+
});
|
|
771
|
+
} else if (retryAnom(cat, httpRequest.op)) {
|
|
772
|
+
uBackoff.backOff(error).then(() => {
|
|
773
|
+
return doSendWithRetry(
|
|
774
|
+
httpRequest,
|
|
775
|
+
requestContext,
|
|
776
|
+
spi,
|
|
777
|
+
timeout,
|
|
778
|
+
signParams,
|
|
779
|
+
uBackoff,
|
|
780
|
+
bBackoff,
|
|
781
|
+
);
|
|
782
|
+
});
|
|
783
|
+
} else {
|
|
784
|
+
throw error;
|
|
785
|
+
}
|
|
786
|
+
} else {
|
|
787
|
+
throw error;
|
|
788
|
+
}
|
|
789
|
+
};
|
|
790
|
+
return signParams.then(execRequest).then(handleResponse).catch(catchError);
|
|
703
791
|
}
|
|
704
792
|
|
|
705
|
-
const signedHeaders = [
|
|
793
|
+
const signedHeaders = [
|
|
794
|
+
"content-type",
|
|
795
|
+
"host",
|
|
796
|
+
"x-amz-content-sha256",
|
|
797
|
+
"x-amz-date",
|
|
798
|
+
"x-amz-target",
|
|
799
|
+
];
|
|
706
800
|
|
|
707
801
|
function canonicalHeadersStr(headers) {
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
802
|
+
return signedHeaders
|
|
803
|
+
.map((hdr) => {
|
|
804
|
+
let v = headers[hdr];
|
|
805
|
+
if (v !== undefined) {
|
|
806
|
+
return hdr + ":" + v + "\n";
|
|
807
|
+
} else {
|
|
808
|
+
return "";
|
|
809
|
+
}
|
|
810
|
+
})
|
|
811
|
+
.join("");
|
|
716
812
|
}
|
|
717
813
|
|
|
718
814
|
function canonicalRequestStr(request) {
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
815
|
+
let path = request.path;
|
|
816
|
+
if (path == null || path === "") {
|
|
817
|
+
path = "/";
|
|
818
|
+
}
|
|
819
|
+
return (
|
|
820
|
+
request.method.toUpperCase() +
|
|
821
|
+
"\n" +
|
|
822
|
+
path +
|
|
823
|
+
"\n" +
|
|
824
|
+
"\n" + // no query params
|
|
825
|
+
canonicalHeadersStr(request.headers) +
|
|
826
|
+
"\n" +
|
|
827
|
+
signedHeaders.join(";") +
|
|
828
|
+
"\n" +
|
|
829
|
+
request.headers["x-amz-content-sha256"]
|
|
830
|
+
);
|
|
729
831
|
}
|
|
730
832
|
|
|
731
833
|
function canonicalRequestHash(request) {
|
|
732
|
-
|
|
733
|
-
|
|
834
|
+
let requestStr = canonicalRequestStr(request);
|
|
835
|
+
return crypto
|
|
836
|
+
.createHash("sha256")
|
|
837
|
+
.update(requestStr)
|
|
838
|
+
.digest()
|
|
839
|
+
.toString("hex");
|
|
734
840
|
}
|
|
735
841
|
|
|
736
842
|
function credentialScope(service, region, xAmzDate) {
|
|
737
|
-
|
|
843
|
+
return [xAmzDate.split("T")[0], region, service, "aws4_request"].join("/");
|
|
738
844
|
}
|
|
739
845
|
|
|
740
846
|
function stringtoSign(xAmzDate, credentialScope, requestHash) {
|
|
741
|
-
|
|
847
|
+
return ["AWS4-HMAC-SHA256", xAmzDate, credentialScope, requestHash].join(
|
|
848
|
+
"\n",
|
|
849
|
+
);
|
|
742
850
|
}
|
|
743
851
|
|
|
744
852
|
function escapeAccessKeyId(accessKeyId) {
|
|
745
|
-
|
|
853
|
+
return accessKeyId.split("/").join("\\");
|
|
746
854
|
}
|
|
747
855
|
exports.escapeAccessKeyId = escapeAccessKeyId;
|
|
748
856
|
|
|
749
857
|
function unescapeAccessKeyId(accessKeyId) {
|
|
750
|
-
|
|
858
|
+
return accessKeyId.split("\\").join("/");
|
|
751
859
|
}
|
|
752
860
|
|
|
753
|
-
function formatSignature(
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
861
|
+
function formatSignature(
|
|
862
|
+
accessKeyId,
|
|
863
|
+
credentialScope,
|
|
864
|
+
signedHeaders,
|
|
865
|
+
signature,
|
|
866
|
+
) {
|
|
867
|
+
return (
|
|
868
|
+
"AWS4-HMAC-SHA256 Credential=" +
|
|
869
|
+
escapeAccessKeyId(accessKeyId) +
|
|
870
|
+
"/" +
|
|
871
|
+
credentialScope +
|
|
872
|
+
", SignedHeaders=" +
|
|
873
|
+
signedHeaders +
|
|
874
|
+
", Signature=" +
|
|
875
|
+
signature
|
|
876
|
+
);
|
|
757
877
|
}
|
|
758
878
|
|
|
759
879
|
function hmacSha256(key, input) {
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
880
|
+
let mac = crypto.createHmac("sha256", key);
|
|
881
|
+
mac.update(input);
|
|
882
|
+
return mac.digest();
|
|
763
883
|
}
|
|
764
884
|
|
|
765
885
|
function signRequest(request, signParams) {
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
886
|
+
if (
|
|
887
|
+
typeof signParams.accessKey == "string" &&
|
|
888
|
+
typeof signParams.secret == "string" &&
|
|
889
|
+
typeof signParams.service == "string" &&
|
|
890
|
+
typeof signParams.region == "string"
|
|
891
|
+
) {
|
|
892
|
+
request = Object.assign({}, request);
|
|
893
|
+
let pattern = /\.[0-9]{3}Z/;
|
|
894
|
+
let now = new Date();
|
|
895
|
+
let amzDate = now.toJSON().replace(pattern, "Z").split(/[-:]/).join("");
|
|
896
|
+
let amzSha = crypto
|
|
897
|
+
.createHash("sha256")
|
|
898
|
+
.update(request.body)
|
|
899
|
+
.digest()
|
|
900
|
+
.toString("hex");
|
|
901
|
+
request.headers["x-amz-date"] = amzDate;
|
|
902
|
+
request.headers["x-amz-content-sha256"] = amzSha;
|
|
903
|
+
let crh = canonicalRequestHash(request);
|
|
904
|
+
let cs = credentialScope(signParams.service, signParams.region, amzDate);
|
|
905
|
+
let ss = stringtoSign(amzDate, cs, crh);
|
|
906
|
+
let dateToSign = amzDate.split("T")[0];
|
|
907
|
+
let k = hmacSha256("AWS4" + signParams.secret, dateToSign);
|
|
908
|
+
k = hmacSha256(k, signParams.region);
|
|
909
|
+
k = hmacSha256(k, signParams.service);
|
|
910
|
+
let derivedKey = hmacSha256(k, "aws4_request");
|
|
911
|
+
let signature = hmacSha256(derivedKey, ss).toString("hex");
|
|
912
|
+
request.headers["authorization"] = formatSignature(
|
|
913
|
+
signParams.accessKey,
|
|
914
|
+
cs,
|
|
915
|
+
signedHeaders.join(";"),
|
|
916
|
+
signature,
|
|
917
|
+
);
|
|
918
|
+
return request;
|
|
919
|
+
} else {
|
|
920
|
+
throw new AnomalyError({
|
|
921
|
+
"cognitect.anomalies/category": "cognitect.anomalies/incorrect",
|
|
922
|
+
});
|
|
923
|
+
}
|
|
791
924
|
}
|
|
792
925
|
|
|
793
926
|
function toTitleCase(s) {
|
|
794
|
-
|
|
927
|
+
return s[0].toUpperCase() + s.slice(1);
|
|
795
928
|
}
|
|
796
929
|
|
|
797
930
|
function camelCaseToKebabCase(s) {
|
|
798
|
-
|
|
931
|
+
return s
|
|
932
|
+
.split(/(?=[A-Z])/)
|
|
933
|
+
.map((x) => x.toLowerCase())
|
|
934
|
+
.join("-");
|
|
799
935
|
}
|
|
800
936
|
|
|
801
937
|
function keywordizeKey(k) {
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
} else {
|
|
806
|
-
return keyword(camelCaseToKebabCase(k));
|
|
807
|
-
}
|
|
938
|
+
if (typeof k == "string") {
|
|
939
|
+
if (k.indexOf("/") >= 0) {
|
|
940
|
+
return keyword(k);
|
|
808
941
|
} else {
|
|
809
|
-
|
|
942
|
+
return keyword(camelCaseToKebabCase(k));
|
|
810
943
|
}
|
|
944
|
+
} else {
|
|
945
|
+
return k;
|
|
946
|
+
}
|
|
811
947
|
}
|
|
812
948
|
|
|
813
|
-
const uuidPat =
|
|
949
|
+
const uuidPat =
|
|
950
|
+
/[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/;
|
|
814
951
|
function jsToTransit(m) {
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
} else {
|
|
841
|
-
throw new Error(`can't convert tagged value '${m.dn()}' to transit`)
|
|
842
|
-
}
|
|
843
|
-
} else if (m instanceof jsedn.Keyword) {
|
|
844
|
-
return transit.keyword(m.val.slice(1));
|
|
845
|
-
} else if (m instanceof jsedn.Symbol) {
|
|
846
|
-
return transit.symbol(m.val);
|
|
847
|
-
} else if (m instanceof jsedn.BigInt) {
|
|
848
|
-
return transit.bigInt(m.val);
|
|
849
|
-
} else if (transit.isTaggedValue(m) || transit.isKeyword(m) || transit.isSymbol(m)) {
|
|
850
|
-
return m;
|
|
851
|
-
} else if (typeof m == 'object') {
|
|
852
|
-
let ret = transit.map([]);
|
|
853
|
-
for (let k in m) {
|
|
854
|
-
if (m.hasOwnProperty(k)) {
|
|
855
|
-
ret.set(keywordizeKey(k), jsToTransit(m[k]));
|
|
856
|
-
}
|
|
857
|
-
}
|
|
858
|
-
return ret;
|
|
952
|
+
if (Array.isArray(m)) {
|
|
953
|
+
return m.map(jsToTransit);
|
|
954
|
+
} else if (m instanceof UUID) {
|
|
955
|
+
return transit.uuid(m.rep);
|
|
956
|
+
} else if (m instanceof BigInt) {
|
|
957
|
+
return transit.bigInt(m.rep);
|
|
958
|
+
} else if (m instanceof BigDec) {
|
|
959
|
+
return transit.bigDec(m.rep);
|
|
960
|
+
} else if (m instanceof Db) {
|
|
961
|
+
return jsToTransit(m.toQueryArg());
|
|
962
|
+
} else if (m instanceof jsedn.Map) {
|
|
963
|
+
let ret = transit.map();
|
|
964
|
+
m.each((v, k) => {
|
|
965
|
+
ret.set(jsToTransit(k), jsToTransit(v));
|
|
966
|
+
});
|
|
967
|
+
return ret;
|
|
968
|
+
} else if (m instanceof jsedn.List) {
|
|
969
|
+
return transit.list(m.val.map(jsToTransit));
|
|
970
|
+
} else if (m instanceof jsedn.Set) {
|
|
971
|
+
return transit.set(m.val.map(jsToTransit));
|
|
972
|
+
} else if (m instanceof jsedn.Vector) {
|
|
973
|
+
return m.val.map(jsToTransit);
|
|
974
|
+
} else if (m instanceof jsedn.Tagged) {
|
|
975
|
+
if (m.tag() === uuidTag) {
|
|
976
|
+
return transit.uuid(m.obj());
|
|
859
977
|
} else {
|
|
860
|
-
|
|
978
|
+
throw new Error(`can't convert tagged value '${m.dn()}' to transit`);
|
|
861
979
|
}
|
|
980
|
+
} else if (m instanceof jsedn.Keyword) {
|
|
981
|
+
return transit.keyword(m.val.slice(1));
|
|
982
|
+
} else if (m instanceof jsedn.Symbol) {
|
|
983
|
+
return transit.symbol(m.val);
|
|
984
|
+
} else if (m instanceof jsedn.BigInt) {
|
|
985
|
+
return transit.bigInt(m.val);
|
|
986
|
+
} else if (
|
|
987
|
+
transit.isTaggedValue(m) ||
|
|
988
|
+
transit.isKeyword(m) ||
|
|
989
|
+
transit.isSymbol(m)
|
|
990
|
+
) {
|
|
991
|
+
return m;
|
|
992
|
+
} else if (typeof m == "object") {
|
|
993
|
+
let ret = transit.map([]);
|
|
994
|
+
for (let k in m) {
|
|
995
|
+
if (m.hasOwnProperty(k)) {
|
|
996
|
+
ret.set(keywordizeKey(k), jsToTransit(m[k]));
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
return ret;
|
|
1000
|
+
} else {
|
|
1001
|
+
return m;
|
|
1002
|
+
}
|
|
862
1003
|
}
|
|
863
1004
|
|
|
864
1005
|
function transitToJs(m) {
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
} else {
|
|
887
|
-
let parts = m.name().split('-');
|
|
888
|
-
return parts[0] + parts.slice(1).map(toTitleCase).join('');
|
|
889
|
-
}
|
|
890
|
-
} else if (transit.isUUID(m)) {
|
|
891
|
-
return new UUID(m.toString());
|
|
892
|
-
} else if (transit.isBigInt(m)) {
|
|
893
|
-
return new BigInt(m.rep);
|
|
894
|
-
} else if (transit.isBigDec(m)) {
|
|
895
|
-
return new BigDec(m.rep);
|
|
896
|
-
} else if (transit.isTaggedValue(m) && m.tag === 'datom') {
|
|
897
|
-
return {
|
|
898
|
-
e: transitToJs(m.rep[0]),
|
|
899
|
-
a: transitToJs(m.rep[1]),
|
|
900
|
-
v: transitToJs(m.rep[2]),
|
|
901
|
-
tx: transitToJs(m.rep[3]),
|
|
902
|
-
added: transitToJs(m.rep[4])
|
|
903
|
-
};
|
|
904
|
-
} else if (transit.isInteger(m) && typeof m !== 'number') {
|
|
905
|
-
return new BigInt(m.toString());
|
|
1006
|
+
if (transit.isList(m)) {
|
|
1007
|
+
return m.rep.map(transitToJs);
|
|
1008
|
+
} else if (transit.isMap(m)) {
|
|
1009
|
+
let ret = {};
|
|
1010
|
+
m.forEach((v, k) => {
|
|
1011
|
+
k = transitToJs(k);
|
|
1012
|
+
v = transitToJs(v);
|
|
1013
|
+
ret[k] = v;
|
|
1014
|
+
});
|
|
1015
|
+
return ret;
|
|
1016
|
+
} else if (transit.isSet(m)) {
|
|
1017
|
+
let ret = [];
|
|
1018
|
+
m.forEach((v) => {
|
|
1019
|
+
ret.push(transitToJs(v));
|
|
1020
|
+
});
|
|
1021
|
+
return ret;
|
|
1022
|
+
} else if (Array.isArray(m)) {
|
|
1023
|
+
return m.map(transitToJs);
|
|
1024
|
+
} else if (transit.isKeyword(m) || transit.isSymbol(m)) {
|
|
1025
|
+
if (m.namespace() != null) {
|
|
1026
|
+
return m.namespace() + "/" + m.name();
|
|
906
1027
|
} else {
|
|
907
|
-
|
|
1028
|
+
let parts = m.name().split("-");
|
|
1029
|
+
return parts[0] + parts.slice(1).map(toTitleCase).join("");
|
|
908
1030
|
}
|
|
1031
|
+
} else if (transit.isUUID(m)) {
|
|
1032
|
+
return new UUID(m.toString());
|
|
1033
|
+
} else if (transit.isBigInt(m)) {
|
|
1034
|
+
return new BigInt(m.rep);
|
|
1035
|
+
} else if (transit.isBigDec(m)) {
|
|
1036
|
+
return new BigDec(m.rep);
|
|
1037
|
+
} else if (transit.isTaggedValue(m) && m.tag === "datom") {
|
|
1038
|
+
return {
|
|
1039
|
+
e: transitToJs(m.rep[0]),
|
|
1040
|
+
a: transitToJs(m.rep[1]),
|
|
1041
|
+
v: transitToJs(m.rep[2]),
|
|
1042
|
+
tx: transitToJs(m.rep[3]),
|
|
1043
|
+
added: transitToJs(m.rep[4]),
|
|
1044
|
+
};
|
|
1045
|
+
} else if (transit.isInteger(m) && typeof m !== "number") {
|
|
1046
|
+
return new BigInt(m.toString());
|
|
1047
|
+
} else {
|
|
1048
|
+
return m;
|
|
1049
|
+
}
|
|
909
1050
|
}
|
|
910
1051
|
|
|
911
1052
|
function clientResponseToApi(conn, op, requester, response) {
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
1053
|
+
switch (op.toString()) {
|
|
1054
|
+
case ":transact":
|
|
1055
|
+
case ":with":
|
|
1056
|
+
return {
|
|
1057
|
+
dbBefore: new Db(
|
|
1058
|
+
this,
|
|
1059
|
+
conn,
|
|
1060
|
+
Object.assign(
|
|
1061
|
+
{},
|
|
1062
|
+
selectKeys(getRequestContext(requester), ["databaseId", "dbName"]),
|
|
1063
|
+
selectKeys(
|
|
1064
|
+
transitToJs(response.get(keyword("db-before"))),
|
|
1065
|
+
dbContextKeys,
|
|
1066
|
+
),
|
|
1067
|
+
),
|
|
1068
|
+
),
|
|
1069
|
+
dbAfter: new Db(
|
|
1070
|
+
this,
|
|
1071
|
+
conn,
|
|
1072
|
+
Object.assign(
|
|
1073
|
+
{},
|
|
1074
|
+
selectKeys(getRequestContext(requester), ["databaseId", "dbName"]),
|
|
1075
|
+
selectKeys(
|
|
1076
|
+
transitToJs(response.get(keyword("db-after"))),
|
|
1077
|
+
dbContextKeys,
|
|
1078
|
+
),
|
|
1079
|
+
),
|
|
1080
|
+
),
|
|
1081
|
+
txData: transitToJs(response.get(keyword("tx-data"))),
|
|
1082
|
+
tempids: transitToJs(response.get(keyword("tempids"))),
|
|
1083
|
+
};
|
|
1084
|
+
case ":datoms":
|
|
1085
|
+
case ":q":
|
|
1086
|
+
case ":tx-range":
|
|
1087
|
+
case ":index-range":
|
|
1088
|
+
case ":next":
|
|
1089
|
+
return transitToJs(response.get(keyword("data")));
|
|
1090
|
+
case ":pull":
|
|
1091
|
+
case ":db-stats":
|
|
1092
|
+
case ":datomic.catalog/list-dbs":
|
|
1093
|
+
return transitToJs(response.get(keyword("result")));
|
|
1094
|
+
case ":with-db":
|
|
1095
|
+
return new Db(
|
|
1096
|
+
this,
|
|
1097
|
+
conn,
|
|
1098
|
+
Object.assign(
|
|
1099
|
+
{},
|
|
1100
|
+
getRequestContext(requester),
|
|
1101
|
+
selectKeys(transitToJs(response), dbContextKeys),
|
|
1102
|
+
),
|
|
1103
|
+
);
|
|
1104
|
+
case ":datomic.catalog/create-db":
|
|
1105
|
+
case ":datomic.catalog/delete-db":
|
|
1106
|
+
return true;
|
|
1107
|
+
default:
|
|
1108
|
+
return transitToJs(response);
|
|
1109
|
+
}
|
|
944
1110
|
}
|
|
945
1111
|
|
|
946
1112
|
function updateState(conn, response) {
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
}
|
|
961
|
-
}
|
|
1113
|
+
if (response != null) {
|
|
1114
|
+
let dbs = response.get(keyword("dbs"));
|
|
1115
|
+
let dbAfter = response.get(keyword("db-after"));
|
|
1116
|
+
if (conn != null && conn.info != null) {
|
|
1117
|
+
if (dbs != null) {
|
|
1118
|
+
dbs.forEach((db) => {
|
|
1119
|
+
if (db.get(keyword("database-id")) === conn.info.databaseId) {
|
|
1120
|
+
conn.advanceT(db);
|
|
1121
|
+
}
|
|
1122
|
+
});
|
|
1123
|
+
} else if (dbAfter != null) {
|
|
1124
|
+
if (dbAfter.get(keyword("database-id")) === conn.info.databaseId) {
|
|
1125
|
+
conn.advanceT(dbAfter);
|
|
962
1126
|
}
|
|
1127
|
+
}
|
|
963
1128
|
}
|
|
1129
|
+
}
|
|
964
1130
|
}
|
|
965
1131
|
|
|
966
1132
|
function convertResponse(conn, op, requester, response, handler) {
|
|
967
|
-
|
|
968
|
-
|
|
1133
|
+
updateState(conn, response);
|
|
1134
|
+
return handler(conn, op, requester, response);
|
|
969
1135
|
}
|
|
970
1136
|
|
|
971
1137
|
Client.prototype.asyncOp = function (conn, op, requester, m) {
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
1138
|
+
let requestContext = getRequestContext(requester);
|
|
1139
|
+
let request = apiToClientRequest(op, requestContext, m);
|
|
1140
|
+
let httpRequest = clientRequestToHttpRequest(request);
|
|
1141
|
+
let routedHttpRequest = this.spi.addRouting(httpRequest);
|
|
1142
|
+
m = m || {};
|
|
1143
|
+
return sendWithRetry(
|
|
1144
|
+
routedHttpRequest,
|
|
1145
|
+
requestContext,
|
|
1146
|
+
this.spi,
|
|
1147
|
+
m.timeout || 60000,
|
|
1148
|
+
).then((result) => {
|
|
1149
|
+
let res = null;
|
|
1150
|
+
if (result != null) {
|
|
1151
|
+
res = result.body;
|
|
1152
|
+
}
|
|
1153
|
+
return convertResponse(conn, op, requester, res, clientResponseToApi);
|
|
1154
|
+
});
|
|
986
1155
|
};
|
|
987
1156
|
|
|
988
|
-
function convertChunkedResponse(
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1157
|
+
function convertChunkedResponse(
|
|
1158
|
+
conn,
|
|
1159
|
+
op,
|
|
1160
|
+
requester,
|
|
1161
|
+
response,
|
|
1162
|
+
handler,
|
|
1163
|
+
spi,
|
|
1164
|
+
requestContext,
|
|
1165
|
+
timeout,
|
|
1166
|
+
channel,
|
|
1167
|
+
) {
|
|
1168
|
+
updateState(conn, response);
|
|
1169
|
+
let resp = handler(conn, op, requester, response);
|
|
1170
|
+
channel.put(resp).then((result) => {
|
|
1171
|
+
if (result) {
|
|
1172
|
+
let nextOffset = response.get(keyword("next-offset"));
|
|
1173
|
+
if (nextOffset != null) {
|
|
1174
|
+
let nextOp = keyword("next");
|
|
1175
|
+
let nextRequest = Object.assign({}, requestContext, {
|
|
1176
|
+
op: nextOp,
|
|
1177
|
+
nextToken: response.get(keyword("next-token")),
|
|
1178
|
+
offset: nextOffset,
|
|
1179
|
+
chunk: response.get(keyword("chunk")),
|
|
1180
|
+
});
|
|
1181
|
+
let nextClientRequest = apiToClientRequest(
|
|
1182
|
+
nextOp,
|
|
1183
|
+
requester,
|
|
1184
|
+
nextRequest,
|
|
1185
|
+
);
|
|
1186
|
+
let nextHttpRequest = clientRequestToHttpRequest(nextClientRequest);
|
|
1187
|
+
let nextRoutedRequest = spi.addRouting(nextHttpRequest);
|
|
1188
|
+
return sendWithRetry(
|
|
1189
|
+
nextRoutedRequest,
|
|
1190
|
+
requestContext,
|
|
1191
|
+
spi,
|
|
1192
|
+
timeout || 60000,
|
|
1193
|
+
).then((result) => {
|
|
1194
|
+
convertChunkedResponse(
|
|
1195
|
+
conn,
|
|
1196
|
+
nextOp,
|
|
1197
|
+
requester,
|
|
1198
|
+
result.body,
|
|
1199
|
+
handler,
|
|
1200
|
+
spi,
|
|
1201
|
+
requestContext,
|
|
1202
|
+
timeout,
|
|
1203
|
+
channel,
|
|
1204
|
+
);
|
|
1205
|
+
});
|
|
1206
|
+
} else {
|
|
1207
|
+
channel.close();
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
});
|
|
1016
1211
|
}
|
|
1017
1212
|
|
|
1018
1213
|
Client.prototype.chunkedAsyncOp = function (conn, op, requester, m) {
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1214
|
+
let channel = new chans.Channel();
|
|
1215
|
+
let requestContext = getRequestContext(requester);
|
|
1216
|
+
let request = apiToClientRequest(op, requestContext, m);
|
|
1217
|
+
let httpRequest = clientRequestToHttpRequest(request);
|
|
1218
|
+
let routedHttpRequest = this.spi.addRouting(httpRequest);
|
|
1219
|
+
m = m || {};
|
|
1220
|
+
return sendWithRetry(
|
|
1221
|
+
routedHttpRequest,
|
|
1222
|
+
requestContext,
|
|
1223
|
+
this.spi,
|
|
1224
|
+
m.timeout || 60000,
|
|
1225
|
+
).then((result) => {
|
|
1226
|
+
convertChunkedResponse(
|
|
1227
|
+
conn,
|
|
1228
|
+
op,
|
|
1229
|
+
requester,
|
|
1230
|
+
result.body,
|
|
1231
|
+
clientResponseToApi,
|
|
1232
|
+
this.spi,
|
|
1233
|
+
requestContext,
|
|
1234
|
+
m.timeout,
|
|
1235
|
+
channel,
|
|
1030
1236
|
);
|
|
1237
|
+
return channel;
|
|
1238
|
+
});
|
|
1031
1239
|
};
|
|
1032
1240
|
|
|
1033
|
-
Client.prototype.connect = function(m) {
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1241
|
+
Client.prototype.connect = function (m) {
|
|
1242
|
+
if (typeof m.dbName != "string") {
|
|
1243
|
+
throw new Error("expected string for key dbName");
|
|
1244
|
+
} else {
|
|
1245
|
+
let address = { dbName: m.dbName };
|
|
1246
|
+
let _this = this;
|
|
1247
|
+
return this.asyncOp(
|
|
1248
|
+
null,
|
|
1249
|
+
keyword("datomic.catalog/resolve-db"),
|
|
1250
|
+
address,
|
|
1251
|
+
m,
|
|
1252
|
+
).then((resolved) => {
|
|
1253
|
+
return _this
|
|
1254
|
+
.asyncOp(
|
|
1255
|
+
null,
|
|
1256
|
+
keyword("status"),
|
|
1257
|
+
address,
|
|
1258
|
+
Object.assign({}, m, resolved),
|
|
1259
|
+
)
|
|
1260
|
+
.then((status) => {
|
|
1261
|
+
return new Connection(_this, selectKeys(status, stateKeys), {
|
|
1262
|
+
dbName: m.dbName,
|
|
1263
|
+
databaseId: status.databaseId,
|
|
1264
|
+
});
|
|
1265
|
+
});
|
|
1266
|
+
});
|
|
1267
|
+
}
|
|
1049
1268
|
};
|
|
1050
1269
|
|
|
1051
|
-
Client.prototype.listDatabases = function(m) {
|
|
1052
|
-
|
|
1270
|
+
Client.prototype.listDatabases = function (m) {
|
|
1271
|
+
return this.asyncOp(null, keyword("datomic.catalog/list-dbs"), m, null);
|
|
1053
1272
|
};
|
|
1054
1273
|
|
|
1055
|
-
Client.prototype.createDatabase = function(m) {
|
|
1056
|
-
|
|
1274
|
+
Client.prototype.createDatabase = function (m) {
|
|
1275
|
+
return this.asyncOp(null, keyword("datomic.catalog/create-db"), m, {
|
|
1276
|
+
dbName: m.dbName,
|
|
1277
|
+
});
|
|
1057
1278
|
};
|
|
1058
1279
|
|
|
1059
|
-
Client.prototype.deleteDatabase = function(m) {
|
|
1060
|
-
|
|
1280
|
+
Client.prototype.deleteDatabase = function (m) {
|
|
1281
|
+
return this.asyncOp(null, keyword("datomic.catalog/delete-db"), m, {
|
|
1282
|
+
dbName: m.dbName,
|
|
1283
|
+
});
|
|
1061
1284
|
};
|
|
1062
1285
|
|
|
1063
1286
|
function convertSelector(s) {
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
}
|
|
1074
|
-
return transit.map(a);
|
|
1075
|
-
} else if (typeof s == 'string' && s[0] === ':') {
|
|
1076
|
-
return transit.keyword(s.slice(1));
|
|
1077
|
-
} else {
|
|
1078
|
-
return s;
|
|
1287
|
+
if (Array.isArray(s)) {
|
|
1288
|
+
return transit.list(s.map(convertSelector));
|
|
1289
|
+
} else if (typeof s == "object") {
|
|
1290
|
+
let a = [];
|
|
1291
|
+
for (let k in s) {
|
|
1292
|
+
if (s.hasOwnProperty(k)) {
|
|
1293
|
+
a.push(convertSelector(k));
|
|
1294
|
+
a.push(convertSelector(s[k]));
|
|
1295
|
+
}
|
|
1079
1296
|
}
|
|
1297
|
+
return transit.map(a);
|
|
1298
|
+
} else if (typeof s == "string" && s[0] === ":") {
|
|
1299
|
+
return transit.keyword(s.slice(1));
|
|
1300
|
+
} else {
|
|
1301
|
+
return s;
|
|
1302
|
+
}
|
|
1080
1303
|
}
|
|
1081
1304
|
|
|
1082
1305
|
function keyword(v) {
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
} else {
|
|
1089
|
-
return transit.keyword(v);
|
|
1090
|
-
}
|
|
1306
|
+
if (transit.isKeyword(v)) {
|
|
1307
|
+
return v;
|
|
1308
|
+
} else if (typeof v == "string") {
|
|
1309
|
+
if (v[0] === ":") {
|
|
1310
|
+
return transit.keyword(v.slice(1));
|
|
1091
1311
|
} else {
|
|
1092
|
-
|
|
1312
|
+
return transit.keyword(v);
|
|
1093
1313
|
}
|
|
1314
|
+
} else {
|
|
1315
|
+
throw Error("failed to convert value to keyword");
|
|
1316
|
+
}
|
|
1094
1317
|
}
|
|
1095
1318
|
|
|
1096
1319
|
function keywordizeKeys(m) {
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
}
|
|
1107
|
-
return transit.map(a);
|
|
1108
|
-
} else {
|
|
1109
|
-
return m;
|
|
1320
|
+
if (Array.isArray(m)) {
|
|
1321
|
+
return transit.list(m.map(keywordizeKeys));
|
|
1322
|
+
} else if (typeof m == "object") {
|
|
1323
|
+
let a = [];
|
|
1324
|
+
for (let k in m) {
|
|
1325
|
+
if (m.hasOwnProperty(k)) {
|
|
1326
|
+
a.push(keyword(k));
|
|
1327
|
+
a.push(keywordizeKeys(m[k]));
|
|
1328
|
+
}
|
|
1110
1329
|
}
|
|
1330
|
+
return transit.map(a);
|
|
1331
|
+
} else {
|
|
1332
|
+
return m;
|
|
1333
|
+
}
|
|
1111
1334
|
}
|
|
1112
1335
|
|
|
1113
1336
|
function apiToClientRequest(op, requester, m) {
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
}
|
|
1122
|
-
} else if (op.toString() === ':pull') {
|
|
1123
|
-
if (m.eid == null || m.selector == null) {
|
|
1124
|
-
throw Error('invalid request');
|
|
1125
|
-
}
|
|
1126
|
-
} else if (op.toString() === ':datoms') {
|
|
1127
|
-
if ([':eavt', ':aevt', ':avet', ':vaet', 'eavt', 'aevt', 'avet', 'vaet'].indexOf(m.index.toString()) === -1) {
|
|
1128
|
-
throw Error('invalid request');
|
|
1129
|
-
}
|
|
1337
|
+
if (
|
|
1338
|
+
op.toString() === ":datomic.catalog/create-db" ||
|
|
1339
|
+
op.toString() === ":datomic.catalog/delete-db" ||
|
|
1340
|
+
op.toString() === ":connect"
|
|
1341
|
+
) {
|
|
1342
|
+
if (typeof m.dbName != "string") {
|
|
1343
|
+
throw Error("invalid request");
|
|
1130
1344
|
}
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
comps2[0] = tx.convertE(comps[0]);
|
|
1223
|
-
default:
|
|
1224
|
-
}
|
|
1225
|
-
break;
|
|
1226
|
-
}
|
|
1345
|
+
} else if (op.toString() === ":transact" || op.toString() === ":with") {
|
|
1346
|
+
if (!Array.isArray(m.txData) && !(m.txData instanceof jsedn.Vector)) {
|
|
1347
|
+
throw Error("invalid request");
|
|
1348
|
+
}
|
|
1349
|
+
} else if (op.toString() === ":pull") {
|
|
1350
|
+
if (m.eid == null || m.selector == null) {
|
|
1351
|
+
throw Error("invalid request");
|
|
1352
|
+
}
|
|
1353
|
+
} else if (op.toString() === ":datoms") {
|
|
1354
|
+
if (
|
|
1355
|
+
[
|
|
1356
|
+
":eavt",
|
|
1357
|
+
":aevt",
|
|
1358
|
+
":avet",
|
|
1359
|
+
":vaet",
|
|
1360
|
+
"eavt",
|
|
1361
|
+
"aevt",
|
|
1362
|
+
"avet",
|
|
1363
|
+
"vaet",
|
|
1364
|
+
].indexOf(m.index.toString()) === -1
|
|
1365
|
+
) {
|
|
1366
|
+
throw Error("invalid request");
|
|
1367
|
+
}
|
|
1368
|
+
}
|
|
1369
|
+
let request = transit.map();
|
|
1370
|
+
switch (op.toString()) {
|
|
1371
|
+
case ":status":
|
|
1372
|
+
request = transit.map([transit.keyword("database-id"), m.databaseId]);
|
|
1373
|
+
break;
|
|
1374
|
+
case ":datomic.catalog/list-dbs":
|
|
1375
|
+
case ":with-db":
|
|
1376
|
+
case ":db-stats":
|
|
1377
|
+
break;
|
|
1378
|
+
case ":datomic.catalog/resolve-db":
|
|
1379
|
+
case ":datomic.catalog/create-db":
|
|
1380
|
+
case ":datomic.catalog/delete-db":
|
|
1381
|
+
request = transit.map([transit.keyword("db-name"), m.dbName]);
|
|
1382
|
+
break;
|
|
1383
|
+
case ":transact":
|
|
1384
|
+
case ":with":
|
|
1385
|
+
request = transit.map([
|
|
1386
|
+
transit.keyword("tx-id"),
|
|
1387
|
+
transit.uuid(crypto.randomUUID()),
|
|
1388
|
+
transit.keyword("tx-data"),
|
|
1389
|
+
jsToTransit(m.txData),
|
|
1390
|
+
]);
|
|
1391
|
+
break;
|
|
1392
|
+
case ":q":
|
|
1393
|
+
request = transit.map([
|
|
1394
|
+
transit.keyword("offset"),
|
|
1395
|
+
m.offset || 0,
|
|
1396
|
+
transit.keyword("query"),
|
|
1397
|
+
jsToTransit(m.query),
|
|
1398
|
+
transit.keyword("args"),
|
|
1399
|
+
jsToTransit(m.args),
|
|
1400
|
+
transit.keyword("timeout"),
|
|
1401
|
+
m.timeout || 60000,
|
|
1402
|
+
transit.keyword("limit"),
|
|
1403
|
+
m.limit || 1000,
|
|
1404
|
+
transit.keyword("chunk"),
|
|
1405
|
+
m.chunk || 1000,
|
|
1406
|
+
]);
|
|
1407
|
+
break;
|
|
1408
|
+
case ":tx-range":
|
|
1409
|
+
request = transit.map([
|
|
1410
|
+
transit.keyword("offset"),
|
|
1411
|
+
m.offset || 0,
|
|
1412
|
+
transit.keyword("start"),
|
|
1413
|
+
m.start || null,
|
|
1414
|
+
transit.keyword("end"),
|
|
1415
|
+
m.end || null,
|
|
1416
|
+
]);
|
|
1417
|
+
break;
|
|
1418
|
+
case ":datoms":
|
|
1419
|
+
let index = keyword(m.index);
|
|
1420
|
+
let comps = m.components;
|
|
1421
|
+
if (comps !== undefined) {
|
|
1422
|
+
let comps2 = new Array(comps.length);
|
|
1423
|
+
switch (index.toString()) {
|
|
1424
|
+
case ":eavt":
|
|
1425
|
+
switch (comps.length) {
|
|
1426
|
+
case 4:
|
|
1427
|
+
comps2[3] = tx.bigInt(comps[3]);
|
|
1428
|
+
case 3:
|
|
1429
|
+
comps2[2] = tx.convertV(comps[2]);
|
|
1430
|
+
case 2:
|
|
1431
|
+
comps2[1] = keyword(comps[1]);
|
|
1432
|
+
case 1:
|
|
1433
|
+
comps2[0] = tx.convertE(comps[0]);
|
|
1434
|
+
default:
|
|
1435
|
+
break;
|
|
1227
1436
|
}
|
|
1228
|
-
request = transit.map([
|
|
1229
|
-
keyword('index'), keyword(m.index),
|
|
1230
|
-
keyword('components'), comps,
|
|
1231
|
-
keyword('timeout'), m.timeout || 60000,
|
|
1232
|
-
keyword('chunk'), m.chunk || 1000,
|
|
1233
|
-
keyword('limit'), m.limit || 1000,
|
|
1234
|
-
keyword('offset'), m.offset || 0,
|
|
1235
|
-
]);
|
|
1236
1437
|
break;
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1438
|
+
case ":aevt":
|
|
1439
|
+
switch (comps.length) {
|
|
1440
|
+
case 4:
|
|
1441
|
+
comps2[3] = tx.bigInt(comps[3]);
|
|
1442
|
+
case 3:
|
|
1443
|
+
comps2[2] = tx.convertV(comps[2]);
|
|
1444
|
+
case 2:
|
|
1445
|
+
comps2[1] = tx.convertE(comps[1]);
|
|
1446
|
+
case 1:
|
|
1447
|
+
comps2[0] = keyword(comps[0]);
|
|
1448
|
+
default:
|
|
1449
|
+
}
|
|
1244
1450
|
break;
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1451
|
+
case ":avet":
|
|
1452
|
+
switch (comps.length) {
|
|
1453
|
+
case 4:
|
|
1454
|
+
comps2[3] = tx.bigInt(comps[3]);
|
|
1455
|
+
case 3:
|
|
1456
|
+
comps2[2] = tx.convertE(comps[2]);
|
|
1457
|
+
case 2:
|
|
1458
|
+
comps2[1] = tx.convertV(comps[1]);
|
|
1459
|
+
case 1:
|
|
1460
|
+
comps2[0] = keyword(comps[0]);
|
|
1461
|
+
default:
|
|
1462
|
+
}
|
|
1251
1463
|
break;
|
|
1252
|
-
|
|
1253
|
-
|
|
1464
|
+
case ":vaet":
|
|
1465
|
+
switch (comps.length) {
|
|
1466
|
+
case 4:
|
|
1467
|
+
comps2[3] = tx.bigInt(comps[3]);
|
|
1468
|
+
case 3:
|
|
1469
|
+
comps2[2] = tx.convertE(comps[2]);
|
|
1470
|
+
case 2:
|
|
1471
|
+
comps2[1] = keyword(comps[1]);
|
|
1472
|
+
case 1:
|
|
1473
|
+
comps2[0] = tx.convertE(comps[0]);
|
|
1474
|
+
default:
|
|
1475
|
+
}
|
|
1254
1476
|
break;
|
|
1255
|
-
}
|
|
1256
|
-
request.set(keyword('op'), keyword(op));
|
|
1257
|
-
let requestContext = getRequestContext(requester);
|
|
1258
|
-
for (let k in requestContext) {
|
|
1259
|
-
if (requestContext.hasOwnProperty(k)) {
|
|
1260
|
-
request.set(keywordizeKey(k), requestContext[k]);
|
|
1261
1477
|
}
|
|
1478
|
+
}
|
|
1479
|
+
request = transit.map([
|
|
1480
|
+
keyword("index"),
|
|
1481
|
+
keyword(m.index),
|
|
1482
|
+
keyword("components"),
|
|
1483
|
+
comps,
|
|
1484
|
+
keyword("timeout"),
|
|
1485
|
+
m.timeout || 60000,
|
|
1486
|
+
keyword("chunk"),
|
|
1487
|
+
m.chunk || 1000,
|
|
1488
|
+
keyword("limit"),
|
|
1489
|
+
m.limit || 1000,
|
|
1490
|
+
keyword("offset"),
|
|
1491
|
+
m.offset || 0,
|
|
1492
|
+
]);
|
|
1493
|
+
break;
|
|
1494
|
+
case ":index-range":
|
|
1495
|
+
request = transit.map([
|
|
1496
|
+
transit.keyword("offset"),
|
|
1497
|
+
m.index || 0,
|
|
1498
|
+
transit.keyword("attrid"),
|
|
1499
|
+
keyword(m.attrid),
|
|
1500
|
+
transit.keyword("start"),
|
|
1501
|
+
m.start || null,
|
|
1502
|
+
transit.keyword("end"),
|
|
1503
|
+
m.end || null,
|
|
1504
|
+
]);
|
|
1505
|
+
break;
|
|
1506
|
+
case ":pull":
|
|
1507
|
+
request = transit.map([
|
|
1508
|
+
keyword("eid"),
|
|
1509
|
+
tx.convertE(m.eid),
|
|
1510
|
+
keyword("selector"),
|
|
1511
|
+
jsToTransit(m.selector),
|
|
1512
|
+
keyword("timeout", m.timeout || 60000),
|
|
1513
|
+
]);
|
|
1514
|
+
break;
|
|
1515
|
+
case ":next":
|
|
1516
|
+
request = jsToTransit(m);
|
|
1517
|
+
break;
|
|
1518
|
+
}
|
|
1519
|
+
request.set(keyword("op"), keyword(op));
|
|
1520
|
+
let requestContext = getRequestContext(requester);
|
|
1521
|
+
for (let k in requestContext) {
|
|
1522
|
+
if (requestContext.hasOwnProperty(k)) {
|
|
1523
|
+
request.set(keywordizeKey(k), requestContext[k]);
|
|
1262
1524
|
}
|
|
1263
|
-
|
|
1525
|
+
}
|
|
1526
|
+
return request;
|
|
1264
1527
|
}
|
|
1265
1528
|
|
|
1266
1529
|
function clientRequestToHttpRequest(request) {
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1530
|
+
let writer = transit.writer("json");
|
|
1531
|
+
let encoded = writer.write(request);
|
|
1532
|
+
let contentType = "application/transit+json";
|
|
1533
|
+
let op = request.get(keyword("op"));
|
|
1534
|
+
let qualifiedOp = "datomic.client.protocol/" + op.name();
|
|
1535
|
+
if (op.namespace() === "datomic.catalog") {
|
|
1536
|
+
qualifiedOp = op.namespace() + "/" + op.name();
|
|
1537
|
+
}
|
|
1538
|
+
let headers = {
|
|
1539
|
+
"content-type": contentType,
|
|
1540
|
+
accept: contentType,
|
|
1541
|
+
"x-nano-op": qualifiedOp,
|
|
1542
|
+
"content-length": Buffer.byteLength(encoded),
|
|
1543
|
+
};
|
|
1544
|
+
let nextToken = request.get(keyword("next-token"));
|
|
1545
|
+
if (nextToken !== undefined) {
|
|
1546
|
+
headers["x-nano-next"] = nextToken.toString();
|
|
1547
|
+
}
|
|
1548
|
+
let databaseId = request.get(keyword("database-id"));
|
|
1549
|
+
if (databaseId !== undefined) {
|
|
1550
|
+
headers["x-nano-target"] = databaseId;
|
|
1551
|
+
}
|
|
1552
|
+
return {
|
|
1553
|
+
headers: headers,
|
|
1554
|
+
method: "post",
|
|
1555
|
+
body: encoded,
|
|
1556
|
+
op: qualifiedOp,
|
|
1557
|
+
};
|
|
1295
1558
|
}
|
|
1296
1559
|
|
|
1297
1560
|
function makeClient(spi) {
|
|
1298
|
-
|
|
1561
|
+
return new Client(spi);
|
|
1299
1562
|
}
|
|
1300
1563
|
|
|
1301
1564
|
function makeConnection(spi, args) {
|
|
1302
|
-
|
|
1565
|
+
return makeClient(spi).connect(args);
|
|
1303
1566
|
}
|
|
1304
1567
|
|
|
1305
1568
|
function makeUuid(s) {
|
|
1306
|
-
|
|
1569
|
+
return new UUID(s);
|
|
1307
1570
|
}
|
|
1308
1571
|
|
|
1309
1572
|
function randomUuid() {
|
|
1310
|
-
|
|
1573
|
+
return new UUID(crypto.randomUUID());
|
|
1311
1574
|
}
|
|
1312
1575
|
|
|
1313
1576
|
exports.makeClient = makeClient;
|
|
@@ -1319,4 +1582,4 @@ exports.canonicalRequestStr = canonicalRequestStr;
|
|
|
1319
1582
|
|
|
1320
1583
|
exports.UUID = UUID;
|
|
1321
1584
|
exports.BigInt = BigInt;
|
|
1322
|
-
exports.BigDec = BigDec;
|
|
1585
|
+
exports.BigDec = BigDec;
|