Socket
Socket
Sign inDemoInstall

abi-wan-kanabi

Package Overview
Dependencies
Maintainers
3
Versions
25
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

abi-wan-kanabi - npm Package Compare versions

Comparing version 1.0.1 to 1.0.2

.vscode/settings.json

33

index.ts

@@ -1,5 +0,30 @@

import {Abi, ExtractAbiFunctionName, FunctionArgs, FunctionRet} from './kanabi';
import {
Abi,
ExtractAbiFunctionNames,
FunctionArgs,
FunctionRet,
ContractFunctions,
} from './kanabi'
export function call<TAbi extends Abi, TFunctionName extends ExtractAbiFunctionName<TAbi>>(abi: TAbi, f: TFunctionName, args: FunctionArgs<TAbi, TFunctionName>): FunctionRet<TAbi, TFunctionName> {
throw new Error('todo')
}
export { Abi } from './kanabi'
export function call<
TAbi extends Abi,
TFunctionName extends ExtractAbiFunctionNames<TAbi>,
>(
abi: TAbi,
f: TFunctionName,
args: FunctionArgs<TAbi, TFunctionName>,
): FunctionRet<TAbi, TFunctionName> {
throw new Error('todo')
}
type TypedCall<TAbi extends Abi> = {
call<TFunctionName extends ExtractAbiFunctionNames<TAbi>>(
method: TFunctionName,
args?: FunctionArgs<TAbi, TFunctionName>,
): Promise<FunctionRet<TAbi, TFunctionName>>
}
export type TypedContract<TAbi extends Abi> = TypedCall<TAbi> &
ContractFunctions<TAbi>

@@ -1,109 +0,336 @@

