@asyncswap/engine-rpc 0.0.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/CHANGELOG.md +13 -0
- package/README.md +35 -0
- package/example.ts +6 -0
- package/package.json +45 -0
- package/src/engine-api.ts +19 -0
- package/src/index.ts +1 -0
- package/src/types/blob.d.ts +12 -0
- package/src/types/forkchoice.d.ts +32 -0
- package/src/types/identification.d.ts +24 -0
- package/src/types/methods.d.ts +130 -0
- package/src/types/payload.d.ts +121 -0
- package/src/types/transition-configuration.d.ts +10 -0
- package/tsconfig.json +40 -0
package/CHANGELOG.md
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# @asyncswap/engine-rpc
|
|
2
|
+
|
|
3
|
+
A library for Ethereum engine api JSON-RPC spec.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
bun add @asyncswap/engine-rpc
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
### Engine API Client
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { EngineExecutionClient } from '@asyncswap/eth-rpc';
|
|
17
|
+
|
|
18
|
+
const engineUrl = 'http://localhost:8551';
|
|
19
|
+
const engine = new EngineExecutionClient(engineUrl, process.env.JWT_TOKEN!);
|
|
20
|
+
const payload = await engine.engine_getPayloadV1("0x1");
|
|
21
|
+
|
|
22
|
+
console.log(payload);
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## References
|
|
26
|
+
|
|
27
|
+
- [ethereum/execution-apis](https://github.com/ethereum/execution-apis/tree/main/src/engine)
|
|
28
|
+
|
|
29
|
+
## Dependencies
|
|
30
|
+
|
|
31
|
+
- `@asyncswap/eth-rpc` - lib for ethereum execution client JSON-RPC 2.0 api.
|
|
32
|
+
|
|
33
|
+
## License
|
|
34
|
+
|
|
35
|
+
MIT
|
package/example.ts
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@asyncswap/engine-rpc",
|
|
3
|
+
"description": "A library for Ethereum engine api JSON-RPC spec.",
|
|
4
|
+
"author": "Meek Msaki",
|
|
5
|
+
"version": "0.0.1",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"main": "dist/index.js",
|
|
9
|
+
"module": "dist/index.mjs",
|
|
10
|
+
"types": "dist/index.d.ts",
|
|
11
|
+
"keywords": [
|
|
12
|
+
"ethereum",
|
|
13
|
+
"engine-api",
|
|
14
|
+
"execution-client",
|
|
15
|
+
"json-rpc"
|
|
16
|
+
],
|
|
17
|
+
"homepage": "https://github.com/asyncswap/eth-libs/tree/main/packages/flashbots-rpc",
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/asyncswap/eth-libs.git",
|
|
21
|
+
"directory": "packages/flashbots-rpc"
|
|
22
|
+
},
|
|
23
|
+
"bugs": {
|
|
24
|
+
"url": "https://github.com/asyncswap/eth-libs/issues"
|
|
25
|
+
},
|
|
26
|
+
"publishConfig": {
|
|
27
|
+
"access": "public",
|
|
28
|
+
"directory": "dist"
|
|
29
|
+
},
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "tsc -p tsconfig.json",
|
|
32
|
+
"publish": "bun run build && bun publish --access public",
|
|
33
|
+
"format": "bun biome format --write"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@biomejs/biome": "2.3.11",
|
|
37
|
+
"@types/bun": "latest"
|
|
38
|
+
},
|
|
39
|
+
"peerDependencies": {
|
|
40
|
+
"typescript": "^5"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"@asyncswap/eth-rpc": "^0.4.8"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { BaseClient } from "@asyncswap/eth-rpc";
|
|
2
|
+
|
|
3
|
+
export class EngineExecutionClient extends BaseClient<EngineMethodsSpec> {
|
|
4
|
+
constructor(url: string, jwt_token: string) {
|
|
5
|
+
super(url);
|
|
6
|
+
this.headers = {
|
|
7
|
+
Authorization: `Bearer ${jwt_token}`,
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export type EngineRpcMethods<
|
|
13
|
+
T extends Record<string, { params: readonly unknown[]; result: unknown }>,
|
|
14
|
+
> = {
|
|
15
|
+
[K in keyof T]: (...params: T[K]["params"]) => Promise<T[K]["result"]>;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export interface EngineExecutionClient
|
|
19
|
+
extends EngineRpcMethods<EngineMethodsSpec> { }
|
package/src/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./engine-api";
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
declare global {
|
|
2
|
+
// forkchoice
|
|
3
|
+
export interface ForkchoiceStateV1 {
|
|
4
|
+
headBlockHash: Hash32;
|
|
5
|
+
safeBlockHash: Hash32;
|
|
6
|
+
finalizedBlockHash: Hash32;
|
|
7
|
+
}
|
|
8
|
+
export interface ForkchoiceUpdatedResponseV1 {
|
|
9
|
+
payloadStatus: RestrictedPayloadStatusV1;
|
|
10
|
+
payloadId?: Bytes8;
|
|
11
|
+
}
|
|
12
|
+
export interface PayloadAttributesV1 {
|
|
13
|
+
timestamp: Uint64;
|
|
14
|
+
prevRandao: Bytes32;
|
|
15
|
+
suggestedFeeRecipient: Address;
|
|
16
|
+
}
|
|
17
|
+
export interface PayloadAttributesV2 {
|
|
18
|
+
timestamp: Uint64;
|
|
19
|
+
prevRandao: Bytes32;
|
|
20
|
+
suggestedFeeRecipient: Address;
|
|
21
|
+
withdrawals: WithdrawalV1[];
|
|
22
|
+
}
|
|
23
|
+
export interface PayloadAttributesV3 {
|
|
24
|
+
timestamp: Uint64;
|
|
25
|
+
prevRandao: Bytes32;
|
|
26
|
+
suggestedFeeRecipient: Address;
|
|
27
|
+
withdrawals: WithdrawalV1[];
|
|
28
|
+
parentBeaconBlockRoot: Hash32;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export { };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
declare global {
|
|
2
|
+
export type ClientVersionV1 = {
|
|
3
|
+
code: ClientCode;
|
|
4
|
+
name: string;
|
|
5
|
+
varsion: string;
|
|
6
|
+
commit: string;
|
|
7
|
+
};
|
|
8
|
+
export type ClientCode =
|
|
9
|
+
| "BU" // besu
|
|
10
|
+
| "EJ" // ethereumJs
|
|
11
|
+
| "EG" // erigon
|
|
12
|
+
| "GE" // go-ethereum
|
|
13
|
+
| "GR" // gradine
|
|
14
|
+
| "LH" // lighthouse
|
|
15
|
+
| "LS" // lodestar
|
|
16
|
+
| "NM" // nethermind
|
|
17
|
+
| "NB" // nimbus
|
|
18
|
+
| "TE" // thin-execution
|
|
19
|
+
| "TK" // teku
|
|
20
|
+
| "PM" // prysm
|
|
21
|
+
| "RH"; // reth
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export { };
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
declare global {
|
|
2
|
+
export type EngineMethodsSpec = {
|
|
3
|
+
// identification
|
|
4
|
+
engine_getClientVersionV1: {
|
|
5
|
+
params: [ClientVersionV1];
|
|
6
|
+
result: ClientVersionV1[];
|
|
7
|
+
};
|
|
8
|
+
// share methods
|
|
9
|
+
eth_blockNumber: { params: []; result: Uint };
|
|
10
|
+
eth_call: {
|
|
11
|
+
params: [GenericTransaction, BlockNumberOrTagOrHash];
|
|
12
|
+
result: Bytes;
|
|
13
|
+
};
|
|
14
|
+
eth_chainId: { params: []; result: Uint };
|
|
15
|
+
eth_getCode: { params: [Address, BlockNumberOrTagOrHash]; result: Bytes };
|
|
16
|
+
eth_getBlockByHash: { params: [Hash32, boolean]; result: NotFound | Block };
|
|
17
|
+
eth_getBlockByNumber: {
|
|
18
|
+
params: [BlockNumberOrTag, boolean];
|
|
19
|
+
result: NotFound | Block;
|
|
20
|
+
};
|
|
21
|
+
eth_getLogs: { params: [Filter]; result: FilterResults };
|
|
22
|
+
eth_sendRawTransaction: { params: [Bytes]; result: Hash32 };
|
|
23
|
+
eth_syncing: { params: []; result: SyncingStatus };
|
|
24
|
+
// engine/blob
|
|
25
|
+
engine_getBlobsV1: { params: [Hash32[]]; result: BlobAndProofV1[] };
|
|
26
|
+
engine_getBlobsV2: { params: [Hash32[]]; result: BlobAndProofV2[] };
|
|
27
|
+
engine_getBlobsV3: {
|
|
28
|
+
params: [Hash32[]];
|
|
29
|
+
result: Array<BlobAndProofV2[] | null> | null;
|
|
30
|
+
};
|
|
31
|
+
// engine/capabilities
|
|
32
|
+
engine_exchangeCapabilities: { params: [string[]]; result: string[] };
|
|
33
|
+
// engine/forkchoice
|
|
34
|
+
engine_forkchoiceUpdatedV1: {
|
|
35
|
+
params: [ForkchoiceStateV1, PayloadAttributesV1];
|
|
36
|
+
result: ForkchoiceUpdatedResponseV1;
|
|
37
|
+
};
|
|
38
|
+
engine_forkchoiceUpdatedV2: {
|
|
39
|
+
params: [ForkchoiceStateV1, PayloadAttributesV2];
|
|
40
|
+
result: ForkchoiceUpdatedResponseV1;
|
|
41
|
+
};
|
|
42
|
+
engine_forkchoiceUpdatedV3: {
|
|
43
|
+
params: [ForkchoiceStateV1, PayloadAttributesV3];
|
|
44
|
+
result: ForkchoiceUpdatedResponseV1;
|
|
45
|
+
};
|
|
46
|
+
// engine/payload
|
|
47
|
+
engine_newPayloadV1: {
|
|
48
|
+
params: [ExecutionPayloadV1];
|
|
49
|
+
result: PayloadStatusV1;
|
|
50
|
+
};
|
|
51
|
+
engine_newPayloadV2: {
|
|
52
|
+
params: [ExecutionPayloadV1 | ExecutionPayloadV2];
|
|
53
|
+
result: PayloadStatusNoInvalidBlockHash;
|
|
54
|
+
};
|
|
55
|
+
engine_newPayloadV3: {
|
|
56
|
+
params: [ExecutionPayloadV3, Hash32[], Hash32];
|
|
57
|
+
result: PayloadStatusNoInvalidBlockHash;
|
|
58
|
+
};
|
|
59
|
+
engine_newPayloadV4: {
|
|
60
|
+
params: [ExecutionPayloadV3, Hash32[], Hash32, Bytes[]];
|
|
61
|
+
result: PayloadStatusNoInvalidBlockHash;
|
|
62
|
+
};
|
|
63
|
+
engine_getPayloadV1: { params: [Bytes8]; result: ExecutionPayloadV1 };
|
|
64
|
+
engine_getPayloadV2: {
|
|
65
|
+
params: [Bytes8];
|
|
66
|
+
result: {
|
|
67
|
+
executionPayload: ExecutionPayloadV1 | ExecutionPayloadV2;
|
|
68
|
+
blockValue: Uint256;
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
engine_getPayloadV3: {
|
|
72
|
+
params: [Bytes8];
|
|
73
|
+
result: {
|
|
74
|
+
executionPayload: ExecutionPayloadV3;
|
|
75
|
+
blockValue: Uint256;
|
|
76
|
+
blobsBundle: BlobsBundleV1;
|
|
77
|
+
shouldOverrideBuilder: boolean;
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
engine_getPayloadV4: {
|
|
81
|
+
params: [Bytes8];
|
|
82
|
+
result: {
|
|
83
|
+
executionPayload: ExecutionPayloadV3;
|
|
84
|
+
blockValue: Uint256;
|
|
85
|
+
blobsBundle: BlobsBundleV1;
|
|
86
|
+
shouldOverrideBuilder: boolean;
|
|
87
|
+
executionRequests: Bytes[];
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
engine_getPayloadV5: {
|
|
91
|
+
params: [Bytes8];
|
|
92
|
+
result: {
|
|
93
|
+
executionPayload: ExecutionPayloadV3;
|
|
94
|
+
blockValue: Uint256;
|
|
95
|
+
blobsBundle: BlobsBundleV2;
|
|
96
|
+
shouldOverrideBuilder: boolean;
|
|
97
|
+
executionRequests: Bytes[];
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
engine_getPayloadBodiesByHashV1: {
|
|
101
|
+
params: [Hash32[]];
|
|
102
|
+
result: ExecutionPayloadBodyV1[];
|
|
103
|
+
};
|
|
104
|
+
engine_getPayloadBodiesByRangeV1: {
|
|
105
|
+
params: [Uint64, Uint64];
|
|
106
|
+
result: ExecutionPayloadBodyV1[];
|
|
107
|
+
};
|
|
108
|
+
engine_newPayloadV5: {
|
|
109
|
+
params: [ExecutionPayloadV4, Hash32[], Hash32, Bytes[]];
|
|
110
|
+
result: PayloadStatusNoInvalidBlockHash;
|
|
111
|
+
};
|
|
112
|
+
engine_getPayloadV6: {
|
|
113
|
+
params: [Bytes8];
|
|
114
|
+
result: {
|
|
115
|
+
executionPayload: ExecutionPayloadV4;
|
|
116
|
+
blockValue: Uint256;
|
|
117
|
+
blobsBundle: BlobsBundleV2;
|
|
118
|
+
shouldOverrideBuilder: boolean;
|
|
119
|
+
executionRequests: Bytes[];
|
|
120
|
+
};
|
|
121
|
+
};
|
|
122
|
+
// engine/transition-configuration
|
|
123
|
+
engine_exchangeTransitionConfigurationV1: {
|
|
124
|
+
params: [TransitionConfigurationV1];
|
|
125
|
+
result: TransitionConfigurationV1;
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export { };
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
declare global {
|
|
2
|
+
export enum PAYLOAD_STATUS {
|
|
3
|
+
VALID = "VALID",
|
|
4
|
+
INVALID = "INVALID",
|
|
5
|
+
SYNCING = "SYNCING",
|
|
6
|
+
ACCEPTED = "ACCEPTED",
|
|
7
|
+
INVALID_BLOCK_HASH = "INVALID_BLOCK_HASH",
|
|
8
|
+
}
|
|
9
|
+
export interface PayloadStatusV1 {
|
|
10
|
+
status: PAYLOAD_STATUS;
|
|
11
|
+
latestValidHash?: Hash32;
|
|
12
|
+
validationError?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface RestrictedPayloadStatusV1 {
|
|
15
|
+
status:
|
|
16
|
+
| PAYLOAD_STATUS.VALID
|
|
17
|
+
| PAYLOAD_STATUS.INVALID
|
|
18
|
+
| PAYLOAD_STATUS.SYNCING;
|
|
19
|
+
latestValidHash: Hash32;
|
|
20
|
+
validationError: string;
|
|
21
|
+
}
|
|
22
|
+
export interface PayloadStatusNoInvalidBlockHash {
|
|
23
|
+
status: Exclude<PAYLOAD_STATUS, PAYLOAD_STATUS.INVALID_BLOCK_HASH>;
|
|
24
|
+
latestValidHash: Hash32;
|
|
25
|
+
validationError: string;
|
|
26
|
+
}
|
|
27
|
+
export interface ExecutionPayloadV1 {
|
|
28
|
+
parentHash: Hash32;
|
|
29
|
+
feeRecipient: Address;
|
|
30
|
+
stateRoot: Bytes32;
|
|
31
|
+
receiptsRoot: Bytes32;
|
|
32
|
+
logsBloom: Bytes256;
|
|
33
|
+
prevRandao: Bytes32;
|
|
34
|
+
blockNumber: Uint64;
|
|
35
|
+
gasLimit: Uint64;
|
|
36
|
+
gasUsed: Uint64;
|
|
37
|
+
timestamp: Uint64;
|
|
38
|
+
extraData: Bytes32;
|
|
39
|
+
baseFeePerGas: Uint64;
|
|
40
|
+
blockHash: Hash32;
|
|
41
|
+
transactions: Bytes[];
|
|
42
|
+
}
|
|
43
|
+
export interface WithdrawalV1 {
|
|
44
|
+
index: Uint64;
|
|
45
|
+
validatorIndex: Uint64;
|
|
46
|
+
address: Address;
|
|
47
|
+
amount: Uint64;
|
|
48
|
+
}
|
|
49
|
+
export interface ExecutionPayloadV2 {
|
|
50
|
+
parentHash: Hash32;
|
|
51
|
+
feeRecipient: Address;
|
|
52
|
+
stateRoot: Bytes32;
|
|
53
|
+
receiptsRoot: Bytes32;
|
|
54
|
+
logsBloom: Bytes256;
|
|
55
|
+
prevRandao: Bytes32;
|
|
56
|
+
blockNumber: Uint64;
|
|
57
|
+
gasLimit: Uint64;
|
|
58
|
+
gasUsed: Uint64;
|
|
59
|
+
timestamp: Uint64;
|
|
60
|
+
extraData: Bytes32;
|
|
61
|
+
baseFeePerGas: Uint64;
|
|
62
|
+
blockHash: Hash32;
|
|
63
|
+
transactions: Bytes[];
|
|
64
|
+
withdrawals: WithdrawalV1[];
|
|
65
|
+
}
|
|
66
|
+
export interface ExecutionPayloadV3 {
|
|
67
|
+
parentHash: Hash32;
|
|
68
|
+
feeRecipient: Address;
|
|
69
|
+
stateRoot: Bytes32;
|
|
70
|
+
receiptsRoot: Bytes32;
|
|
71
|
+
logsBloom: Bytes256;
|
|
72
|
+
prevRandao: Bytes32;
|
|
73
|
+
blockNumber: Uint64;
|
|
74
|
+
gasLimit: Uint64;
|
|
75
|
+
gasUsed: Uint64;
|
|
76
|
+
timestamp: Uint64;
|
|
77
|
+
extraData: Bytes32;
|
|
78
|
+
baseFeePerGas: Uint64;
|
|
79
|
+
blockHash: Hash32;
|
|
80
|
+
transactions: Bytes[];
|
|
81
|
+
withdrawals: WithdrawalV1[];
|
|
82
|
+
blobGasUsed: Uint64;
|
|
83
|
+
excessBlobGas: Uint64;
|
|
84
|
+
}
|
|
85
|
+
export interface ExecutionPayloadV4 {
|
|
86
|
+
parentHash: Hash32;
|
|
87
|
+
feeRecipient: Address;
|
|
88
|
+
stateRoot: Bytes32;
|
|
89
|
+
receiptsRoot: Bytes32;
|
|
90
|
+
logsBloom: Bytes256;
|
|
91
|
+
prevRandao: Bytes32;
|
|
92
|
+
blockNumber: Uint64;
|
|
93
|
+
gasLimit: Uint64;
|
|
94
|
+
gasUsed: Uint64;
|
|
95
|
+
timestamp: Uint64;
|
|
96
|
+
extraData: Bytes32;
|
|
97
|
+
baseFeePerGas: Uint64;
|
|
98
|
+
blockHash: Hash32;
|
|
99
|
+
transactions: Bytes[];
|
|
100
|
+
withdrawals: WithdrawalV1[];
|
|
101
|
+
blobGasUsed: Uint64;
|
|
102
|
+
excessBlobGas: Uint64;
|
|
103
|
+
blockAccessList: Bytes;
|
|
104
|
+
}
|
|
105
|
+
export interface ExecutionPayloadBodyV1 {
|
|
106
|
+
transactions: Bytes[];
|
|
107
|
+
withdrawals?: WithdrawalV1[];
|
|
108
|
+
}
|
|
109
|
+
export interface BlobsBundleV1 {
|
|
110
|
+
commitments: Bytes48[];
|
|
111
|
+
proofs: Bytes48[];
|
|
112
|
+
blobs: Bytes[];
|
|
113
|
+
}
|
|
114
|
+
export interface BlobsBundleV2 {
|
|
115
|
+
commitments: Bytes48[];
|
|
116
|
+
proofs: Bytes48[];
|
|
117
|
+
blobs: Bytes[];
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export { };
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
// Environment setup & latest features
|
|
4
|
+
"lib": [
|
|
5
|
+
"ESNext"
|
|
6
|
+
],
|
|
7
|
+
"target": "ESNext",
|
|
8
|
+
"module": "Preserve",
|
|
9
|
+
"moduleDetection": "force",
|
|
10
|
+
"jsx": "react-jsx",
|
|
11
|
+
"allowJs": true,
|
|
12
|
+
// Bundler mode
|
|
13
|
+
"sourceMap": true,
|
|
14
|
+
"declaration": true,
|
|
15
|
+
"declarationMap": true,
|
|
16
|
+
"moduleResolution": "bundler",
|
|
17
|
+
"outDir": "dist",
|
|
18
|
+
"rootDir": "src",
|
|
19
|
+
"allowImportingTsExtensions": false,
|
|
20
|
+
"verbatimModuleSyntax": true,
|
|
21
|
+
"noEmit": false,
|
|
22
|
+
// Best practices
|
|
23
|
+
"strict": true,
|
|
24
|
+
"skipLibCheck": true,
|
|
25
|
+
"noFallthroughCasesInSwitch": true,
|
|
26
|
+
"noUncheckedIndexedAccess": true,
|
|
27
|
+
"noImplicitOverride": true,
|
|
28
|
+
// Some stricter flags (disabled by default)
|
|
29
|
+
"noUnusedLocals": false,
|
|
30
|
+
"noUnusedParameters": false,
|
|
31
|
+
"noPropertyAccessFromIndexSignature": false
|
|
32
|
+
},
|
|
33
|
+
"include": [
|
|
34
|
+
"src/**/*",
|
|
35
|
+
"global.d.ts"
|
|
36
|
+
],
|
|
37
|
+
"exclude": [
|
|
38
|
+
"example.ts"
|
|
39
|
+
]
|
|
40
|
+
}
|