@aztec/foundation 0.86.0 → 0.87.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.
Files changed (216) hide show
  1. package/dest/array/array.d.ts.map +1 -1
  2. package/dest/bigint/index.d.ts +2 -0
  3. package/dest/bigint/index.d.ts.map +1 -1
  4. package/dest/bigint/index.js +6 -0
  5. package/dest/bigint-buffer/index.d.ts +0 -2
  6. package/dest/bigint-buffer/index.d.ts.map +1 -1
  7. package/dest/buffer/buffer16.d.ts +80 -0
  8. package/dest/buffer/buffer16.d.ts.map +1 -0
  9. package/dest/buffer/buffer16.js +100 -0
  10. package/dest/buffer/buffer32.d.ts +3 -7
  11. package/dest/buffer/buffer32.d.ts.map +1 -1
  12. package/dest/buffer/buffer32.js +6 -6
  13. package/dest/buffer/index.d.ts +1 -0
  14. package/dest/buffer/index.d.ts.map +1 -1
  15. package/dest/buffer/index.js +1 -0
  16. package/dest/collection/array.d.ts +0 -2
  17. package/dest/collection/array.d.ts.map +1 -1
  18. package/dest/collection/object.d.ts +2 -0
  19. package/dest/collection/object.d.ts.map +1 -1
  20. package/dest/collection/object.js +8 -0
  21. package/dest/config/env_var.d.ts +1 -1
  22. package/dest/config/env_var.d.ts.map +1 -1
  23. package/dest/crypto/aes128/index.d.ts +2 -4
  24. package/dest/crypto/aes128/index.d.ts.map +1 -1
  25. package/dest/crypto/ecdsa/index.d.ts +0 -2
  26. package/dest/crypto/ecdsa/index.d.ts.map +1 -1
  27. package/dest/crypto/ecdsa/signature.d.ts +1 -3
  28. package/dest/crypto/ecdsa/signature.d.ts.map +1 -1
  29. package/dest/crypto/grumpkin/index.d.ts +0 -2
  30. package/dest/crypto/grumpkin/index.d.ts.map +1 -1
  31. package/dest/crypto/keccak/index.d.ts +2 -4
  32. package/dest/crypto/keccak/index.d.ts.map +1 -1
  33. package/dest/crypto/keys/index.d.ts +0 -2
  34. package/dest/crypto/keys/index.d.ts.map +1 -1
  35. package/dest/crypto/pedersen/pedersen.noble.d.ts +2 -4
  36. package/dest/crypto/pedersen/pedersen.noble.d.ts.map +1 -1
  37. package/dest/crypto/pedersen/pedersen.wasm.d.ts +2 -4
  38. package/dest/crypto/pedersen/pedersen.wasm.d.ts.map +1 -1
  39. package/dest/crypto/poseidon/index.d.ts +0 -2
  40. package/dest/crypto/poseidon/index.d.ts.map +1 -1
  41. package/dest/crypto/random/index.d.ts +1 -3
  42. package/dest/crypto/random/index.d.ts.map +1 -1
  43. package/dest/crypto/random/randomness_singleton.d.ts +0 -2
  44. package/dest/crypto/random/randomness_singleton.d.ts.map +1 -1
  45. package/dest/crypto/schnorr/signature.d.ts +3 -5
  46. package/dest/crypto/schnorr/signature.d.ts.map +1 -1
  47. package/dest/crypto/secp256k1/index.d.ts +4 -6
  48. package/dest/crypto/secp256k1/index.d.ts.map +1 -1
  49. package/dest/crypto/secp256k1-signer/utils.d.ts +0 -2
  50. package/dest/crypto/secp256k1-signer/utils.d.ts.map +1 -1
  51. package/dest/crypto/serialize.d.ts +4 -6
  52. package/dest/crypto/serialize.d.ts.map +1 -1
  53. package/dest/crypto/sha256/index.d.ts +2 -4
  54. package/dest/crypto/sha256/index.d.ts.map +1 -1
  55. package/dest/crypto/sha512/index.d.ts +1 -3
  56. package/dest/crypto/sha512/index.d.ts.map +1 -1
  57. package/dest/crypto/signature/index.d.ts +0 -2
  58. package/dest/crypto/signature/index.d.ts.map +1 -1
  59. package/dest/crypto/sync/pedersen/index.d.ts +2 -4
  60. package/dest/crypto/sync/pedersen/index.d.ts.map +1 -1
  61. package/dest/crypto/sync/poseidon/index.d.ts +0 -2
  62. package/dest/crypto/sync/poseidon/index.d.ts.map +1 -1
  63. package/dest/decorators/memoize.d.ts.map +1 -1
  64. package/dest/eth-address/index.d.ts +2 -5
  65. package/dest/eth-address/index.d.ts.map +1 -1
  66. package/dest/eth-signature/eth_signature.d.ts +0 -2
  67. package/dest/eth-signature/eth_signature.d.ts.map +1 -1
  68. package/dest/fields/coordinate.d.ts +0 -2
  69. package/dest/fields/coordinate.d.ts.map +1 -1
  70. package/dest/fields/fields.d.ts +0 -3
  71. package/dest/fields/fields.d.ts.map +1 -1
  72. package/dest/fields/point.d.ts +2 -4
  73. package/dest/fields/point.d.ts.map +1 -1
  74. package/dest/fields/point.js +2 -2
  75. package/dest/iterable/filter.js +1 -1
  76. package/dest/iterable/map.js +1 -1
  77. package/dest/json-rpc/client/fetch.d.ts +2 -2
  78. package/dest/json-rpc/client/fetch.d.ts.map +1 -1
  79. package/dest/json-rpc/client/fetch.js +16 -30
  80. package/dest/json-rpc/client/safe_json_rpc_client.d.ts +7 -3
  81. package/dest/json-rpc/client/safe_json_rpc_client.d.ts.map +1 -1
  82. package/dest/json-rpc/client/safe_json_rpc_client.js +135 -13
  83. package/dest/json-rpc/client/undici.d.ts.map +1 -1
  84. package/dest/json-rpc/client/undici.js +6 -7
  85. package/dest/json-rpc/convert.d.ts +1 -1
  86. package/dest/json-rpc/convert.d.ts.map +1 -1
  87. package/dest/json-rpc/convert.js +1 -1
  88. package/dest/json-rpc/errors.d.ts +4 -0
  89. package/dest/json-rpc/errors.d.ts.map +1 -0
  90. package/dest/json-rpc/errors.js +6 -0
  91. package/dest/json-rpc/fixtures/class_a.d.ts +5 -3
  92. package/dest/json-rpc/fixtures/class_a.d.ts.map +1 -1
  93. package/dest/json-rpc/fixtures/class_b.d.ts +5 -3
  94. package/dest/json-rpc/fixtures/class_b.d.ts.map +1 -1
  95. package/dest/json-rpc/index.d.ts +1 -0
  96. package/dest/json-rpc/index.d.ts.map +1 -1
  97. package/dest/json-rpc/index.js +1 -0
  98. package/dest/json-rpc/js_utils.d.ts.map +1 -1
  99. package/dest/json-rpc/server/safe_json_rpc_server.d.ts +2 -1
  100. package/dest/json-rpc/server/safe_json_rpc_server.d.ts.map +1 -1
  101. package/dest/json-rpc/server/safe_json_rpc_server.js +112 -39
  102. package/dest/json-rpc/test/integration.d.ts +0 -1
  103. package/dest/json-rpc/test/integration.d.ts.map +1 -1
  104. package/dest/log/console.d.ts.map +1 -1
  105. package/dest/log/gcloud-logger-config.d.ts.map +1 -1
  106. package/dest/log/gcloud-logger-config.js +0 -4
  107. package/dest/log/pino-logger.d.ts +1 -2
  108. package/dest/log/pino-logger.d.ts.map +1 -1
  109. package/dest/message/index.d.ts.map +1 -1
  110. package/dest/mutex/mutex_database.d.ts.map +1 -1
  111. package/dest/queue/bounded_serial_queue.d.ts.map +1 -1
  112. package/dest/schemas/api.d.ts.map +1 -1
  113. package/dest/schemas/parse.js +1 -1
  114. package/dest/schemas/schemas.d.ts +3 -5
  115. package/dest/schemas/schemas.d.ts.map +1 -1
  116. package/dest/schemas/utils.d.ts +1 -3
  117. package/dest/schemas/utils.d.ts.map +1 -1
  118. package/dest/serialize/buffer_reader.d.ts +9 -2
  119. package/dest/serialize/buffer_reader.d.ts.map +1 -1
  120. package/dest/serialize/buffer_reader.js +15 -2
  121. package/dest/serialize/field_reader.d.ts +2 -1
  122. package/dest/serialize/field_reader.d.ts.map +1 -1
  123. package/dest/serialize/field_reader.js +4 -1
  124. package/dest/serialize/free_funcs.d.ts +15 -9
  125. package/dest/serialize/free_funcs.d.ts.map +1 -1
  126. package/dest/serialize/free_funcs.js +11 -0
  127. package/dest/serialize/serialize.d.ts +3 -5
  128. package/dest/serialize/serialize.d.ts.map +1 -1
  129. package/dest/string/index.d.ts +2 -2
  130. package/dest/string/index.d.ts.map +1 -1
  131. package/dest/string/index.js +6 -0
  132. package/dest/testing/files/index.d.ts +0 -2
  133. package/dest/testing/files/index.d.ts.map +1 -1
  134. package/dest/timer/timeout.d.ts.map +1 -1
  135. package/dest/transport/dispatch/create_dispatch_fn.d.ts.map +1 -1
  136. package/dest/transport/interface/connector.d.ts.map +1 -1
  137. package/dest/transport/interface/listener.d.ts +0 -1
  138. package/dest/transport/interface/listener.d.ts.map +1 -1
  139. package/dest/transport/interface/socket.d.ts.map +1 -1
  140. package/dest/transport/node/node_connector.d.ts +0 -1
  141. package/dest/transport/node/node_connector.d.ts.map +1 -1
  142. package/dest/transport/node/node_connector_socket.d.ts +0 -1
  143. package/dest/transport/node/node_connector_socket.d.ts.map +1 -1
  144. package/dest/transport/node/node_listener.d.ts +0 -1
  145. package/dest/transport/node/node_listener.d.ts.map +1 -1
  146. package/dest/transport/node/node_listener_socket.d.ts +0 -1
  147. package/dest/transport/node/node_listener_socket.d.ts.map +1 -1
  148. package/dest/transport/transport_client.d.ts +0 -1
  149. package/dest/transport/transport_client.d.ts.map +1 -1
  150. package/dest/transport/transport_server.d.ts.map +1 -1
  151. package/dest/trees/hasher.d.ts +4 -6
  152. package/dest/trees/hasher.d.ts.map +1 -1
  153. package/dest/trees/indexed_merkle_tree.d.ts +0 -2
  154. package/dest/trees/indexed_merkle_tree.d.ts.map +1 -1
  155. package/dest/trees/indexed_merkle_tree_calculator.d.ts +1 -3
  156. package/dest/trees/indexed_merkle_tree_calculator.d.ts.map +1 -1
  157. package/dest/trees/indexed_tree_leaf.d.ts +0 -2
  158. package/dest/trees/indexed_tree_leaf.d.ts.map +1 -1
  159. package/dest/trees/membership_witness.d.ts +1 -3
  160. package/dest/trees/membership_witness.d.ts.map +1 -1
  161. package/dest/trees/merkle_tree.d.ts +0 -2
  162. package/dest/trees/merkle_tree.d.ts.map +1 -1
  163. package/dest/trees/merkle_tree_calculator.d.ts +1 -3
  164. package/dest/trees/merkle_tree_calculator.d.ts.map +1 -1
  165. package/dest/trees/sibling_path.d.ts +6 -8
  166. package/dest/trees/sibling_path.d.ts.map +1 -1
  167. package/dest/trees/unbalanced_merkle_tree.d.ts +0 -2
  168. package/dest/trees/unbalanced_merkle_tree.d.ts.map +1 -1
  169. package/dest/types/index.d.ts +0 -2
  170. package/dest/types/index.d.ts.map +1 -1
  171. package/dest/url/index.d.ts.map +1 -1
  172. package/dest/url/index.js +1 -1
  173. package/package.json +16 -15
  174. package/src/bigint/index.ts +8 -0
  175. package/src/buffer/buffer16.ts +133 -0
  176. package/src/buffer/buffer32.ts +8 -6
  177. package/src/buffer/index.ts +1 -0
  178. package/src/collection/object.ts +10 -0
  179. package/src/config/env_var.ts +13 -3
  180. package/src/fields/point.ts +0 -2
  181. package/src/iterable/filter.ts +1 -1
  182. package/src/iterable/map.ts +1 -1
  183. package/src/json-rpc/client/fetch.ts +14 -33
  184. package/src/json-rpc/client/safe_json_rpc_client.ts +171 -13
  185. package/src/json-rpc/client/undici.ts +6 -13
  186. package/src/json-rpc/convert.ts +2 -2
  187. package/src/json-rpc/errors.ts +6 -0
  188. package/src/json-rpc/fixtures/class_a.ts +4 -1
  189. package/src/json-rpc/fixtures/class_b.ts +4 -1
  190. package/src/json-rpc/index.ts +1 -0
  191. package/src/json-rpc/server/safe_json_rpc_server.ts +78 -25
  192. package/src/log/console.ts +4 -1
  193. package/src/log/gcloud-logger-config.ts +2 -2
  194. package/src/log/pino-logger.ts +2 -2
  195. package/src/message/index.ts +5 -1
  196. package/src/mutex/mutex_database.ts +2 -3
  197. package/src/queue/bounded_serial_queue.ts +4 -1
  198. package/src/schemas/api.ts +4 -4
  199. package/src/schemas/parse.ts +1 -1
  200. package/src/serialize/buffer_reader.ts +23 -3
  201. package/src/serialize/field_reader.ts +11 -3
  202. package/src/serialize/free_funcs.ts +13 -0
  203. package/src/string/index.ts +9 -1
  204. package/src/timer/timeout.ts +5 -1
  205. package/src/transport/interface/connector.ts +0 -1
  206. package/src/transport/interface/listener.ts +2 -3
  207. package/src/transport/interface/socket.ts +2 -3
  208. package/src/transport/transport_client.ts +3 -4
  209. package/src/transport/transport_server.ts +4 -1
  210. package/src/trees/hasher.ts +4 -4
  211. package/src/trees/indexed_merkle_tree.ts +5 -1
  212. package/src/trees/indexed_merkle_tree_calculator.ts +2 -2
  213. package/src/trees/merkle_tree.ts +4 -1
  214. package/src/trees/merkle_tree_calculator.ts +8 -3
  215. package/src/types/index.ts +0 -5
  216. package/src/url/index.ts +0 -1