type Felt = 'felt'
type CairoFunction = 'function'
import {
BigNumberish,
CallOptions,
Calldata,
InvokeFunctionResponse,
InvokeOptions,
Uint256,
} from './starknet'
type MAX_TUPLE_SIZE = 3
export type CairoFelt = 'core::felt252'
type MBits = 8 | 16 | 32
type BigMBits = 64 | 128
export type CairoInt = `${'core::integer::u'}${MBits}`
export type CairoBigInt = `${'core::integer::u'}${BigMBits}`
export type CairoU256 = 'core::integer::u256'
export type CairoAddress = 'core::starknet::contract_address::ContractAddress'
export type CairoFunction = 'function'
export type CairoVoid = '()'
export type CairoBool = 'core::bool'
/// Implementation of tuples
type MAX_TUPLE_SIZE = 20
// Question: why do we need both R and A here ?
type _BuildTuple<
R extends unknown = never,
A extends string = '',
D extends readonly number[] = []
R extends unknown = never,
A extends string = '',
D extends readonly number[] = [],
> = D['length'] extends MAX_TUPLE_SIZE
? `${A})` | R
: A extends ''
? _BuildTuple<R, `(${string}`, [...D, 1]>
: _BuildTuple<`${A})` | R, `${A}, ${string}`, [...D, 1]>
? `${A})` | R
: A extends ''
? _BuildTuple<R, `(${string}`, [...D, 1]>
: _BuildTuple<`${A})` | R, `${A}, ${string}`, [...D, 1]>
type CairoTuple = _BuildTuple
export type CairoTuple = _BuildTuple
type AbiType = Felt | CairoFunction | CairoTuple
type AbiType =
| CairoFelt
| CairoFunction
| CairoInt
| CairoBigInt
| CairoU256
| CairoAddress
| CairoBool
| CairoVoid
type ResolvedAbiType = AbiType
// We have to use string to support nesting
type CairoOptionGeneric<T extends string> = `core::option::Option::<${T}>`
type CairoArrayGeneric<T extends string> = `core::array::Array::<${T}>`
type CairoGeneric<T extends string> =
| CairoOptionGeneric<T>
| CairoArrayGeneric<T>
// Note that Option<Option<number>> = T | undefined | undefined which is the same
// as Option<Option<number>, is this what we want for Option ?
export type Option<T> = T | undefined
type AbiParameter = {
type: string
name: string
name: string
type: string
}
type AbiOutput = {
type: string
}
type AbiStateMutability = 'view' | 'external'
type AbiFunction = {
name: string
inputs: readonly AbiParameter[]
outputs: readonly AbiParameter[]
} & (
| {
type: 'function'
stateMutability?: AbiStateMutability
}
| {
type: 'constructor'
}
)
type: 'function'
name: string
inputs: readonly AbiParameter[]
outputs: readonly AbiOutput[]
state_mutability: AbiStateMutability
}
type AbiEvent = {
type: 'event'
name: string
inputs: readonly AbiParameter[]
}
type AbiMember = {
name: string
offset: number
type: string
name: string
type: string
}
type AbiStruct = {
type: 'struct'
name: string
size: number
members: readonly AbiMember[]
type: 'struct'
name: string
members: readonly AbiMember[]
}
export type Abi = readonly (AbiFunction | AbiStruct)[]
type AbiEnum = {
type: 'enum'
name: string
variants: readonly AbiParameter[]
}
export type Abi = readonly (AbiFunction | AbiStruct | AbiEvent | AbiEnum)[]
/// Implement
type _BuildArgs<TAbi extends Abi, TAbiParam extends readonly AbiParameter[], R extends unknown[]> =
R['length'] extends TAbiParam['length'] ? R : _BuildArgs<TAbi, TAbiParam, [...R, AbiParameterToPrimitiveType<TAbi, TAbiParam[R['length']]>]>
type _BuildArgs<
TAbi extends Abi,
TAbiParam extends readonly AbiParameter[],
R extends unknown[],
> = R['length'] extends TAbiParam['length']
? R
: _BuildArgs<
TAbi,
TAbiParam,
[...R, StringToPrimitiveType<TAbi, TAbiParam[R['length']]['type']>]
>
export type FunctionArgs<TAbi extends Abi, TFunctionName extends ExtractAbiFunctionName<TAbi>> =
_BuildArgs<TAbi, ExtractAbiFunction<TAbi, TFunctionName>['inputs'], []>
export type FunctionArgs<
TAbi extends Abi,
TFunctionName extends ExtractAbiFunctionNames<TAbi>,
> = ExtractAbiFunction<TAbi, TFunctionName>['inputs'] extends readonly []
? []
: _BuildArgs<
TAbi,
ExtractAbiFunction<TAbi, TFunctionName>['inputs'],
[]
> extends [infer T]
? T
: _BuildArgs<TAbi, ExtractAbiFunction<TAbi, TFunctionName>['inputs'], []>
export type FunctionRet<TAbi extends Abi, TFunctionName extends ExtractAbiFunctionName<TAbi>> =
_BuildArgs<TAbi, ExtractAbiFunction<TAbi, TFunctionName>['outputs'], []>
export type FunctionRet<
TAbi extends Abi,
TFunctionName extends ExtractAbiFunctionNames<TAbi>,
> = ExtractAbiFunction<TAbi, TFunctionName>['outputs'] extends readonly []
? void
: StringToPrimitiveType<
TAbi,
ExtractAbiFunction<TAbi, TFunctionName>['outputs'][0]['type']
>
export type ExtractAbiFunctions<TAbi extends Abi> = Extract<TAbi[number], { type: 'function' }>
export type ExtractAbiFunctions<TAbi extends Abi> = Extract<
TAbi[number],
{ type: 'function' }
>
export type ExtractAbiFunctionName<TAbi extends Abi> = ExtractAbiFunctions<TAbi>['name']
export type ExtractAbiFunctionNames<TAbi extends Abi> =
ExtractAbiFunctions<TAbi>['name']
export type ExtractAbiFunction<
TAbi extends Abi,
TFunctionName extends ExtractAbiFunctionName<TAbi>
TAbi extends Abi,
TFunctionName extends ExtractAbiFunctionNames<TAbi>,
> = Extract<ExtractAbiFunctions<TAbi>, { name: TFunctionName }>
export type ExtractAbiStructs<TAbi extends Abi> = Extract<TAbi[number], { type: 'struct' }>
export type ExtractAbiStructs<TAbi extends Abi> = Extract<
TAbi[number],
{ type: 'struct' }
>
export type ExtractAbiStructNames<TAbi extends Abi> = ExtractAbiStructs<TAbi>['name']
export type ExtractAbiStructNames<TAbi extends Abi> =
ExtractAbiStructs<TAbi>['name']
export type ExtractAbiStruct<
TAbi extends Abi,
TStructName extends ExtractAbiStructNames<TAbi>
TAbi extends Abi,
TStructName extends ExtractAbiStructNames<TAbi>,
> = Extract<ExtractAbiStructs<TAbi>, { name: TStructName }>
export type ExtractAbiEnums<TAbi extends Abi> = Extract<
TAbi[number],
{ type: 'enum' }
>
export type ExtractAbiEnumNames<TAbi extends Abi> =
ExtractAbiEnums<TAbi>['name']
export type ExtractAbiEnum<
TAbi extends Abi,
TEnumName extends ExtractAbiEnumNames<TAbi>,
> = Extract<ExtractAbiEnums<TAbi>, { name: TEnumName }>
// Question: why do we need TAbi extends Abi here, it's not used ?
type PrimitiveTypeLookup<TAbi extends Abi> = {
[_ in Felt]: number
[_ in CairoFelt]: BigNumberish
} & {
[_ in CairoFunction]: number
[_ in CairoFunction]: number
} & {
[_ in CairoTuple]: [number, number]
[_ in CairoInt]: number | bigint
} & {
[_ in CairoU256]: number | bigint | Uint256
} & {
[_ in CairoBigInt]: number | bigint
} & {
[_ in CairoAddress]: string
} & {
[_ in CairoVoid]: void
} & {
[_ in CairoBool]: boolean
}
export type AbiTypeToPrimitiveType<TAbi extends Abi, TAbiType extends AbiType> = PrimitiveTypeLookup<TAbi>[TAbiType]
export type AbiParameterToPrimitiveType<
TAbi extends Abi,
TAbiParameter extends AbiParameter
> =
TAbiParameter['type'] extends AbiType
? AbiTypeToPrimitiveType<TAbi, TAbiParameter['type']>
: ExtractAbiStruct<TAbi, TAbiParameter['type']> extends {
type: 'struct',
members: infer TMembers extends readonly AbiMember[]
}
?
{
[Member in TMembers[number] as Member['name']]: AbiParameterToPrimitiveType<TAbi, Member>
}
: unknown
export type AbiTypeToPrimitiveType<
TAbi extends Abi,
TAbiType extends AbiType,
> = PrimitiveTypeLookup<TAbi>[TAbiType]
export type GenericTypeToPrimitiveType<
TAbi extends Abi,
G extends string,
> = G extends CairoOptionGeneric<infer T>
? T extends AbiType
? Option<AbiTypeToPrimitiveType<TAbi, T>>
: Option<StringToPrimitiveType<TAbi, T>>
: G extends CairoArrayGeneric<infer T>
? T extends AbiType
? AbiTypeToPrimitiveType<TAbi, T>[]
: StringToPrimitiveType<TAbi, T>[]
: unknown
export type CairoTupleToPrimitive<
TAbi extends Abi,
T extends string,
> = T extends `(${infer first}, ${infer remaining})`
? [
StringToPrimitiveType<TAbi, first>,
...CairoTupleToPrimitive<TAbi, `(${remaining})`>,
]
: T extends `(${infer first})`
? [StringToPrimitiveType<TAbi, first>]
: [unknown]
// Convert an object {k1: v1, k2: v2, ...} to a union type of objects with each
// a single element {k1: v1} | {k2: v2} | ...
type ObjectToUnion<T extends Record<string, any>> = {
[K in keyof T]: { [Key in K]: T[K] }
}[keyof T]
export type StringToPrimitiveType<
TAbi extends Abi,
T extends string,
> = T extends AbiType
? AbiTypeToPrimitiveType<TAbi, T>
: T extends CairoGeneric<infer _>
? GenericTypeToPrimitiveType<TAbi, T>
: T extends CairoTuple
? CairoTupleToPrimitive<TAbi, T>
: ExtractAbiStruct<TAbi, T> extends never
? ExtractAbiEnum<TAbi, T> extends never
? unknown
: ExtractAbiEnum<TAbi, T> extends {
type: 'enum'
variants: infer TVariants extends readonly AbiParameter[]
}
? ObjectToUnion<{
[Variant in
TVariants[number] as Variant['name']]: StringToPrimitiveType<
TAbi,
Variant['type']
>
}>
: // We should never have a type T where ExtractAbiEnum<TAbi, T>
// return something different than an enum
never
: ExtractAbiStruct<TAbi, T> extends {
type: 'struct'
members: infer TMembers extends readonly AbiMember[]
}
? {
[Member in TMembers[number] as Member['name']]: StringToPrimitiveType<
TAbi,
Member['type']
>
}
: // We should never have a type T where ExtractAbiStruct<TAbi, T>
// return something different than a struct
never
type UnionToIntersection<Union> = (
Union extends unknown
? (arg: Union) => unknown
: never
) extends (arg: infer R) => unknown
? R
: never
export type FunctionCallWithCallData<
TAbi extends Abi,
TAbiFunction extends AbiFunction,
> = (
calldata: Calldata,
) => TAbiFunction['state_mutability'] extends 'view'
? Promise<FunctionRet<TAbi, TAbiFunction['name']>>
: InvokeFunctionResponse
export type ExtractArgs<
TAbi extends Abi,
TAbiFunction extends AbiFunction,
> = TAbiFunction['inputs'] extends infer TInput extends readonly AbiParameter[]
? {
[K3 in
keyof TInput]: TInput[K3] extends infer TInputParam extends AbiParameter
? StringToPrimitiveType<TAbi, TInputParam['type']>
: never
}
: never
export type FunctionCallWithArgs<
TAbi extends Abi,
TAbiFunction extends AbiFunction,
> = (
...args: ExtractArgs<TAbi, TAbiFunction>
) => TAbiFunction['state_mutability'] extends 'view'
? Promise<FunctionRet<TAbi, TAbiFunction['name']>>
: InvokeFunctionResponse
export type FunctionCallWithOptions<
TAbi extends Abi,
TAbiFunction extends AbiFunction,
> = TAbiFunction['state_mutability'] extends 'view'
? (
options?: CallOptions,
...args: ExtractArgs<TAbi, TAbiFunction>
) => Promise<FunctionRet<TAbi, TAbiFunction['name']>>
: (
options?: InvokeOptions,
...args: ExtractArgs<TAbi, TAbiFunction>
) => InvokeFunctionResponse
export type ContractFunctions<TAbi extends Abi> = UnionToIntersection<
{
[K in keyof TAbi]: TAbi[K] extends infer TAbiFunction extends AbiFunction
? {
[K2 in TAbiFunction['name']]: FunctionCallWithArgs<
TAbi,
TAbiFunction
> &
FunctionCallWithCallData<TAbi, TAbiFunction> &
FunctionCallWithOptions<TAbi, TAbiFunction>
}
: never
}[number]
>

