@lidofinance/next-pages 0.36.0 → 0.37.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/api/index.js +84 -13
- package/dist/api/index.js.map +1 -0
- package/dist/api/rpcFactory.d.ts +2 -2
- package/dist/api/rpcFactory.d.ts.map +1 -1
- package/dist/ui/index.js +44 -9
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/pageError.d.ts.map +1 -1
- package/package.json +33 -12
- package/dist/api/health.js +0 -7
- package/dist/api/metricsFactory.js +0 -8
- package/dist/api/rpcFactory.js +0 -70
- package/dist/ui/page404.js +0 -7
- package/dist/ui/page500.js +0 -7
- package/dist/ui/pageError.js +0 -11
- package/dist/ui/types.js +0 -2
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ Common API and UI next pages.
|
|
|
10
10
|
yarn add @lidofinance/next-pages
|
|
11
11
|
|
|
12
12
|
# and additional
|
|
13
|
-
yarn add next@^12.3.0 prom-client@^14.0.0 @lidofinance/
|
|
13
|
+
yarn add next@^12.3.0 prom-client@^14.0.0 @lidofinance/api-logger@^0.36.0 @lidofinance/api-rpc@^0.36.0 @lidofinance/rpc@^0.36.0 @lidofinance/ui-pages@^0.36.0
|
|
14
14
|
```
|
|
15
15
|
|
|
16
16
|
## Getting started
|
package/dist/api/index.js
CHANGED
|
@@ -1,13 +1,84 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
1
|
+
import {Readable as $FgOCV$Readable} from "node:stream";
|
|
2
|
+
import {Counter as $FgOCV$Counter} from "prom-client";
|
|
3
|
+
import {iterateUrls as $FgOCV$iterateUrls} from "@lidofinance/rpc";
|
|
4
|
+
|
|
5
|
+
const $6ad1ea13f08e3d24$export$f0784a54fb0af903 = (_req, res)=>{
|
|
6
|
+
res.status(200).send({
|
|
7
|
+
status: "ok"
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
const $29c7c52f2735c037$export$fc20b1372f40c2c5 = ({ registry: registry })=>async (_req, res)=>{
|
|
13
|
+
const collectedMetrics = await registry.metrics();
|
|
14
|
+
res.send(collectedMetrics);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
const $7d34ac0315ec4c05$export$c982278a0ddc4dbe = "Something went wrong. Sorry, try again later :(";
|
|
22
|
+
const $7d34ac0315ec4c05$export$56a189db5508cdcb = "Healthy RPC services are over!";
|
|
23
|
+
class $7d34ac0315ec4c05$export$fc97cac2ba066ec7 extends Error {
|
|
24
|
+
constructor(message){
|
|
25
|
+
super(message || "Unsupported chainId");
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
class $7d34ac0315ec4c05$export$2dfa2d8949b43fdc extends Error {
|
|
29
|
+
constructor(message){
|
|
30
|
+
super(message || "Unsupported HTTP method");
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
const $7d34ac0315ec4c05$export$9bfcc39f106ad871 = ({ metrics: { prefix: prefix, registry: registry }, providers: providers, fetchRPC: fetchRPC, serverLogger: serverLogger = console, defaultChain: defaultChain, allowedRPCMethods: allowedRPCMethods })=>{
|
|
34
|
+
const rpcRequestBlocked = new (0, $FgOCV$Counter)({
|
|
35
|
+
name: prefix + "rpc_service_request_blocked",
|
|
36
|
+
help: "RPC service request blocked",
|
|
37
|
+
labelNames: [],
|
|
38
|
+
registers: []
|
|
39
|
+
});
|
|
40
|
+
registry.registerMetric(rpcRequestBlocked);
|
|
41
|
+
return async (req, res)=>{
|
|
42
|
+
try {
|
|
43
|
+
// Accept only POST requests
|
|
44
|
+
if (req.method !== "POST") // We don't care about tracking blocked requests here
|
|
45
|
+
throw new $7d34ac0315ec4c05$export$2dfa2d8949b43fdc();
|
|
46
|
+
const chainId = Number(req.query.chainId || defaultChain);
|
|
47
|
+
// Allow only chainId of specified chains
|
|
48
|
+
if (providers[chainId] == null) // We don't care about tracking blocked requests here
|
|
49
|
+
throw new $7d34ac0315ec4c05$export$fc97cac2ba066ec7();
|
|
50
|
+
// TODO: consider returning array of validators instead of throwing error right away
|
|
51
|
+
// Check if provided methods are allowed
|
|
52
|
+
for (const { method: method } of Array.isArray(req.body) ? req.body : [
|
|
53
|
+
req.body
|
|
54
|
+
]){
|
|
55
|
+
if (typeof method !== "string") throw new Error(`RPC method isn't string`);
|
|
56
|
+
if (!allowedRPCMethods.includes(method)) {
|
|
57
|
+
rpcRequestBlocked.inc();
|
|
58
|
+
throw new Error(`RPC method ${method} isn't allowed`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const requested = await (0, $FgOCV$iterateUrls)(providers[chainId], // TODO: consider adding verification that body is actually matches FetchRpcInitBody
|
|
62
|
+
(url)=>fetchRPC(url, {
|
|
63
|
+
body: req.body
|
|
64
|
+
}, {
|
|
65
|
+
chainId: chainId
|
|
66
|
+
}), serverLogger.error);
|
|
67
|
+
res.setHeader("Content-Type", requested.headers.get("Content-Type") ?? "application/json");
|
|
68
|
+
if (requested.body) (0, $FgOCV$Readable).fromWeb(requested.body).pipe(res);
|
|
69
|
+
else res.status(requested.status).json("There are a problems with RPC provider");
|
|
70
|
+
} catch (error) {
|
|
71
|
+
if (error instanceof Error) {
|
|
72
|
+
// TODO: check if there are errors duplication with iterateUrls
|
|
73
|
+
serverLogger.error(error.message ?? $7d34ac0315ec4c05$export$c982278a0ddc4dbe);
|
|
74
|
+
res.status(500).json(error.message ?? $7d34ac0315ec4c05$export$c982278a0ddc4dbe);
|
|
75
|
+
} else res.status(500).json($7d34ac0315ec4c05$export$56a189db5508cdcb);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
export {$6ad1ea13f08e3d24$export$f0784a54fb0af903 as health, $29c7c52f2735c037$export$fc20b1372f40c2c5 as metricsFactory, $7d34ac0315ec4c05$export$c982278a0ddc4dbe as DEFAULT_API_ERROR_MESSAGE, $7d34ac0315ec4c05$export$56a189db5508cdcb as HEALTHY_RPC_SERVICES_ARE_OVER, $7d34ac0315ec4c05$export$fc97cac2ba066ec7 as UnsupportedChainIdError, $7d34ac0315ec4c05$export$2dfa2d8949b43fdc as UnsupportedHTTPMethodError, $7d34ac0315ec4c05$export$9bfcc39f106ad871 as rpcFactory};
|
|
84
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"mappings":";;;;ACEO,MAAM,4CAAS,CAAC,MAAsB;IAC3C,IAAI,OAAO,KAAK,KAAK;QAAE,QAAQ;IAAK;AACtC;;;ACGO,MAAM,4CACX,CAAC,YAAE,QAAQ,EAA4B,GACvC,OAAO,MAAsB;QAC3B,MAAM,mBAAmB,MAAM,SAAS;QACxC,IAAI,KAAK;IACX;;;;;;ACDK,MAAM,4CAA4B;AAElC,MAAM,4CAAgC;AAEtC,MAAM,kDAAgC;IAC3C,YAAY,OAAgB,CAAE;QAC5B,KAAK,CAAC,WAAW;IACnB;AACF;AAEO,MAAM,kDAAmC;IAC9C,YAAY,OAAgB,CAAE;QAC5B,KAAK,CAAC,WAAW;IACnB;AACF;AAqBO,MAAM,4CAAa,CAAC,EACzB,SAAS,UAAE,MAAM,YAAE,QAAQ,EAAE,aAC7B,SAAS,YACT,QAAQ,gBACR,eAAe,uBACf,YAAY,qBACZ,iBAAiB,EACA;IACjB,MAAM,oBAAoB,IAAI,CAAA,GAAA,cAAM,EAAE;QACpC,MAAM,SAAS;QACf,MAAM;QACN,YAAY,EAAE;QACd,WAAW,EAAE;IACf;IACA,SAAS,eAAe;IAExB,OAAO,OAAO,KAAqB;QACjC,IAAI;YACF,4BAA4B;YAC5B,IAAI,IAAI,WAAW,QACjB,qDAAqD;YACrD,MAAM,IAAI;YAGZ,MAAM,UAAU,OAAO,IAAI,MAAM,WAAW;YAE5C,yCAAyC;YACzC,IAAI,SAAS,CAAC,QAAQ,IAAI,MACxB,qDAAqD;YACrD,MAAM,IAAI;YAGZ,oFAAoF;YACpF,wCAAwC;YACxC,KAAK,MAAM,UAAE,MAAM,EAAE,IAAI,MAAM,QAAQ,IAAI,QAAQ,IAAI,OAAO;gBAAC,IAAI;aAAK,CAAE;gBACxE,IAAI,OAAO,WAAW,UACpB,MAAM,IAAI,MAAM,CAAC,uBAAuB,CAAC;gBAE3C,IAAI,CAAC,kBAAkB,SAAS,SAAS;oBACvC,kBAAkB;oBAClB,MAAM,IAAI,MAAM,CAAC,WAAW,EAAE,OAAO,cAAc,CAAC;gBACtD;YACF;YAEA,MAAM,YAAY,MAAM,CAAA,GAAA,kBAAU,EAChC,SAAS,CAAC,QAAQ,EAClB,oFAAoF;YACpF,CAAC,MAAQ,SAAS,KAAK;oBAAE,MAAM,IAAI;gBAAyB,GAAG;6BAAE;gBAAQ,IACzE,aAAa;YAGf,IAAI,UAAU,gBAAgB,UAAU,QAAQ,IAAI,mBAAmB;YACvE,IAAI,UAAU,MACZ,CAAA,GAAA,eAAO,EAAE,QAAQ,UAAU,MAAwB,KAAK;iBAExD,IAAI,OAAO,UAAU,QAAQ,KAAK;QAEtC,EAAE,OAAO,OAAO;YACd,IAAI,iBAAiB,OAAO;gBAC1B,+DAA+D;gBAC/D,aAAa,MAAM,MAAM,WAAW;gBACpC,IAAI,OAAO,KAAK,KAAK,MAAM,WAAW;YACxC,OACE,IAAI,OAAO,KAAK,KAAK;QAEzB;IACF;AACF;","sources":["packages/next/pages/src/api/index.ts","packages/next/pages/src/api/health.ts","packages/next/pages/src/api/metricsFactory.ts","packages/next/pages/src/api/rpcFactory.ts"],"sourcesContent":["export { health } from './health'\nexport { type MetricsFactoryParameters, metricsFactory } from './metricsFactory'\nexport {\n type RpcProviders,\n DEFAULT_API_ERROR_MESSAGE,\n HEALTHY_RPC_SERVICES_ARE_OVER,\n UnsupportedChainIdError,\n UnsupportedHTTPMethodError,\n type RPCFactoryParams,\n rpcFactory,\n} from './rpcFactory'\n","import { NextApiRequest, NextApiResponse } from 'next'\n\nexport const health = (_req: NextApiRequest, res: NextApiResponse): void => {\n res.status(200).send({ status: 'ok' })\n}\n","import { NextApiRequest, NextApiResponse } from 'next'\nimport { Registry } from 'prom-client'\n\nexport type MetricsFactoryParameters = {\n registry: Registry\n}\n\nexport const metricsFactory =\n ({ registry }: MetricsFactoryParameters) =>\n async (_req: NextApiRequest, res: NextApiResponse) => {\n const collectedMetrics = await registry.metrics()\n res.send(collectedMetrics)\n }\n","import { Readable } from 'node:stream'\nimport { ReadableStream } from 'node:stream/web'\nimport type { NextApiRequest, NextApiResponse } from 'next'\nimport { Counter, Registry } from 'prom-client'\nimport type { TrackedFetchRPC } from '@lidofinance/api-rpc'\nimport type { ServerLogger } from '@lidofinance/api-logger'\nimport type { FetchRpcInitBody } from '@lidofinance/rpc'\nimport { iterateUrls } from '@lidofinance/rpc'\n\nexport type RpcProviders = Record<string | number, [string, ...string[]]>\n\nexport const DEFAULT_API_ERROR_MESSAGE = 'Something went wrong. Sorry, try again later :('\n\nexport const HEALTHY_RPC_SERVICES_ARE_OVER = 'Healthy RPC services are over!'\n\nexport class UnsupportedChainIdError extends Error {\n constructor(message?: string) {\n super(message || 'Unsupported chainId')\n }\n}\n\nexport class UnsupportedHTTPMethodError extends Error {\n constructor(message?: string) {\n super(message || 'Unsupported HTTP method')\n }\n}\n\nexport type RPCFactoryParams = {\n metrics: {\n prefix: string\n registry: Registry\n }\n providers: RpcProviders\n fetchRPC: TrackedFetchRPC\n /**\n * @deprecated you should mask logs via pino & satanizer, see policies\n * for additional details or reach out ui/secops\n */\n serverLogger?: ServerLogger\n defaultChain: string | number\n // If we don't specify allowed RPC methods, then we can't use\n // fetchRPC with prometheus, otherwise it will blow up, if someone will send arbitrary\n // methods\n allowedRPCMethods: string[]\n}\n\nexport const rpcFactory = ({\n metrics: { prefix, registry },\n providers,\n fetchRPC,\n serverLogger = console,\n defaultChain,\n allowedRPCMethods,\n}: RPCFactoryParams) => {\n const rpcRequestBlocked = new Counter({\n name: prefix + 'rpc_service_request_blocked',\n help: 'RPC service request blocked',\n labelNames: [],\n registers: [],\n })\n registry.registerMetric(rpcRequestBlocked)\n\n return async (req: NextApiRequest, res: NextApiResponse): Promise<void> => {\n try {\n // Accept only POST requests\n if (req.method !== 'POST') {\n // We don't care about tracking blocked requests here\n throw new UnsupportedHTTPMethodError()\n }\n\n const chainId = Number(req.query.chainId || defaultChain)\n\n // Allow only chainId of specified chains\n if (providers[chainId] == null) {\n // We don't care about tracking blocked requests here\n throw new UnsupportedChainIdError()\n }\n\n // TODO: consider returning array of validators instead of throwing error right away\n // Check if provided methods are allowed\n for (const { method } of Array.isArray(req.body) ? req.body : [req.body]) {\n if (typeof method !== 'string') {\n throw new Error(`RPC method isn't string`)\n }\n if (!allowedRPCMethods.includes(method)) {\n rpcRequestBlocked.inc()\n throw new Error(`RPC method ${method} isn't allowed`)\n }\n }\n\n const requested = await iterateUrls(\n providers[chainId],\n // TODO: consider adding verification that body is actually matches FetchRpcInitBody\n (url) => fetchRPC(url, { body: req.body as FetchRpcInitBody }, { chainId }),\n serverLogger.error,\n )\n\n res.setHeader('Content-Type', requested.headers.get('Content-Type') ?? 'application/json')\n if (requested.body) {\n Readable.fromWeb(requested.body as ReadableStream).pipe(res)\n } else {\n res.status(requested.status).json('There are a problems with RPC provider')\n }\n } catch (error) {\n if (error instanceof Error) {\n // TODO: check if there are errors duplication with iterateUrls\n serverLogger.error(error.message ?? DEFAULT_API_ERROR_MESSAGE)\n res.status(500).json(error.message ?? DEFAULT_API_ERROR_MESSAGE)\n } else {\n res.status(500).json(HEALTHY_RPC_SERVICES_ARE_OVER)\n }\n }\n }\n}\n"],"names":[],"version":3,"file":"index.js.map","sourceRoot":"../../../../../"}
|
package/dist/api/rpcFactory.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { NextApiRequest, NextApiResponse } from 'next';
|
|
2
2
|
import { Registry } from 'prom-client';
|
|
3
|
-
import { TrackedFetchRPC } from '@lidofinance/api-rpc';
|
|
4
|
-
import { ServerLogger } from '@lidofinance/api-logger';
|
|
3
|
+
import type { TrackedFetchRPC } from '@lidofinance/api-rpc';
|
|
4
|
+
import type { ServerLogger } from '@lidofinance/api-logger';
|
|
5
5
|
export type RpcProviders = Record<string | number, [string, ...string[]]>;
|
|
6
6
|
export declare const DEFAULT_API_ERROR_MESSAGE = "Something went wrong. Sorry, try again later :(";
|
|
7
7
|
export declare const HEALTHY_RPC_SERVICES_ARE_OVER = "Healthy RPC services are over!";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpcFactory.d.ts","sourceRoot":"","sources":["../../src/api/rpcFactory.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"rpcFactory.d.ts","sourceRoot":"","sources":["../../src/api/rpcFactory.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,MAAM,CAAA;AAC3D,OAAO,EAAW,QAAQ,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAI3D,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC,CAAA;AAEzE,eAAO,MAAM,yBAAyB,oDAAoD,CAAA;AAE1F,eAAO,MAAM,6BAA6B,mCAAmC,CAAA;AAE7E,qBAAa,uBAAwB,SAAQ,KAAK;gBACpC,OAAO,CAAC,EAAE,MAAM;CAG7B;AAED,qBAAa,0BAA2B,SAAQ,KAAK;gBACvC,OAAO,CAAC,EAAE,MAAM;CAG7B;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE;QACP,MAAM,EAAE,MAAM,CAAA;QACd,QAAQ,EAAE,QAAQ,CAAA;KACnB,CAAA;IACD,SAAS,EAAE,YAAY,CAAA;IACvB,QAAQ,EAAE,eAAe,CAAA;IACzB;;;OAGG;IACH,YAAY,CAAC,EAAE,YAAY,CAAA;IAC3B,YAAY,EAAE,MAAM,GAAG,MAAM,CAAA;IAI7B,iBAAiB,EAAE,MAAM,EAAE,CAAA;CAC5B,CAAA;AAED,eAAO,MAAM,UAAU,2GAOpB,gBAAgB,WASE,cAAc,OAAO,eAAe,KAAG,QAAQ,IAAI,CAmDvE,CAAA"}
|
package/dist/ui/index.js
CHANGED
|
@@ -1,9 +1,44 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
import {jsxs as $fmwPY$jsxs, jsx as $fmwPY$jsx} from "react/jsx-runtime";
|
|
2
|
+
import "react";
|
|
3
|
+
import $fmwPY$nextheadjs from "next/head.js";
|
|
4
|
+
import {ServicePage as $fmwPY$ServicePage} from "@lidofinance/ui-pages";
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
const $b3d49e808d0a0868$export$ece78e4633e29053 = ({ title: title, content: content })=>/*#__PURE__*/ (0, $fmwPY$jsxs)((0, $fmwPY$ServicePage), {
|
|
11
|
+
title: title,
|
|
12
|
+
children: [
|
|
13
|
+
/*#__PURE__*/ (0, $fmwPY$jsx)((0, $fmwPY$nextheadjs), {
|
|
14
|
+
children: /*#__PURE__*/ (0, $fmwPY$jsx)("title", {
|
|
15
|
+
children: title
|
|
16
|
+
})
|
|
17
|
+
}),
|
|
18
|
+
content
|
|
19
|
+
]
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
const $7dcef83a3ed31828$export$3cb69218ff952ef8 = ({ title: title, content: content })=>/*#__PURE__*/ (0, $fmwPY$jsx)((0, $b3d49e808d0a0868$export$ece78e4633e29053), {
|
|
27
|
+
title: title ?? "Page Not Found",
|
|
28
|
+
content: content ?? "\xaf\\_(ツ)_/\xaf"
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
const $3f6b29e27472c2a9$export$fd3f669c2104219d = ({ title: title, content: content })=>/*#__PURE__*/ (0, $fmwPY$jsx)((0, $b3d49e808d0a0868$export$ece78e4633e29053), {
|
|
36
|
+
title: title ?? "Internal Server Error",
|
|
37
|
+
content: content ?? "Oops! Something went wrong."
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
export {$b3d49e808d0a0868$export$ece78e4633e29053 as PageError, $7dcef83a3ed31828$export$3cb69218ff952ef8 as Page404, $3f6b29e27472c2a9$export$fd3f669c2104219d as Page500};
|
|
44
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"mappings":";;;;;;;;;ACMO,MAAM,4CAAgC,CAAC,SAAE,KAAK,WAAE,OAAO,EAAE,iBAC9D,iBAAC,CAAA,GAAA,kBAAU;QAAE,OAAO;;0BAClB,gBAAC,CAAA,GAAA,iBAAG;0BACF,cAAA,gBAAC;8BAAO;;;YAET;;;;;;;;ACPE,MAAM,4CAAuC,CAAC,SAAE,KAAK,WAAE,OAAO,EAAE,iBACrE,gBAAC,CAAA,GAAA,yCAAQ;QAAE,OAAO,SAAS;QAAkB,SAAS,WAAW;;;;;;;ACD5D,MAAM,4CAAuC,CAAC,SAAE,KAAK,WAAE,OAAO,EAAE,iBACrE,gBAAC,CAAA,GAAA,yCAAQ;QAAE,OAAO,SAAS;QAAyB,SAAS,WAAW;;","sources":["packages/next/pages/src/ui/index.ts","packages/next/pages/src/ui/pageError.tsx","packages/next/pages/src/ui/page404.tsx","packages/next/pages/src/ui/page500.tsx"],"sourcesContent":["export { PageError } from './pageError'\nexport { Page404 } from './page404'\nexport { Page500 } from './page500'\n","import React, { FC } from 'react'\n// TODO: import without extension https://linear.app/lidofi/issue/UI-1052/fix-import-in-esm-module\nimport Head from 'next/head.js'\nimport { ServicePage } from '@lidofinance/ui-pages'\nimport { PageErrorProps } from './types'\n\nexport const PageError: FC<PageErrorProps> = ({ title, content }) => (\n <ServicePage title={title}>\n <Head>\n <title>{title}</title>\n </Head>\n {content}\n </ServicePage>\n)\n","import React, { FC } from 'react'\nimport { PageErrorProps } from './types'\nimport { PageError } from './pageError'\n\nexport const Page404: FC<Partial<PageErrorProps>> = ({ title, content }) => (\n <PageError title={title ?? 'Page Not Found'} content={content ?? '¯\\\\_(ツ)_/¯'} />\n)\n","import React, { FC } from 'react'\nimport { PageErrorProps } from './types'\nimport { PageError } from './pageError'\n\nexport const Page500: FC<Partial<PageErrorProps>> = ({ title, content }) => (\n <PageError title={title ?? 'Internal Server Error'} content={content ?? 'Oops! Something went wrong.'} />\n)\n"],"names":[],"version":3,"file":"index.js.map","sourceRoot":"../../../../../"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pageError.d.ts","sourceRoot":"","sources":["../../src/ui/pageError.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAE,EAAE,EAAE,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"pageError.d.ts","sourceRoot":"","sources":["../../src/ui/pageError.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAE,EAAE,EAAE,MAAM,OAAO,CAAA;AAIjC,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAExC,eAAO,MAAM,SAAS,EAAE,EAAE,CAAC,cAAc,CAOxC,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lidofinance/next-pages",
|
|
3
3
|
"description": "Common next API and UI pages",
|
|
4
|
-
"repository": "
|
|
4
|
+
"repository": "https://github.com/lidofinance/warehouse.git",
|
|
5
|
+
"homepage": "https://github.com/lidofinance/warehouse/tree/main/packages/next/pages",
|
|
6
|
+
"bugs": {
|
|
7
|
+
"url": "https://github.com/lidofinance/warehouse/issues"
|
|
8
|
+
},
|
|
5
9
|
"license": "MIT",
|
|
6
|
-
"version": "0.
|
|
10
|
+
"version": "0.37.1",
|
|
11
|
+
"type": "module",
|
|
7
12
|
"files": [
|
|
8
13
|
"dist"
|
|
9
14
|
],
|
|
@@ -11,8 +16,24 @@
|
|
|
11
16
|
"node": ">= 16",
|
|
12
17
|
"browsers": "> 0.5%, last 2 versions, not dead"
|
|
13
18
|
},
|
|
19
|
+
"targets": {
|
|
20
|
+
"ui": {
|
|
21
|
+
"source": "./src/ui/index.ts",
|
|
22
|
+
"distDir": "./dist/ui",
|
|
23
|
+
"outputFormat": "esmodule",
|
|
24
|
+
"isLibrary": true,
|
|
25
|
+
"context": "node"
|
|
26
|
+
},
|
|
27
|
+
"api": {
|
|
28
|
+
"source": "./src/api/index.ts",
|
|
29
|
+
"distDir": "./dist/api",
|
|
30
|
+
"outputFormat": "esmodule",
|
|
31
|
+
"isLibrary": true,
|
|
32
|
+
"context": "node"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
14
35
|
"scripts": {
|
|
15
|
-
"build": "tsc",
|
|
36
|
+
"build": "parcel build && tsc --emitDeclarationOnly",
|
|
16
37
|
"lint": "eslint . && prettier --check src",
|
|
17
38
|
"lint:fix": "eslint --fix . && prettier --check src --write",
|
|
18
39
|
"types": "tsc --noEmit"
|
|
@@ -36,20 +57,20 @@
|
|
|
36
57
|
}
|
|
37
58
|
},
|
|
38
59
|
"peerDependencies": {
|
|
39
|
-
"@lidofinance/api-logger": "~0.
|
|
40
|
-
"@lidofinance/api-rpc": "~0.
|
|
41
|
-
"@lidofinance/rpc": "~0.
|
|
42
|
-
"@lidofinance/ui-pages": "~0.
|
|
60
|
+
"@lidofinance/api-logger": "~0.37.1",
|
|
61
|
+
"@lidofinance/api-rpc": "~0.37.1",
|
|
62
|
+
"@lidofinance/rpc": "~0.37.1",
|
|
63
|
+
"@lidofinance/ui-pages": "~0.37.1",
|
|
43
64
|
"next": "12 || 13",
|
|
44
65
|
"prom-client": "^14.1.0",
|
|
45
66
|
"react": "17 || 18"
|
|
46
67
|
},
|
|
47
68
|
"devDependencies": {
|
|
48
|
-
"@lidofinance/api-logger": "~0.
|
|
49
|
-
"@lidofinance/api-rpc": "~0.
|
|
50
|
-
"@lidofinance/config-prettier": "~0.
|
|
51
|
-
"@lidofinance/rpc": "~0.
|
|
52
|
-
"@lidofinance/ui-pages": "~0.
|
|
69
|
+
"@lidofinance/api-logger": "~0.37.1",
|
|
70
|
+
"@lidofinance/api-rpc": "~0.37.1",
|
|
71
|
+
"@lidofinance/config-prettier": "~0.37.1",
|
|
72
|
+
"@lidofinance/rpc": "~0.37.1",
|
|
73
|
+
"@lidofinance/ui-pages": "~0.37.1",
|
|
53
74
|
"@types/react": "^18.0.25",
|
|
54
75
|
"next": "^12.3.1",
|
|
55
76
|
"prom-client": "^14.1.0"
|
package/dist/api/health.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.metricsFactory = void 0;
|
|
4
|
-
const metricsFactory = ({ registry }) => async (_req, res) => {
|
|
5
|
-
const collectedMetrics = await registry.metrics();
|
|
6
|
-
res.send(collectedMetrics);
|
|
7
|
-
};
|
|
8
|
-
exports.metricsFactory = metricsFactory;
|
package/dist/api/rpcFactory.js
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.rpcFactory = exports.UnsupportedHTTPMethodError = exports.UnsupportedChainIdError = exports.HEALTHY_RPC_SERVICES_ARE_OVER = exports.DEFAULT_API_ERROR_MESSAGE = void 0;
|
|
4
|
-
const prom_client_1 = require("prom-client");
|
|
5
|
-
const rpc_1 = require("@lidofinance/rpc");
|
|
6
|
-
exports.DEFAULT_API_ERROR_MESSAGE = 'Something went wrong. Sorry, try again later :(';
|
|
7
|
-
exports.HEALTHY_RPC_SERVICES_ARE_OVER = 'Healthy RPC services are over!';
|
|
8
|
-
class UnsupportedChainIdError extends Error {
|
|
9
|
-
constructor(message) {
|
|
10
|
-
super(message || 'Unsupported chainId');
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
exports.UnsupportedChainIdError = UnsupportedChainIdError;
|
|
14
|
-
class UnsupportedHTTPMethodError extends Error {
|
|
15
|
-
constructor(message) {
|
|
16
|
-
super(message || 'Unsupported HTTP method');
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
exports.UnsupportedHTTPMethodError = UnsupportedHTTPMethodError;
|
|
20
|
-
const rpcFactory = ({ metrics: { prefix, registry }, providers, fetchRPC, serverLogger = console, defaultChain, allowedRPCMethods, }) => {
|
|
21
|
-
const rpcRequestBlocked = new prom_client_1.Counter({
|
|
22
|
-
name: prefix + 'rpc_service_request_blocked',
|
|
23
|
-
help: 'RPC service request blocked',
|
|
24
|
-
labelNames: [],
|
|
25
|
-
registers: [],
|
|
26
|
-
});
|
|
27
|
-
registry.registerMetric(rpcRequestBlocked);
|
|
28
|
-
return async (req, res) => {
|
|
29
|
-
try {
|
|
30
|
-
// Accept only POST requests
|
|
31
|
-
if (req.method !== 'POST') {
|
|
32
|
-
// We don't care about tracking blocked requests here
|
|
33
|
-
throw new UnsupportedHTTPMethodError();
|
|
34
|
-
}
|
|
35
|
-
const chainId = Number(req.query.chainId || defaultChain);
|
|
36
|
-
// Allow only chainId of specified chains
|
|
37
|
-
if (providers[chainId] == null) {
|
|
38
|
-
// We don't care about tracking blocked requests here
|
|
39
|
-
throw new UnsupportedChainIdError();
|
|
40
|
-
}
|
|
41
|
-
// TODO: consider returning array of validators instead of throwing error right away
|
|
42
|
-
// Check if provided methods are allowed
|
|
43
|
-
for (const { method } of Array.isArray(req.body) ? req.body : [req.body]) {
|
|
44
|
-
if (typeof method !== 'string') {
|
|
45
|
-
throw new Error(`RPC method isn't string`);
|
|
46
|
-
}
|
|
47
|
-
if (!allowedRPCMethods.includes(method)) {
|
|
48
|
-
rpcRequestBlocked.inc();
|
|
49
|
-
throw new Error(`RPC method ${method} isn't allowed`);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
const requested = await (0, rpc_1.iterateUrls)(providers[chainId],
|
|
53
|
-
// TODO: consider adding verification that body is actually matches FetchRpcInitBody
|
|
54
|
-
(url) => fetchRPC(url, { body: req.body }, { chainId }), serverLogger.error);
|
|
55
|
-
res.setHeader('Content-Type', requested.headers.get('Content-Type') ?? 'application/json');
|
|
56
|
-
res.status(requested.status).send(requested.body);
|
|
57
|
-
}
|
|
58
|
-
catch (error) {
|
|
59
|
-
if (error instanceof Error) {
|
|
60
|
-
// TODO: check if there are errors duplication with iterateUrls
|
|
61
|
-
serverLogger.error(error.message ?? exports.DEFAULT_API_ERROR_MESSAGE);
|
|
62
|
-
res.status(500).json(error.message ?? exports.DEFAULT_API_ERROR_MESSAGE);
|
|
63
|
-
}
|
|
64
|
-
else {
|
|
65
|
-
res.status(500).json(exports.HEALTHY_RPC_SERVICES_ARE_OVER);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
};
|
|
70
|
-
exports.rpcFactory = rpcFactory;
|
package/dist/ui/page404.js
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Page404 = void 0;
|
|
4
|
-
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
-
const pageError_1 = require("./pageError");
|
|
6
|
-
const Page404 = ({ title, content }) => ((0, jsx_runtime_1.jsx)(pageError_1.PageError, { title: title ?? 'Page Not Found', content: content ?? '¯\\_(ツ)_/¯' }));
|
|
7
|
-
exports.Page404 = Page404;
|
package/dist/ui/page500.js
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Page500 = void 0;
|
|
4
|
-
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
-
const pageError_1 = require("./pageError");
|
|
6
|
-
const Page500 = ({ title, content }) => ((0, jsx_runtime_1.jsx)(pageError_1.PageError, { title: title ?? 'Internal Server Error', content: content ?? 'Oops! Something went wrong.' }));
|
|
7
|
-
exports.Page500 = Page500;
|
package/dist/ui/pageError.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.PageError = void 0;
|
|
7
|
-
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
-
const head_1 = __importDefault(require("next/head"));
|
|
9
|
-
const ui_pages_1 = require("@lidofinance/ui-pages");
|
|
10
|
-
const PageError = ({ title, content }) => ((0, jsx_runtime_1.jsxs)(ui_pages_1.ServicePage, { title: title, children: [(0, jsx_runtime_1.jsx)(head_1.default, { children: (0, jsx_runtime_1.jsx)("title", { children: title }) }), content] }));
|
|
11
|
-
exports.PageError = PageError;
|
package/dist/ui/types.js
DELETED