@@ -1,20 +1,108 @@
1
1
  import { format } from 'util';
2
2
  import { createLogger } from '../../log/pino-logger.js';
3
+ import { promiseWithResolvers } from '../../promise/utils.js';
3
4
  import { schemaHasMethod } from '../../schemas/api.js';
4
5
  import { defaultFetch } from './fetch.js';
6
+ // batch window of 0 would capture all requests in the current sync iteration of the event loop
7
+ // and send them all at once in a single batch
8
+ // minimal latency
9
+ const DEFAULT_BATCH_WINDOW_MS = 0;
10
+ // expose helpful information on the RPC clients such that we can recognize them later
11
+ const SEND_BATCH = Symbol('JsonRpcClient.sendBatch');
12
+ const CLIENT_ID = Symbol('JsonRpcClient.clientId');
13
+ let nextClientId = 1;
14
+ // keep a reference to clients so that we can force send a batch
15
+ const clients = new Map();
5
16
  /**
6
17
  * Creates a Proxy object that delegates over RPC and validates outputs against a given schema.
7
18
  * The server is expected to be a JsonRpcServer.
8
19
  * @param host - The host URL.
9
20
  * @param schema - The api schema to validate returned data against.
10
- * @param useApiEndpoints - Whether to use the API endpoints or the default RPC endpoint.
11
- * @param namespaceMethods - String value (or false/empty) to namespace all methods sent to the server. e.g. 'getInfo' -\> 'pxe_getInfo'
12
21
  * @param fetch - The fetch implementation to use.
13
22
  */ export function createSafeJsonRpcClient(host, schema, config = {}) {
14
23
  const fetch = config.fetch ?? defaultFetch;
15
24
  const log = config.log ?? createLogger('json-rpc:client');
16
- const { useApiEndpoints = false, namespaceMethods = false } = config;
25
+ const { namespaceMethods = false, batchWindowMS = DEFAULT_BATCH_WINDOW_MS } = config;
17
26
  let id = 0;
27
+ let sendBatchTimeoutHandle;
28
+ let queue = [];
29
+ const sendBatch = async ()=>{
30
+ if (sendBatchTimeoutHandle !== undefined) {
31
+ clearTimeout(sendBatchTimeoutHandle);
32
+ sendBatchTimeoutHandle = undefined;
33
+ }
34
+ const rpcCalls = queue;
35
+ queue = [];
36
+ if (rpcCalls.length === 0) {
37
+ return;
38
+ }
39
+ log.debug(`Executing JSON-RPC batch of size: ${rpcCalls.length}`, {
40
+ methods: rpcCalls.map(({ request })=>request.method)
41
+ });
42
+ try {
43
+ const { response, headers } = await fetch(host, rpcCalls.map(({ request })=>request));
44
+ if (config.onResponse) {
45
+ await config.onResponse({
46
+ response,
47
+ headers
48
+ });
49
+ }
50
+ if (!Array.isArray(response) || response.length !== rpcCalls.length) {
51
+ log.warn(`Invalid response received from JSON-RPC server. Expected array of responses of length ${rpcCalls.length}`, {
52
+ response
53
+ });
54
+ for(let i = 0; i < rpcCalls.length; i++){
55
+ const { request, deferred } = rpcCalls[i];
56
+ deferred.resolve({
57
+ id: request.id,
58
+ jsonrpc: '2.0',
59
+ error: {
60
+ code: -32000,
61
+ data: response,
62
+ message: response.message ?? 'Failed request'
63
+ }
64
+ });
65
+ }
66
+ } else {
67
+ for(let i = 0; i < response.length; i++){
68
+ const resp = response[i];
69
+ const { request, deferred } = rpcCalls[i];
70
+ if (resp.id !== request.id) {
71
+ log.warn(`Invalid response received at index ${i} from JSON-RPC server: id mismatch`, {
72
+ requestMethod: request.method,
73
+ requestId: request.id,
74
+ responseId: resp.id
75
+ });
76
+ deferred.resolve({
77
+ id: request.id,
78
+ jsonrpc: '2.0',
79
+ error: {
80
+ code: -32001,
81
+ data: resp,
82
+ message: 'RPC id mismatch'
83
+ }
84
+ });
85
+ } else {
86
+ deferred.resolve(resp);
87
+ }
88
+ }
89
+ }
90
+ } catch (err) {
91
+ log.warn(`Failed to fetch from the remote server`, err);
92
+ for(let i = 0; i < rpcCalls.length; i++){
93
+ const { request, deferred } = rpcCalls[i];
94
+ deferred.resolve({
95
+ id: request.id,
96
+ jsonrpc: '2.0',
97
+ error: {
98
+ code: -32000,
99
+ data: err,
100
+ message: err.message ?? 'Failed request'
101
+ }
102
+ });
103
+ }
104
+ }
105
+ };
18
106
  const request = async (methodName, params)=>{
19
107
  if (!schemaHasMethod(schema, methodName)) {
20
108
  throw new Error(`Unspecified method ${methodName} in client schema`);
@@ -26,18 +114,23 @@ import { defaultFetch } from './fetch.js';
26
114
  method,
27
115
  params
28
116
  };
117
+ const deferred = promiseWithResolvers();
118
+ queue.push({
119
+ request: body,
120
+ deferred
121
+ });
122
+ if (sendBatchTimeoutHandle === undefined) {
123
+ // eslint-disable-next-line @typescript-eslint/no-misused-promises
124
+ sendBatchTimeoutHandle = setTimeout(sendBatch, batchWindowMS);
125
+ }
29
126
  log.debug(format(`request`, method, params));
30
- const { response, headers } = await fetch(host, method, body, useApiEndpoints);
127
+ const response = await deferred.promise;
31
128
  log.debug(format(`result`, method, response));
32
- if (config.onResponse) {
33
- await config.onResponse({
34
- response,
35
- headers
129
+ if ('error' in response) {
130
+ throw new Error(response.error.message, {
131
+ cause: response.error
36
132
  });
37
133
  }
38
- if (response.error) {
39
- throw response.error;
40
- }
41
134
  // TODO(palla/schemas): Find a better way to handle null responses (JSON.stringify(null) is string "null").
42
135
  if ([
43
136
  null,
@@ -49,9 +142,38 @@ import { defaultFetch } from './fetch.js';
49
142
  }
50
143
  return schema[methodName].returnType().parseAsync(response.result);
51
144
  };
52
- const proxy = {};
145
+ const clientId = nextClientId++;
146
+ const proxy = {
147
+ [CLIENT_ID]: clientId,
148
+ [SEND_BATCH]: sendBatch
149
+ };
53
150
  for (const method of Object.keys(schema)){
54
- proxy[method] = (...params)=>request(method, params);
151
+ // attach the clientId to the promise so that if we want to trigger a batch immediately, we can do that
152
+ proxy[method] = (...params)=>Object.assign(request(method, params), {
153
+ [CLIENT_ID]: clientId
154
+ });
55
155
  }
156
+ clients.set(clientId, new WeakRef(proxy));
56
157
  return proxy;
57
158
  }
159
+ /**
160
+ * Triggers a batch to be sent immediately
161
+ */ export async function batch(values) {
162
+ const clientIdsSeen = new Set();
163
+ await Promise.allSettled(values.map((val)=>{
164
+ if (typeof val === 'object' && val && Object.hasOwn(val, CLIENT_ID)) {
165
+ const clientId = val[CLIENT_ID];
166
+ if (typeof clientId === 'number') {
167
+ if (clientIdsSeen.has(clientId)) {
168
+ return;
169
+ }
170
+ clientIdsSeen.add(clientId);
171
+ const client = clients.get(clientId)?.deref();
172
+ if (client) {
173
+ return client[SEND_BATCH]();
174
+ }
175
+ }
176
+ }
177
+ }));
178
+ return Promise.all(values);
179
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"undici.d.ts","sourceRoot":"","sources":["../../../src/json-rpc/client/undici.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAmB,MAAM,QAAQ,CAAC;AAKhD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAI/C,OAAO,EAAE,KAAK,EAAE,CAAC;AAEjB,wBAAgB,eAAe,CAAC,MAAM,QAAc,GAAG,YAAY,CA+DlE"}
1
+ {"version":3,"file":"undici.d.ts","sourceRoot":"","sources":["../../../src/json-rpc/client/undici.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAmB,MAAM,QAAQ,CAAC;AAKhD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAI/C,OAAO,EAAE,KAAK,EAAE,CAAC;AAEjB,wBAAgB,eAAe,CAAC,MAAM,QAAc,GAAG,YAAY,CAwDlE"}
@@ -5,10 +5,9 @@ import { jsonStringify } from '../convert.js';
5
5
  const log = createLogger('json-rpc:json_rpc_client:undici');
6
6
  export { Agent };
7
7
  export function makeUndiciFetch(client = new Agent()) {
8
- return async (host, rpcMethod, body, useApiEndpoints, extraHeaders = {}, noRetry = false)=>{
9
- log.trace(`JsonRpcClient.fetch: ${host} ${rpcMethod}`, {
8
+ return async (host, body, extraHeaders = {}, noRetry = false)=>{
9
+ log.trace(`JsonRpcClient.fetch: ${host}`, {
10
10
  host,
11
- rpcMethod,
12
11
  body
13
12
  });
14
13
  let resp;
@@ -16,7 +15,7 @@ export function makeUndiciFetch(client = new Agent()) {
16
15
  resp = await client.request({
17
16
  method: 'POST',
18
17
  origin: new URL(host),
19
- path: useApiEndpoints ? rpcMethod : '/',
18
+ path: '/',
20
19
  body: jsonStringify(body),
21
20
  headers: {
22
21
  ...extraHeaders,
@@ -24,21 +23,21 @@ export function makeUndiciFetch(client = new Agent()) {
24
23
  }
25
24
  });
26
25
  } catch (err) {
27
- const errorMessage = `Error fetching from host ${host} with method ${rpcMethod}: ${String(err)}`;
26
+ const errorMessage = `Error fetching from host ${host}: ${String(err)}`;
28
27
  throw new Error(errorMessage);
29
28
  }
30
29
  let responseJson;
31
30
  const responseOk = resp.statusCode >= 200 && resp.statusCode <= 299;
32
31
  try {
33
32
  responseJson = await resp.body.json();
34
- } catch (err) {
33
+ } catch {
35
34
  if (!responseOk) {
36
35
  throw new Error('HTTP ' + resp.statusCode);
37
36
  }
38
37
  throw new Error(`Failed to parse body as JSON: ${await resp.body.text()}`);
39
38
  }
40
39
  if (!responseOk) {
41
- const errorMessage = `Error ${resp.statusCode} response from server ${host} on ${rpcMethod}: ${responseJson.error.message}`;
40
+ const errorMessage = `Error ${resp.statusCode} response from server ${host}: ${responseJson}`;
42
41
  if (noRetry || resp.statusCode >= 400 && resp.statusCode < 500) {
43
42
  throw new NoRetryError(errorMessage);
44
43
  } else {
@@ -18,7 +18,7 @@ export declare function jsonParseWithSchemaSync<T>(json: string, schema: ZodFor<
18
18
  * @param obj - The object to be stringified.
19
19
  * @returns The resulting string.
20
20
  */
21
- export declare function jsonStringify(obj: object, prettify?: boolean): string;
21
+ export declare function jsonStringify(obj: unknown, prettify?: boolean): string;
22
22
  /**
23
23
  * Calls jsonStringify but swallows errors.
24
24
  * Use for logging, when you don't want to potentially introduce another thing that throws.
@@ -1 +1 @@
1
- {"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../../src/json-rpc/convert.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAElD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAElF;AACD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAE7E;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAoBrE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAMjF"}
1
+ {"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../../src/json-rpc/convert.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAElD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAElF;AACD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAE7E;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAoBtE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAMjF"}
@@ -42,7 +42,7 @@ import { Buffer } from 'buffer';
42
42
  */ export function tryJsonStringify(obj, prettify) {
43
43
  try {
44
44
  return jsonStringify(obj, prettify);
45
- } catch (e) {
45
+ } catch {
46
46
  return undefined;
47
47
  }
48
48
  }
@@ -0,0 +1,4 @@
1
+ export declare class BadRequestError extends Error {
2
+ constructor(message: string);
3
+ }
4
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/json-rpc/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,eAAgB,SAAQ,KAAK;gBAC5B,OAAO,EAAE,MAAM;CAI5B"}
@@ -0,0 +1,6 @@
1
+ export class BadRequestError extends Error {
2
+ constructor(message){
3
+ super(message);
4
+ this.name = 'BadRequestError';
5
+ }
6
+ }
@@ -2,9 +2,11 @@
2
2
  * Test class for testing string converter.
3
3
  */
4
4
  export declare class ToStringClass {
5
- readonly x: string;
6
- readonly y: string;
7
- constructor(/** A value */ x: string, /** Another value */ y: string);
5
+ /** A value */ readonly x: string;
6
+ /** Another value */ readonly y: string;
7
+ constructor(
8
+ /** A value */ x: string,
9
+ /** Another value */ y: string);
8
10
  toString(): string;
9
11
  static fromString(value: string): ToStringClass;
10
12
  }
@@ -1 +1 @@
1
- {"version":3,"file":"class_a.d.ts","sourceRoot":"","sources":["../../../src/json-rpc/fixtures/class_a.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,aAAa;aACmB,CAAC,EAAE,MAAM;aAAuC,CAAC,EAAE,MAAM;gBAAxF,cAAc,CAAiB,CAAC,EAAE,MAAM,EAAE,oBAAoB,CAAiB,CAAC,EAAE,MAAM;IAEpG,QAAQ,IAAI,MAAM;IAIlB,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM;CAIhC"}
1
+ {"version":3,"file":"class_a.d.ts","sourceRoot":"","sources":["../../../src/json-rpc/fixtures/class_a.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,aAAa;IAEtB,cAAc,UAAiB,CAAC,EAAE,MAAM;IACxC,oBAAoB,UAAiB,CAAC,EAAE,MAAM;;IAD9C,cAAc,CAAiB,CAAC,EAAE,MAAM;IACxC,oBAAoB,CAAiB,CAAC,EAAE,MAAM;IAGhD,QAAQ,IAAI,MAAM;IAIlB,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM;CAIhC"}
@@ -2,9 +2,11 @@
2
2
  * Test class for testing string converter.
3
3
  */
4
4
  export declare class ToStringClass {
5
- readonly x: string;
6
- readonly y: string;
7
- constructor(/** A value */ x: string, /** Another value */ y: string);
5
+ /** A value */ readonly x: string;
6
+ /** Another value */ readonly y: string;
7
+ constructor(
8
+ /** A value */ x: string,
9
+ /** Another value */ y: string);
8
10
  toString(): string;
9
11
  static fromString(value: string): ToStringClass;
10
12
  }
@@ -1 +1 @@
1
- {"version":3,"file":"class_b.d.ts","sourceRoot":"","sources":["../../../src/json-rpc/fixtures/class_b.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,aAAa;aACmB,CAAC,EAAE,MAAM;aAAuC,CAAC,EAAE,MAAM;gBAAxF,cAAc,CAAiB,CAAC,EAAE,MAAM,EAAE,oBAAoB,CAAiB,CAAC,EAAE,MAAM;IAEpG,QAAQ,IAAI,MAAM;IAIlB,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM;CAIhC"}
1
+ {"version":3,"file":"class_b.d.ts","sourceRoot":"","sources":["../../../src/json-rpc/fixtures/class_b.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,aAAa;IAEtB,cAAc,UAAiB,CAAC,EAAE,MAAM;IACxC,oBAAoB,UAAiB,CAAC,EAAE,MAAM;;IAD9C,cAAc,CAAiB,CAAC,EAAE,MAAM;IACxC,oBAAoB,CAAiB,CAAC,EAAE,MAAM;IAGhD,QAAQ,IAAI,MAAM;IAIlB,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM;CAIhC"}
@@ -1,2 +1,3 @@
1
1
  export { jsonStringify, jsonParseWithSchema, jsonParseWithSchemaSync, tryJsonStringify } from './convert.js';
2
+ export { BadRequestError } from './errors.js';
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/json-rpc/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/json-rpc/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC7G,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC"}
@@ -1 +1,2 @@
1
1
  export { jsonStringify, jsonParseWithSchema, jsonParseWithSchemaSync, tryJsonStringify } from './convert.js';
2
+ export { BadRequestError } from './errors.js';
@@ -1 +1 @@
1
- {"version":3,"file":"js_utils.d.ts","sourceRoot":"","sources":["../../src/json-rpc/js_utils.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,eAAO,MAAM,cAAc,QAAS,GAAG,gBAAgB,MAAM,YACJ,CAAC;AAE1D;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAIrD"}
1
+ {"version":3,"file":"js_utils.d.ts","sourceRoot":"","sources":["../../src/json-rpc/js_utils.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,eAAO,MAAM,cAAc,GAAI,KAAK,GAAG,EAAE,cAAc,MAAM,YACJ,CAAC;AAE1D;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAIrD"}
@@ -1,4 +1,3 @@
1
- /// <reference types="node" resolution-mode="require"/>
2
1
  import http from 'http';
3
2
  import { type default as Application } from 'koa';
4
3
  import Router from 'koa-router';
@@ -57,6 +56,8 @@ export declare class SafeJsonRpcServer {
57
56
  * @returns The router object.
58
57
  */
59
58
  private getRouter;
59
+ private processBatch;
60
+ private processRequest;
60
61
  /**
61
62
  * Start this server with koa.
62
63
  * @param port - Port number.
@@ -1 +1 @@
1
- {"version":3,"file":"safe_json_rpc_server.d.ts","sourceRoot":"","sources":["../../../src/json-rpc/server/safe_json_rpc_server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"safe_json_rpc_server.d.ts","sourceRoot":"","sources":["../../../src/json-rpc/server/safe_json_rpc_server.ts"],"names":[],"mappings":"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"}
@@ -45,36 +45,25 @@ export class SafeJsonRpcServer {
45
45
  await next();
46
46
  } catch (err) {
47
47
  const method = ctx.request.body?.method ?? 'unknown';
48
- this.log.warn(`Error in JSON RPC server call ${method}: ${inspect(err)}`);
49
- if (err instanceof SyntaxError) {
48
+ this.log.warn(`Uncaught error in JSON RPC server call ${method}: ${inspect(err)}`);
49
+ if (err && 'name' in err && err.name === 'BadRequestError') {
50
50
  ctx.status = 400;
51
51
  ctx.body = {
52
52
  jsonrpc: '2.0',
53
53
  id: null,
54
54
  error: {
55
- code: -32700,
56
- message: `Parse error: ${err.message}`
55
+ code: -32000,
56
+ message: `Bad request: ${err.message}`
57
57
  }
58
58
  };
59
- } else if (err instanceof ZodError) {
60
- const message = err.issues.map((e)=>`${e.message} (${e.path.join('.')})`).join('. ') || 'Validation error';
59
+ } else if (err && err instanceof SyntaxError) {
61
60
  ctx.status = 400;
62
61
  ctx.body = {
63
62
  jsonrpc: '2.0',
64
63
  id: null,
65
64
  error: {
66
- code: -32701,
67
- message
68
- }
69
- };
70
- } else if (this.http200OnError) {
71
- ctx.body = {
72
- jsonrpc: '2.0',
73
- id: null,
74
- error: {
75
- code: err.code || -32600,
76
- data: err.data,
77
- message: err.message
65
+ code: -32700,
66
+ message: `Parse error: ${err.message}`
78
67
  }
79
68
  };
80
69
  } else {
@@ -141,31 +130,115 @@ export class SafeJsonRpcServer {
141
130
  });
142
131
  // "JSON RPC mode" where a single endpoint is used and the method is given in the request body
143
132
  router.post('/', async (ctx)=>{
144
- const { params = [], jsonrpc, id, method } = ctx.request.body;
145
- // Fail if not a registered function in the proxy
146
- if (typeof method !== 'string' || method === 'constructor' || !this.proxy.hasMethod(method)) {
147
- ctx.status = 400;
148
- const code = -32601;
149
- const message = `Method not found: ${method}`;
150
- ctx.body = {
151
- jsonrpc,
152
- id,
153
- error: {
154
- code,
155
- message
156
- }
157
- };
133
+ if (Array.isArray(ctx.request.body)) {
134
+ const resp = await this.processBatch(ctx.request.body);
135
+ if (Array.isArray(resp)) {
136
+ ctx.status = 200;
137
+ ctx.body = resp;
138
+ } else {
139
+ ctx.status = this.http200OnError ? 200 : 400;
140
+ ctx.body = resp;
141
+ }
158
142
  } else {
159
- ctx.status = 200;
143
+ const resp = await this.processRequest(ctx.request.body);
144
+ if ('error' in resp) {
145
+ ctx.status = this.http200OnError ? 200 : 400;
146
+ }
147
+ ctx.body = resp;
148
+ }
149
+ });
150
+ return router;
151
+ }
152
+ async processBatch(requests) {
153
+ if (requests.length === 0) {
154
+ return {
155
+ jsonrpc: '2.0',
156
+ error: {
157
+ code: -32600,
158
+ message: 'Invalid Request'
159
+ },
160
+ id: null
161
+ };
162
+ }
163
+ const results = await Promise.allSettled(requests.map((req)=>this.processRequest(req)));
164
+ return results.map((res)=>{
165
+ if (res.status === 'fulfilled') {
166
+ return res.value;
167
+ }
168
+ this.log.warn(`Uncaught error executing request in batch: ${res.reason}.`);
169
+ return {
170
+ jsonrpc: '2.0',
171
+ error: {
172
+ code: -32600,
173
+ message: 'Invalid Request'
174
+ },
175
+ id: null
176
+ };
177
+ });
178
+ }
179
+ async processRequest(request) {
180
+ if (!request || typeof request !== 'object') {
181
+ return {
182
+ jsonrpc: '2.0',
183
+ error: {
184
+ code: -32600,
185
+ message: 'Invalid Request'
186
+ },
187
+ id: null
188
+ };
189
+ }
190
+ const { params = [], jsonrpc, id, method } = request;
191
+ // Fail if not a registered function in the proxy
192
+ if (typeof method !== 'string' || method === 'constructor' || !this.proxy.hasMethod(method)) {
193
+ return {
194
+ jsonrpc,
195
+ id,
196
+ error: {
197
+ code: -32601,
198
+ message: `Method not found: ${method}`
199
+ }
200
+ };
201
+ } else {
202
+ try {
160
203
  const result = await this.proxy.call(method, params);
161
- ctx.body = {
204
+ return {
162
205
  jsonrpc,
163
206
  id,
164
207
  result
165
208
  };
209
+ } catch (err) {
210
+ if (err && err instanceof ZodError) {
211
+ const message = err.issues.map((e)=>`${e.message} (${e.path.join('.')})`).join('. ') || 'Validation error';
212
+ return {
213
+ jsonrpc: '2.0',
214
+ id,
215
+ error: {
216
+ code: -32701,
217
+ message
218
+ }
219
+ };
220
+ } else if (err) {
221
+ return {
222
+ jsonrpc,
223
+ id,
224
+ error: {
225
+ code: -32702,
226
+ data: err.data,
227
+ message: err.message
228
+ }
229
+ };
230
+ } else {
231
+ return {
232
+ jsonrpc,
233
+ id,
234
+ error: {
235
+ code: -32702,
236
+ message: 'Error executing request'
237
+ }
238
+ };
239
+ }
166
240
  }
167
- });
168
- return router;
241
+ }
169
242
  }
170
243
  /**
171
244
  * Start this server with koa.
@@ -265,9 +338,9 @@ export function makeHandler(handler, schema) {
265
338
  function makeAggregateHealthcheck(namedHandlers, log) {
266
339
  return async ()=>{
267
340
  try {
268
- const results = await Promise.all(Object.entries(namedHandlers).map(([name, [, , healthCheck]])=>[
341
+ const results = await Promise.all(Object.entries(namedHandlers).map(async ([name, [, , healthCheck]])=>[
269
342
  name,
270
- healthCheck ? healthCheck() : true
343
+ healthCheck ? await healthCheck() : true
271
344
  ]));
272
345
  const failed = results.filter(([_, result])=>!result);
273
346
  if (failed.length > 0) {
@@ -311,7 +384,7 @@ export function createSafeJsonRpcServer(handler, schema, options = {}) {
311
384
  let ok;
312
385
  try {
313
386
  ok = await getCurrentStatus() === true;
314
- } catch (err) {
387
+ } catch {
315
388
  ok = false;
316
389
  }
317
390
  ctx.status = ok ? 200 : 500;
@@ -1,4 +1,3 @@
1
- /// <reference types="node" resolution-mode="require"/>
2
1
  import type http from 'http';
3
2
  import type { ApiSchemaFor } from '../../schemas/api.js';
4
3
  import { type SafeJsonRpcClientOptions } from '../client/safe_json_rpc_client.js';
@@ -1 +1 @@
1
- {"version":3,"file":"integration.d.ts","sourceRoot":"","sources":["../../../src/json-rpc/test/integration.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,OAAO,EAAE,KAAK,wBAAwB,EAA2B,MAAM,mCAAmC,CAAC;AAC3G,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,wBAAwB,EAG9B,MAAM,mCAAmC,CAAC;AAE3C,MAAM,MAAM,kBAAkB,CAAC,CAAC,SAAS,MAAM,IAAI;IACjD,MAAM,EAAE,iBAAiB,CAAC;IAC1B,MAAM,EAAE,CAAC,CAAC;IACV,UAAU,EAAE,IAAI,CAAC,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3C,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,wBAAsB,sBAAsB,CAAC,CAAC,SAAS,MAAM,EAC3D,OAAO,EAAE,CAAC,EACV,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,EACvB,aAAa,GAAE,OAAO,CAAC,wBAAwB,CAAM,EACrD,aAAa,GAAE,wBAA6B,GAC3C,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAUhC"}
1
+ {"version":3,"file":"integration.d.ts","sourceRoot":"","sources":["../../../src/json-rpc/test/integration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,OAAO,EAAE,KAAK,wBAAwB,EAA2B,MAAM,mCAAmC,CAAC;AAC3G,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,wBAAwB,EAG9B,MAAM,mCAAmC,CAAC;AAE3C,MAAM,MAAM,kBAAkB,CAAC,CAAC,SAAS,MAAM,IAAI;IACjD,MAAM,EAAE,iBAAiB,CAAC;IAC1B,MAAM,EAAE,CAAC,CAAC;IACV,UAAU,EAAE,IAAI,CAAC,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3C,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,wBAAsB,sBAAsB,CAAC,CAAC,SAAS,MAAM,EAC3D,OAAO,EAAE,CAAC,EACV,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,EACvB,aAAa,GAAE,OAAO,CAAC,wBAAwB,CAAM,EACrD,aAAa,GAAE,wBAA6B,GAC3C,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAUhC"}
@@ -1 +1 @@
1
- {"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../../src/log/console.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAuBzC;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,CAM1D"}
1
+ {"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../../src/log/console.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AA0BzC;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,CAM1D"}
@@ -1 +1 @@
1
- {"version":3,"file":"gcloud-logger-config.d.ts","sourceRoot":"","sources":["../../src/log/gcloud-logger-config.ts"],"names":[],"mappings":"AAQA;;;;GAIG;AACH,eAAO,MAAM,uBAAuB;;iBAGrB,MAAM;;oBAIL,OAAO,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,MAAM,EAAE,OAAO,CAAC;qBAgBhD,MAAM,SAAS,MAAM,GAAG,MAAM;;CA+BjB,CAAC"}
1
+ {"version":3,"file":"gcloud-logger-config.d.ts","sourceRoot":"","sources":["../../src/log/gcloud-logger-config.ts"],"names":[],"mappings":"AAQA;;;;GAIG;AACH,eAAO,MAAM,uBAAuB;;iBAGrB,MAAM;;oBAIL,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;qBAgBhD,MAAM,SAAS,MAAM,GAAG,MAAM;;CA+BjB,CAAC"}
@@ -60,7 +60,3 @@ const GOOGLE_CLOUD_TRACE_SAMPLED = 'logging.googleapis.com/trace_sampled';
60
60
  }
61
61
  }
62
62
  };
63
- // Define custom logging levels for pino. Duplicate from pino-logger.ts.
64
- const customLevels = {
65
- verbose: 25
66
- };
@@ -1,4 +1,3 @@
1
- /// <reference types="node" resolution-mode="require"/>
2
1
  import type { Writable } from 'stream';
3
2
  import type { LogLevel } from './log-levels.js';
4
3
  import type { LogData, LogFn } from './log_fn.js';
@@ -40,7 +39,7 @@ export declare function overwriteLoggingStream(stream: Writable): void;
40
39
  */
41
40
  export declare function registerLoggingStream(stream: Writable): void;
42
41
  /** Log function that accepts an exception object */
43
- type ErrorLogFn = (msg: string, err?: Error | unknown, data?: LogData) => void;
42
+ type ErrorLogFn = (msg: string, err?: unknown, data?: LogData) => void;
44
43
  /**
45
44
  * Logger that supports multiple severity levels.
46
45
  */
@@ -1 +1 @@
1
- {"version":3,"file":"pino-logger.d.ts","sourceRoot":"","sources":["../../src/log/pino-logger.ts"],"names":[],"mappings":";AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAOvC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAElD,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAgCnD;AAID,KAAK,cAAc,GAAG,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC;AAGjD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAE/D;AAQD,KAAK,cAAc,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;AAGjD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAE/D;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,cAAc,QAK3D;AAED,iGAAiG;AACjG,wBAAsB,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAMjG;AAWD,eAAO,MAAO,QAAQ,kFAAE,UAAU,uCAAoD,CAAC;AA0CvF,eAAO,MAAM,MAAM;;;;;CAGlB,CAAC;AAMF,eAAO,MAAM,cAAc;;;;;;;;;;CAU1B,CAAC;AAoDF,eAAO,MAAM,MAAM,2CAAe,CAAC;AAanC;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,QAAQ,GAAG,IAAI,CAE7D;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,QAAQ,GAAG,IAAI,CAe5D;AAED,oDAAoD;AACpD,KAAK,UAAU,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK,GAAG,OAAO,EAAE,IAAI,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;AAE/E;;GAEG;AACH,MAAM,MAAM,MAAM,GAAG;KAAG,CAAC,IAAI,QAAQ,GAAG,KAAK;CAAE,GAAG;IAA4B,KAAK,EAAE,UAAU,CAAA;CAAE,GAAG;IAClG,KAAK,EAAE,QAAQ,CAAC;IAChB,cAAc,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,OAAO,CAAC;IAC7C,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC"}
1
+ {"version":3,"file":"pino-logger.d.ts","sourceRoot":"","sources":["../../src/log/pino-logger.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAOvC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAElD,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAgCnD;AAID,KAAK,cAAc,GAAG,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC;AAGjD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAE/D;AAQD,KAAK,cAAc,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;AAGjD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAE/D;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,cAAc,QAK3D;AAED,iGAAiG;AACjG,wBAAsB,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAMjG;AAWD,eAAO,MAAO,QAAQ,kFAAE,UAAU,uCAAoD,CAAC;AA0CvF,eAAO,MAAM,MAAM;;;;;CAGlB,CAAC;AAMF,eAAO,MAAM,cAAc;;;;;;;;;;CAU1B,CAAC;AAoDF,eAAO,MAAM,MAAM,2CAAe,CAAC;AAanC;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,QAAQ,GAAG,IAAI,CAE7D;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,QAAQ,GAAG,IAAI,CAe5D;AAED,oDAAoD;AACpD,KAAK,UAAU,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;AAEvE;;GAEG;AACH,MAAM,MAAM,MAAM,GAAG;KAAG,CAAC,IAAI,QAAQ,GAAG,KAAK;CAAE,GAAG;IAA4B,KAAK,EAAE,UAAU,CAAA;CAAE,GAAG;IAClG,KAAK,EAAE,QAAQ,CAAC;IAChB,cAAc,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,OAAO,CAAC;IAC7C,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/message/index.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG;IAC9B,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,qBAAa,aAAa;IACxB,yCAAyC;IACzC,SAAgB,SAAS,EAAE,MAAM,CAAC;IAClC,+EAA+E;IAC/E,SAAgB,SAAS,EAAE,MAAM,CAAC;gBAEtB,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,iBAAiB;IAKvD,MAAM,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa;CAGpD;AAED,UAAU,gBAAgB;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE;QACN,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,KAAK,EAAE,GAAG,CAAC;CACZ;AAED,qBAAa,YAAY,CAAC,CAAC,EAAE,CAAC;aACO,OAAO,EAAE,CAAC;aAAkB,MAAM,EAAE,aAAa;aAAkB,KAAK,EAAE,CAAC;gBAA3E,OAAO,EAAE,CAAC,EAAkB,MAAM,EAAE,aAAa,EAAkB,KAAK,EAAE,CAAC;IAE9G,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,gBAAgB,GAAG,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC;IAIxE,MAAM,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,gBAAgB;CAG7D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/message/index.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG;IAC9B,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,qBAAa,aAAa;IACxB,yCAAyC;IACzC,SAAgB,SAAS,EAAE,MAAM,CAAC;IAClC,+EAA+E;IAC/E,SAAgB,SAAS,EAAE,MAAM,CAAC;gBAEtB,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,iBAAiB;IAKvD,MAAM,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa;CAGpD;AAED,UAAU,gBAAgB;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE;QACN,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,KAAK,EAAE,GAAG,CAAC;CACZ;AAED,qBAAa,YAAY,CAAC,CAAC,EAAE,CAAC;aAEV,OAAO,EAAE,CAAC;aACV,MAAM,EAAE,aAAa;aACrB,KAAK,EAAE,CAAC;gBAFR,OAAO,EAAE,CAAC,EACV,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,CAAC;IAG1B,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,gBAAgB,GAAG,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC;IAIxE,MAAM,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,gBAAgB;CAG7D"}