33

package.json
{
"name": "abi-wan-kanabi",
"version": "1.0.1",
"version": "1.0.2",
"description": "Abi parser for Cairo smart contracts, based on wagmi abitype",
"main": "index.js",
"bin": {
"generate": "./dist/generate.js"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"generate": "tsc && node dist/generate.js",
"test": "vitest",
"coverage": "vitest run --coverage",
"typecheck": "vitest typecheck",
"format": "rome format . --write"
},

@@ -13,20 +20,24 @@ "repository": {

},
"keywords": [
"abi",
"cairo"
],
"keywords": ["abi", "cairo"],
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/ivpavici/abi-wan-kanabi/issues"
"url": "https://github.com/keep-starknet-strange/abi-wan-kanabi/issues"
},
"homepage": "https://github.com/ivpavici/abi-wan-kanabi#readme",
"homepage": "https://github.com/keep-starknet-strange/abi-wan-kanabi#readme",
"publishConfig": {
"ivpavici:registry": "https://npm.pkg.github.com"
},
"dependencies": {
"typescript": "^4.8.4"
"abi-wan-kanabi": "^1.0.1",
"fs-extra": "^10.0.0",
"rome": "^12.1.3",
"typescript": "^4.9.5",
"yargs": "^17.7.2"
},
"devDependencies": {
"@types/fs-extra": "^11.0.1",
"@types/yargs": "^17.0.24",
"vitest": "^0.30.1"
}
}

@@ -1,4 +0,80 @@

# abi-wan-kanabi
Abi TypeScript parser for Cairo smart contracts, based on [wagmi/abitype](https://github.com/wagmi-dev/abitype).
# ABI-WAN-KANABI
<details>
<summary>Table of Contents</summary>
Big thanks and shoutout to [Francesco](https://github.com/fracek)! :clap:
- [About](#about)
- [Getting Started](#getting-started)
- [Prerequisites](#prerequisites)
- [Build](#build)
- [Demo](#demo)
- [Warning](#warning)
- [Contributing](#contributing)
- [Authors \& contributors](#authors--contributors)
- [Acknowledgements](#acknowledgements)
</details>
## About
Abi-wan-kanabi is an UNLICENSE standalone TypeScript parser for Cairo smart contracts.
It enables on the fly typechecking and autocompletion for contracts call directly in typescript.
Developers can now catch typing mistakes early, prior to executing the call on-chain, and thus enhancing the overall Dapp development experience.
## Getting Started
### Prerequisites
Abiwan is a standalone typescript library. Its only dependence is on typescript version 4.9.5 or higher.
Also, it makes use of BigInt, so the tsconfig.json should target at least ES2020:
```json
// tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"lib": ["ES2020", "ESNext"],
}
}
```
### Build
To use abiwan, you must first generate types from your contracts' ABI json files, for example using the helper script (deprecated):
```bash
./scripts/extract_abi.sh <path>/<to>/<abi>.json <path>/<to>/<other_abi>.json ./
```
This will create a declaration file (.d.ts) for the abi.
You can then import it in any script and you are set to go:
```typescript
import abi from './abi_demo.ts'
import {call} from './kannabi.ts'
call(abi, "balance_of", 5n);
```
> If you think that we should be able to import types directly from the json files, we think so too!
> See this typescript [issue](https://github.com/microsoft/TypeScript/issues/32063) and thumb it up!
### Run tests
```bash
npm run typecheck
```
### Generate `test/example.ts` from `test/example.json`
```bash
npm run generate -- --input test/example.json --output test/example.ts
```
Note: `test/example.json` was generated by `starknet-compile test/example.cairo test/example.json`
### Demo
https://drive.google.com/file/d/1OpIgKlk-okvwJn-dkR2Pq2FvOVwlXTUJ/view?usp=sharing
### Warning
Abiwan is still very young and has not yet been subject to an official release. We do not recommand using it in production yet.
## Contributing
Contributions on abiwan are most welcome!
If you are willing to contribute, please get in touch with one of the project lead or via the repositories [Discussions](https://github.com/keep-starknet-strange/abi-wan-kanabi/discussions/categories/general)
## Acknowledgements
### Authors and Contributors
For a full list of all authors and contributors, see [the contributors page](https://github.com/keep-starknet-strange/abi-wan-kanabi/contributors).
### Special mentions
Big thanks and shoutout to [Francesco](https://github.com/fracek)! :clap: who is at the origin of the project!
### Other projects
Abiwan is greatly influenced by the similar project for EVM-compatible contracts [wagmi/abitype](https://github.com/wagmi-dev/abitype).

@@ -1,92 +0,228 @@

import { call } from '../index';
//import abi from './abi_demo.json';
const ABI = [
{
"members": [
{
"name": "low",
"offset": 0,
"type": "felt"
},
{
"name": "high",
"offset": 1,
"type": "felt"
}
],
"name": "Uint256",
"size": 2,
"type": "struct"
},
{
"inputs": [
{
"name": "par1",
"type": "felt"
},
{
"name": "symbol",
"type": "felt"
},
{
"name": "decimals",
"type": "felt"
},
{
"name": "initial_supply",
"type": "Uint256"
},
{
"name": "recipient",
"type": "felt"
}
],
"name": "constructor",
"outputs": [],
"type": "constructor"
},
{
"inputs": [],
"name": "fun1",
"outputs": [
{
"name": "par1",
"type": "felt"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [{"name": "x", "type": "felt"}, {"name": "y", "type": "felt"}],
"name": "fun2",
"outputs": [
{
"name": "par1",
"type": "felt"
}
],
"stateMutability": "view",
"type": "function"
export const ABI = [
{
type: 'function',
name: 'fn_felt',
inputs: [
{
name: 'felt',
type: 'core::felt252',
},
],
outputs: [],
state_mutability: 'external',
},
{
"inputs": [
{
"name": "account",
"type": "felt"
}
type: 'function',
name: 'fn_felt_u8_bool',
inputs: [
{
name: 'felt',
type: 'core::felt252',
},
{
name: 'int8',
type: 'core::integer::u8',
},
{
name: 'b',
type: 'core::bool',
},
],
"name": "balanceOf",
"outputs": [
{
"name": "balance",
"type": "Uint256"
}
outputs: [],
state_mutability: 'external',
},
{
type: 'function',
name: 'fn_felt_u8_bool_out_address_felt_u8_bool',
inputs: [
{
name: 'felt',
type: 'core::felt252',
},
{
name: 'int8',
type: 'core::integer::u8',
},
{
name: 'boolean',
type: 'core::bool',
},
],
"stateMutability": "view",
"type": "function"
}
outputs: [
{
type: '(core::starknet::contract_address::ContractAddress, core::felt252, core::integer::u8, core::bool)',
},
],
state_mutability: 'view',
},
{
type: 'function',
name: 'fn_felt_out_felt',
inputs: [
{
name: 'felt',
type: 'core::felt252',
},
],
outputs: [
{
type: 'core::felt252',
},
],
state_mutability: 'view',
},
{
type: 'function',
name: 'fn_out_simple_option',
inputs: [],
outputs: [
{
type: 'core::option::Option::<core::integer::u8>',
},
],
state_mutability: 'view',
},
{
type: 'function',
name: 'fn_out_nested_option',
inputs: [],
outputs: [
{
type: 'core::option::Option::<core::option::Option::<core::integer::u8>>',
},
],
state_mutability: 'view',
},
{
type: 'function',
name: 'fn_simple_array',
inputs: [
{
name: 'arg',
type: 'core::array::Array::<core::integer::u8>',
},
],
outputs: [],
state_mutability: 'view',
},
{
type: 'function',
name: 'fn_out_simple_array',
inputs: [],
outputs: [
{
type: 'core::array::Array::<core::integer::u8>',
},
],
state_mutability: 'view',
},
{
type: 'struct',
name: 'example::example::HelloStarknet::TestStruct',
members: [
{
name: 'int128',
type: 'core::integer::u128',
},
{
name: 'felt',
type: 'core::felt252',
},
{
name: 'tuple',
type: '(core::integer::u32, core::integer::u32)',
},
],
},
{
type: 'function',
name: 'fn_struct_array',
inputs: [
{
name: 'arg',
type: 'core::array::Array::<example::example::HelloStarknet::TestStruct>',
},
],
outputs: [],
state_mutability: 'view',
},
{
type: 'function',
name: 'fn_struct',
inputs: [
{
name: 'arg',
type: 'example::example::HelloStarknet::TestStruct',
},
],
outputs: [],
state_mutability: 'view',
},
{
type: 'enum',
name: 'example::example::HelloStarknet::TestEnum',
variants: [
{
name: 'int128',
type: 'core::integer::u128',
},
{
name: 'felt',
type: 'core::felt252',
},
{
name: 'tuple',
type: '(core::integer::u32, core::integer::u32)',
},
],
},
{
type: 'function',
name: 'fn_enum',
inputs: [
{
name: 'arg',
type: 'example::example::HelloStarknet::TestEnum',
},
],
outputs: [],
state_mutability: 'view',
},
{
type: 'function',
name: 'fn_enum_array',
inputs: [
{
name: 'arg',
type: 'core::array::Array::<example::example::HelloStarknet::TestEnum>',
},
],
outputs: [],
state_mutability: 'view',
},
{
type: 'function',
name: 'fn_out_enum_array',
inputs: [],
outputs: [
{
type: 'core::array::Array::<example::example::HelloStarknet::TestEnum>',
},
],
state_mutability: 'view',
},
{
type: 'event',
name: 'TestEvent',
inputs: [
{
name: 'from',
type: 'core::starknet::contract_address::ContractAddress',
},
{
name: 'value',
type: 'core::felt252',
},
],
},
] as const
const [balance] = call(ABI, 'balanceOf', [123]);

@@ -14,4 +14,4 @@ {

/* Language and Environment */
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
"target": "ES2020", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
"lib": ["ES2020", "ESNext"], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
// "jsx": "preserve", /* Specify what JSX code is generated. */

@@ -18,0 +18,0 @@ // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc