From c0a2c553752ef6b38ee85dd23adc36158b3e69ed Mon Sep 17 00:00:00 2001 From: Dan Lynch Date: Thu, 9 May 2024 03:26:14 -0700 Subject: [PATCH] mutations --- .npmignore | 1 + __fixtures__/assetlist.schema.json | 471 ++++++++++++++++++ __fixtures__/assets.json | 119 +++++ __fixtures__/chain.json | 390 +++++++++++++++ .../camel.assets.json.test.ts.snap | 29 ++ .../__snapshots__/camel.assets.test.ts.snap | 29 ++ .../__snapshots__/default-values.test.ts.snap | 126 +++++ __tests__/__snapshots__/includes.test.ts.snap | 218 ++++++++ .../property-rename.test.ts.snap | 60 ++- .../__snapshots__/stringify.json.test.ts.snap | 2 +- .../__snapshots__/stringify.test.ts.snap | 2 +- __tests__/camel.assets.json.test.ts | 94 +--- __tests__/camel.assets.test.ts | 94 +--- __tests__/camel.chain.json.test.ts | 391 +-------------- __tests__/camel.chain.test.ts | 391 +-------------- __tests__/default-values.test.ts | 39 ++ __tests__/expand-paths.test.ts | 115 +++++ __tests__/includes.test.ts | 82 +++ __tests__/property-rename.test.ts | 117 +---- __tests__/stringify.json.test.ts | 46 +- __tests__/stringify.test.ts | 14 +- package.json | 5 +- src/js.ts | 171 ++++++- src/utils.ts | 100 ++++ test-utils/index.ts | 1 + test-utils/interfaces.ts | 90 ++++ types/js.d.ts | 12 +- types/json.d.ts | 9 +- 28 files changed, 2103 insertions(+), 1115 deletions(-) create mode 100644 __fixtures__/assetlist.schema.json create mode 100644 __fixtures__/assets.json create mode 100644 __fixtures__/chain.json create mode 100644 __tests__/__snapshots__/default-values.test.ts.snap create mode 100644 __tests__/__snapshots__/includes.test.ts.snap create mode 100644 __tests__/default-values.test.ts create mode 100644 __tests__/expand-paths.test.ts create mode 100644 __tests__/includes.test.ts create mode 100644 test-utils/index.ts create mode 100644 test-utils/interfaces.ts diff --git a/.npmignore b/.npmignore index b12f994..61f3af2 100644 --- a/.npmignore +++ b/.npmignore @@ -22,6 +22,7 @@ yarn.lock # project files __snapshots__ __fixtures__ +test-utils __tests__ .editorconfig .eslintignore diff --git a/__fixtures__/assetlist.schema.json b/__fixtures__/assetlist.schema.json new file mode 100644 index 0000000..51bcae3 --- /dev/null +++ b/__fixtures__/assetlist.schema.json @@ -0,0 +1,471 @@ +{ + "$id": "https://osmosis.zone/assetlists.schema.json", + "$schema": "https://json-schema.org/draft-07/schema", + "title": "AssetList", + "description": "Asset lists are a similar mechanism to allow frontends and other UIs to fetch metadata associated with Cosmos SDK denoms, especially for assets sent over IBC.", + "type": "object", + "required": [ + "chain_name", + "assets" + ], + "properties": { + "$schema": { + "type": "string", + "pattern": "^(\\.\\./)+assetlist\\.schema\\.json$" + }, + "chain_name": { + "type": "string" + }, + "assets": { + "type": "array", + "items": { + "$ref": "#/$defs/asset" + }, + "minContains": 1 + } + }, + "additionalProperties": false, + "$defs": { + "asset": { + "type": "object", + "required": [ + "denom_units", + "base", + "display", + "name", + "symbol" + ], + "properties": { + "deprecated": { + "type": "boolean", + "description": "[OPTIONAL] Whether the asset has been deprecated for use. For readability, it is best to omit this property unless TRUE." + }, + "description": { + "type": "string", + "description": "[OPTIONAL] A short description of the asset" + }, + "extended_description": { + "type": "string", + "description": "[OPTIONAL] A long description of the asset" + }, + "denom_units": { + "type": "array", + "items": { + "$ref": "#/$defs/denom_unit" + }, + "minContains": 1 + }, + "type_asset": { + "type": "string", + "enum": [ + "sdk.coin", + "cw20", + "erc20", + "ics20", + "snip20", + "snip25", + "bitcoin-like", + "evm-base", + "svm-base", + "substrate" + ], + "default": "sdk.coin", + "description": "[OPTIONAL] The potential options for type of asset. By default, assumes sdk.coin" + }, + "address": { + "type": "string", + "description": "[OPTIONAL] The address of the asset. Only required for type_asset : cw20, snip20" + }, + "base": { + "type": "string", + "description": "The base unit of the asset. Must be in denom_units." + }, + "name": { + "type": "string", + "description": "The project name of the asset. For example Bitcoin.", + "maxLength": 42 + }, + "display": { + "type": "string", + "description": "The human friendly unit of the asset. Must be in denom_units." + }, + "symbol": { + "type": "string", + "description": "The symbol of an asset. For example BTC." + }, + "traces": { + "type": "array", + "description": "The origin of the asset, starting with the index, and capturing all transitions in form and location.", + "items": { + "anyOf": [ + { + "$ref": "#/$defs/ibc_transition" + }, + { + "$ref": "#/$defs/ibc_cw20_transition" + }, + { + "$ref": "#/$defs/non_ibc_transition" + } + ] + }, + "minContains": 1 + }, + "ibc": { + "type": "object", + "description": "[OPTIONAL] IBC Channel between src and dst between chain", + "required": [ + "source_channel", + "dst_channel", + "source_denom" + ], + "properties": { + "source_channel": { + "type": "string" + }, + "dst_channel": { + "type": "string" + }, + "source_denom": { + "type": "string" + } + }, + "additionalProperties": false + }, + "logo_URIs": { + "type": "object", + "properties": { + "png": { + "type": "string", + "format": "uri-reference", + "pattern": "^https://raw\\.githubusercontent\\.com/cosmos/chain-registry/master/(|testnets/|_non-cosmos/)[a-z0-9]+/images/.+\\.png$" + }, + "svg": { + "type": "string", + "format": "uri-reference", + "pattern": "^https://raw\\.githubusercontent\\.com/cosmos/chain-registry/master/(|testnets/|_non-cosmos/)[a-z0-9]+/images/.+\\.svg$" + } + }, + "additionalProperties": false + }, + "images": { + "type": "array", + "items": { + "type": "object", + "properties": { + "image_sync": { + "$ref": "#/$defs/pointer" + }, + "png": { + "type": "string", + "format": "uri-reference", + "pattern": "^https://raw\\.githubusercontent\\.com/cosmos/chain-registry/master/(|testnets/|_non-cosmos/)[a-z0-9]+/images/.+\\.png$" + }, + "svg": { + "type": "string", + "format": "uri-reference", + "pattern": "^https://raw\\.githubusercontent\\.com/cosmos/chain-registry/master/(|testnets/|_non-cosmos/)[a-z0-9]+/images/.+\\.svg$" + }, + "theme": { + "type": "object", + "properties": { + "primary_color_hex": { + "type": "string", + "pattern": "^#[0-9a-fA-F]{6}$" + }, + "circle": { + "type": "boolean" + }, + "dark_mode": { + "type": "boolean" + } + }, + "minProperties": 1, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + "minItems": 1 + }, + "coingecko_id": { + "type": "string", + "description": "[OPTIONAL] The coingecko id to fetch asset data from coingecko v3 api. See https://api.coingecko.com/api/v3/coins/list" + }, + "keywords": { + "type": "array", + "items": { + "type": "string" + }, + "minContains": 1, + "maxContains": 20 + }, + "socials": { + "type": "object", + "minProperties": 1, + "properties": { + "website": { + "type": "string", + "format": "uri" + }, + "twitter": { + "type": "string", + "format": "uri" + } + } + } + }, + "additionalProperties": false, + "if": { + "required": [ + "type_asset" + ], + "properties": { + "type_asset": { + "enum": [ + "erc20", + "cw20", + "snip20" + ] + } + } + }, + "then": { + "required": [ + "address" + ] + } + }, + "denom_unit": { + "type": "object", + "required": [ + "denom", + "exponent" + ], + "properties": { + "denom": { + "type": "string" + }, + "exponent": { + "type": "integer" + }, + "aliases": { + "type": "array", + "items": { + "type": "string" + }, + "minContains": 1 + } + }, + "additionalProperties": false + }, + "pointer": { + "type": "object", + "description": "The (primary) key used to identify an object within the Chain Registry.", + "required": [ + "chain_name" + ], + "properties": { + "chain_name": { + "type": "string", + "description": "The chain name or platform from which the object resides. E.g., 'cosmoshub', 'ethereum', 'forex', or 'nasdaq'" + }, + "base_denom": { + "type": "string", + "description": "The base denom of the asset from which the object originates. E.g., when describing ATOM from Cosmos Hub, specify 'uatom', NOT 'atom' nor 'ATOM'; base units are unique per platform." + } + }, + "additionalProperties": false + }, + "ibc_transition": { + "type": "object", + "required": [ + "type", + "counterparty", + "chain" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "ibc" + ] + }, + "counterparty": { + "type": "object", + "required": [ + "chain_name", + "base_denom", + "channel_id" + ], + "properties": { + "chain_name": { + "type": "string", + "description": "The name of the counterparty chain. (must match exactly the chain name used in the Chain Registry)" + }, + "base_denom": { + "type": "string", + "description": "The base unit of the asset on its source platform. E.g., when describing ATOM from Cosmos Hub, specify 'uatom', NOT 'atom' nor 'ATOM'; base units are unique per platform." + }, + "channel_id": { + "type": "string", + "pattern": "^channel-(JEnb|\\d+)$", + "description": "The counterparty IBC transfer channel(, e.g., 'channel-1')." + } + }, + "additionalProperties": false + }, + "chain": { + "type": "object", + "required": [ + "channel_id", + "path" + ], + "properties": { + "channel_id": { + "type": "string", + "pattern": "^channel-\\d+$", + "description": "The chain's IBC transfer channel(, e.g., 'channel-1')." + }, + "path": { + "type": "string", + "description": "The port/channel/denom input string that generates the 'ibc/...' denom." + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + "ibc_cw20_transition": { + "type": "object", + "required": [ + "type", + "counterparty", + "chain" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "ibc-cw20" + ] + }, + "counterparty": { + "type": "object", + "required": [ + "chain_name", + "base_denom", + "port", + "channel_id" + ], + "properties": { + "chain_name": { + "type": "string", + "description": "The name of the counterparty chain. (must match exactly the chain name used in the Chain Registry)" + }, + "base_denom": { + "type": "string", + "description": "The base unit of the asset on its source platform. E.g., when describing ATOM from Cosmos Hub, specify 'uatom', NOT 'atom' nor 'ATOM'; base units are unique per platform." + }, + "port": { + "type": "string", + "description": "The port used to transfer IBC assets; often 'transfer', but sometimes varies, e.g., for outgoing cw20 transfers." + }, + "channel_id": { + "type": "string", + "pattern": "^channel-\\d+$", + "description": "The counterparty IBC transfer channel(, e.g., 'channel-1')." + } + }, + "additionalProperties": false + }, + "chain": { + "type": "object", + "required": [ + "port", + "channel_id", + "path" + ], + "properties": { + "port": { + "type": "string", + "description": "The port used to transfer IBC assets; often 'transfer', but sometimes varies, e.g., for outgoing cw20 transfers." + }, + "channel_id": { + "type": "string", + "pattern": "^channel-\\d+$", + "description": "The chain's IBC transfer channel(, e.g., 'channel-1')." + }, + "path": { + "type": "string", + "description": "The port/channel/denom input string that generates the 'ibc/...' denom." + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + "non_ibc_transition": { + "type": "object", + "required": [ + "type", + "counterparty", + "provider" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "bridge", + "liquid-stake", + "synthetic", + "wrapped", + "additional-mintage", + "test-mintage" + ] + }, + "counterparty": { + "type": "object", + "required": [ + "chain_name", + "base_denom" + ], + "properties": { + "chain_name": { + "type": "string", + "description": "The chain or platform from which the asset originates. E.g., 'cosmoshub', 'ethereum', 'forex', or 'nasdaq'" + }, + "base_denom": { + "type": "string" + }, + "contract": { + "type": "string", + "description": "The contract address where the transition takes place, where applicable. E.g., The Ethereum contract that locks up the asset while it's minted on another chain." + } + }, + "additionalProperties": false + }, + "chain": { + "type": "object", + "required": [ + "contract" + ], + "properties": { + "contract": { + "type": "string", + "description": "The contract address where the transition takes place, where applicable. E.g., The Ethereum contract that locks up the asset while it's minted on another chain." + } + }, + "additionalProperties": false + }, + "provider": { + "type": "string", + "description": "The entity offering the service. E.g., 'Gravity Bridge' [Network] or 'Tether' [Company]." + } + }, + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/__fixtures__/assets.json b/__fixtures__/assets.json new file mode 100644 index 0000000..9046958 --- /dev/null +++ b/__fixtures__/assets.json @@ -0,0 +1,119 @@ +{ + "$schema": "../assetlist.schema.json", + "chain_name": "comdex", + "assets": [ + { + "description": "Native Token of Comdex Protocol", + "denom_units": [ + { + "denom": "ucmdx", + "exponent": 0 + }, + { + "denom": "cmdx", + "exponent": 6 + } + ], + "base": "ucmdx", + "name": "Comdex", + "display": "cmdx", + "symbol": "CMDX", + "logo_URIs": { + "png": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmdx.png", + "svg": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmdx.svg" + }, + "coingecko_id": "comdex", + "images": [ + { + "png": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmdx.png", + "svg": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmdx.svg" + } + ] + }, + { + "type_asset": "sdk.Factory", + "description": "Governance Token of Harbor protocol on Comdex network", + "denom_units": [ + { + "denom": "uharbor", + "exponent": 0 + }, + { + "denom": "harbor", + "exponent": 6 + } + ], + "base": "uharbor", + "name": "Harbor", + "display": "harbor", + "symbol": "HARBOR", + "logo_URIs": { + "png": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/harbor.png", + "svg": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/harbor.svg" + }, + "coingecko_id": "harbor-2", + "images": [ + { + "png": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/harbor.png", + "svg": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/harbor.svg" + } + ] + }, + { + "description": "Stable Token of Harbor protocol on Comdex network", + "denom_units": [ + { + "denom": "ucmst", + "exponent": 0 + }, + { + "denom": "cmst", + "exponent": 6 + } + ], + "base": "ucmst", + "name": "CMST", + "display": "cmst", + "symbol": "CMST", + "logo_URIs": { + "png": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.png", + "svg": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.svg" + }, + "coingecko_id": "composite", + "images": [ + { + "png": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.png", + "svg": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.svg" + } + ] + }, + { + "description": "My ibc token", + "denom_units": [ + { + "denom": "uibc", + "exponent": 0 + }, + { + "denom": "ibc", + "exponent": 6 + } + ], + "base": "ibc/A358FDF578F3483381C3191F86E4C6859E76100", + "name": "IBC", + "display": "ibc", + "symbol": "IBC", + "logo_URIs": { + "png": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.png", + "svg": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.svg" + }, + "coingecko_id": "ibc", + "images": [ + { + "png": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.png", + "svg": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.svg" + } + ] + } + ] +} \ No newline at end of file diff --git a/__fixtures__/chain.json b/__fixtures__/chain.json new file mode 100644 index 0000000..159e1a0 --- /dev/null +++ b/__fixtures__/chain.json @@ -0,0 +1,390 @@ +{ + "$schema": "../chain.schema.json", + "chain_name": "comdex", + "status": "live", + "network_type": "mainnet", + "website": "https://comdex.one/", + "pretty_name": "Comdex", + "chain_id": "comdex-1", + "bech32_prefix": "comdex", + "slip44": 118, + "fees": { + "fee_tokens": [ + { + "denom": "ucmdx", + "fixed_min_gas_price": 0, + "low_gas_price": 0, + "average_gas_price": 0.025, + "high_gas_price": 0.04 + } + ] + }, + "staking": { + "staking_tokens": [ + { + "denom": "ucmdx" + } + ] + }, + "codebase": { + "git_repo": "https://github.com/comdex-official/comdex", + "recommended_version": "v13.4.0", + "compatible_versions": [ + "v13.4.0" + ], + "binaries": { + "linux/amd64": "https://github.com/comdex-official/comdex/releases/download/v13.4.0/comdex-linux-amd64.tar.gz" + }, + "cosmos_sdk_version": "v0.47.5", + "consensus": { + "type": "cometbft", + "version": "0.37.2" + }, + "cosmwasm_version": "v0.41.0", + "cosmwasm_enabled": true, + "genesis": { + "genesis_url": "https://comdex-mainnet-genesis.s3.ap-southeast-1.amazonaws.com/genesis.json" + }, + "versions": [ + { + "name": "v9.0.0", + "recommended_version": "v9.0.0", + "compatible_versions": [ + "v9.0.0" + ], + "cosmwasm_enabled": true, + "next_version_name": "v10.0.0" + }, + { + "name": "v10.0.0", + "recommended_version": "v10.0.0", + "compatible_versions": [ + "v10.0.0" + ], + "cosmwasm_enabled": true, + "next_version_name": "v11.5.0" + }, + { + "name": "v11.5.0", + "height": 8184000, + "proposal": 154, + "recommended_version": "v11.5.2", + "compatible_versions": [ + "v11.5.2" + ], + "cosmwasm_enabled": true, + "next_version_name": "v13.3.0" + }, + { + "name": "v13.3.0", + "proposal": 216, + "height": 10981900, + "recommended_version": "v13.4.0", + "compatible_versions": [ + "v13.4.0" + ], + "binaries": { + "linux/amd64": "https://github.com/comdex-official/comdex/releases/download/v13.4.0/comdex-linux-amd64.tar.gz" + }, + "cosmos_sdk_version": "v0.47.5", + "consensus": { + "type": "cometbft", + "version": "0.37.2" + }, + "cosmwasm_version": "v0.41.0", + "cosmwasm_enabled": true, + "next_version_name": "" + } + ] + }, + "daemon_name": "comdex", + "node_home": "$HOME/.comdex", + "key_algos": [ + "secp256k1" + ], + "logo_URIs": { + "png": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmdx.png", + "svg": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmdx.svg" + }, + "peers": { + "seeds": [ + { + "id": "7ca14a1d156299999eba9c394ca060368022d52f", + "address": "54.194.178.110:26656" + }, + { + "id": "ade4d8bc8cbe014af6ebdf3cb7b1e9ad36f412c0", + "address": "seeds.polkachu.com:13156", + "provider": "Polkachu" + }, + { + "id": "c30dacf15e97a30b78792c7fa817fd2ef529b820", + "address": "comdex.seed.stavr.tech:2026", + "provider": "🔥STAVR🔥" + }, + { + "id": "20e1000e88125698264454a884812746c2eb4807", + "address": "seeds.lavenderfive.com:13156", + "provider": "Lavender.Five Nodes 🐝" + }, + { + "id": "ebc272824924ea1a27ea3183dd0b9ba713494f83", + "address": "comdex-mainnet-seed.autostake.com:26776", + "provider": "AutoStake 🛡️ Slash Protected" + }, + { + "id": "6596d143fd128b2394b27cd7846bda099ca5a193", + "address": "seeds.goldenratiostaking.net:1621", + "provider": "Golden Ratio Staking" + }, + { + "id": "8542cd7e6bf9d260fef543bc49e59be5a3fa9074", + "address": "seed.publicnode.com:26656", + "provider": "Allnodes ⚡️ Nodes & Staking" + }, + { + "id": "c28827cb96c14c905b127b92065a3fb4cd77d7f6", + "address": "seeds.whispernode.com:13156", + "provider": "WhisperNode 🤐" + }, + { + "id": "88ba33fbdf0279efaf27cff629f3cf72814d4069", + "address": "seed-comdex-01.stakeflow.io:10007", + "provider": "Stakeflow" + }, + { + "id": "df949a46ae6529ae1e09b034b49716468d5cc7e9", + "address": "seeds.stakerhouse.com:10456", + "provider": "StakerHouse" + } + ], + "persistent_peers": [ + { + "id": "d478882a80674fa10a32da63cc20cae13e3a2a57", + "address": "43.204.0.243:26656" + }, + { + "id": "d8b74791ee56f1b345d822f62bd9bc969668d8df", + "address": "194.163.128.55:36656" + }, + { + "id": "ebc272824924ea1a27ea3183dd0b9ba713494f83", + "address": "comdex-mainnet-peer.autostake.com:26776", + "provider": "AutoStake 🛡️ Slash Protecteds" + }, + { + "id": "88ba33fbdf0279efaf27cff629f3cf72814d4069", + "address": "peer-comdex-01.stakeflow.io:10007", + "provider": "Stakeflow" + } + ] + }, + "apis": { + "rpc": [ + { + "address": "https://rpc.comdex.one", + "provider": "comdex" + }, + { + "address": "https://comdex-rpc.polkachu.com", + "provider": "Polkachu" + }, + { + "address": "https://comdex.rpc.m.stavr.tech", + "provider": "🔥STAVR🔥" + }, + { + "address": "https://rpc.comdex.chaintools.tech/", + "provider": "ChainTools" + }, + { + "address": "https://comdex-rpc.lavenderfive.com/", + "provider": "Lavender.Five Nodes 🐝" + }, + { + "address": "https://rpc-comdex.cosmos-spaces.cloud", + "provider": "Cosmos Spaces" + }, + { + "address": "https://rpc-comdex.whispernode.com:443", + "provider": "WhisperNode 🤐" + }, + { + "address": "https://comdex-mainnet-rpc.autostake.com:443", + "provider": "AutoStake 🛡️ Slash Protected" + }, + { + "address": "https://comdex-rpc.w3coins.io", + "provider": "w3coins" + }, + { + "address": "https://comdex-rpc.stakerhouse.com", + "provider": "StakerHouse" + }, + { + "address": "https://comdex-rpc.publicnode.com:443", + "provider": "Allnodes ⚡️ Nodes & Staking" + }, + { + "address": "https://rpc-comdex-01.stakeflow.io", + "provider": "Stakeflow" + }, + { + "address": "https://comdex-rpc.validatornode.com", + "provider": "ValidatorNode" + } + ], + "rest": [ + { + "address": "https://rest.comdex.one", + "provider": "comdex" + }, + { + "address": "https://api.comdex.chaintools.tech/", + "provider": "ChainTools" + }, + { + "address": "https://comdex-api.polkachu.com", + "provider": "Polkachu" + }, + { + "address": "https://comdex.api.m.stavr.tech", + "provider": "🔥STAVR🔥" + }, + { + "address": "https://comdex-api.lavenderfive.com/", + "provider": "Lavender.Five Nodes 🐝" + }, + { + "address": "https://api-comdex.cosmos-spaces.cloud", + "provider": "Cosmos Spaces" + }, + { + "address": "https://comdex-mainnet-lcd.autostake.com:443", + "provider": "AutoStake 🛡️ Slash Protected" + }, + { + "address": "https://lcd-comdex.whispernode.com:443", + "provider": "WhisperNode 🤐" + }, + { + "address": "https://comdex-api.w3coins.io", + "provider": "w3coins" + }, + { + "address": "https://comdex-rest.stakerhouse.com", + "provider": "StakerHouse" + }, + { + "address": "https://comdex-rest.publicnode.com", + "provider": "Allnodes ⚡️ Nodes & Staking" + }, + { + "address": "https://api-comdex-01.stakeflow.io", + "provider": "Stakeflow" + }, + { + "address": "https://comdex-api.validatornode.com", + "provider": "ValidatorNode" + } + ], + "grpc": [ + { + "address": "grpc-comdex-ia.cosmosia.notional.ventures:443", + "provider": "Notional" + }, + { + "address": "comdex.grpcui.chaintools.host:443", + "provider": "ChainTools" + }, + { + "address": "comdex-grpc.polkachu.com:13190", + "provider": "Polkachu" + }, + { + "address": "comdex.grpc.m.stavr.tech:104", + "provider": "🔥STAVR🔥" + }, + { + "address": "grpc-comdex.cosmos-spaces.cloud:2300", + "provider": "Cosmos Spaces" + }, + { + "address": "comdex-grpc.lavenderfive.com:443", + "provider": "Lavender.Five Nodes 🐝" + }, + { + "address": "comdex-mainnet-lcd.autostake.com:443", + "provider": "AutoStake 🛡️ Slash Protected" + }, + { + "address": "comdex-grpc.w3coins.io:13190", + "provider": "w3coins" + }, + { + "address": "comdex-grpc.publicnode.com:443", + "provider": "Allnodes ⚡️ Nodes & Staking" + }, + { + "address": "grpc-comdex-01.stakeflow.io:10002", + "provider": "Stakeflow" + }, + { + "address": "comdex-grpc.stakerhouse.com:443", + "provider": "StakerHouse" + } + ] + }, + "explorers": [ + { + "kind": "ezstaking", + "url": "https://ezstaking.app/comdex", + "tx_page": "https://ezstaking.app/comdex/txs/${txHash}", + "account_page": "https://ezstaking.app/comdex/account/${accountAddress}" + }, + { + "kind": "mintscan", + "url": "https://www.mintscan.io/comdex", + "tx_page": "https://www.mintscan.io/comdex/transactions/${txHash}", + "account_page": "https://www.mintscan.io/comdex/accounts/${accountAddress}" + }, + { + "kind": "🔥STAVR🔥", + "url": "https://explorer.stavr.tech/Comdex-Mainnet", + "tx_page": "https://explorer.stavr.tech/Comdex-Mainnet/txs/${txHash}", + "account_page": "https://explorer.stavr.tech/Comdex-Mainnet/accounts/${accountAddress}" + }, + { + "kind": "aneka", + "url": "https://comdex.aneka.io/", + "tx_page": "https://comdex.aneka.io/txs/${txHash}" + }, + { + "kind": "ping.pub", + "url": "https://ping.pub/comdex", + "tx_page": "https://ping.pub/comdex/tx/${txHash}" + }, + { + "kind": "atomscan", + "url": "https://atomscan.com/comdex", + "tx_page": "https://atomscan.com/comdex/transactions/${txHash}", + "account_page": "https://atomscan.com/comdex/accounts/${accountAddress}" + }, + { + "kind": "Stakeflow", + "url": "https://stakeflow.io/comdex", + "account_page": "https://stakeflow.io/comdex/accounts/${accountAddress}" + }, + { + "kind": "ValidatorNode", + "url": "https://explorer.validatornode.com/comdex", + "tx_page": "https://explorer.validatornode.com/comdex/tx/${txHash}" + } + ], + "images": [ + { + "png": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmdx.png", + "svg": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmdx.svg" + } + ] +} \ No newline at end of file diff --git a/__tests__/__snapshots__/camel.assets.json.test.ts.snap b/__tests__/__snapshots__/camel.assets.json.test.ts.snap index f4de76a..5e95973 100644 --- a/__tests__/__snapshots__/camel.assets.json.test.ts.snap +++ b/__tests__/__snapshots__/camel.assets.json.test.ts.snap @@ -34,6 +34,7 @@ exports[`assetlist 1`] = ` ] }, { + "typeAsset": "sdk.Factory", "description": "Governance Token of Harbor protocol on Comdex network", "denomUnits": [ { @@ -88,6 +89,34 @@ exports[`assetlist 1`] = ` "svg": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.svg" } ] + }, + { + "description": "My ibc token", + "denomUnits": [ + { + "denom": "uibc", + "exponent": 0 + }, + { + "denom": "ibc", + "exponent": 6 + } + ], + "base": "ibc/A358FDF578F3483381C3191F86E4C6859E76100", + "name": "IBC", + "display": "ibc", + "symbol": "IBC", + "logoURIs": { + "png": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.png", + "svg": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.svg" + }, + "coingeckoId": "ibc", + "images": [ + { + "png": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.png", + "svg": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.svg" + } + ] } ] }" diff --git a/__tests__/__snapshots__/camel.assets.test.ts.snap b/__tests__/__snapshots__/camel.assets.test.ts.snap index 8c390a3..3f9edc4 100644 --- a/__tests__/__snapshots__/camel.assets.test.ts.snap +++ b/__tests__/__snapshots__/camel.assets.test.ts.snap @@ -34,6 +34,7 @@ exports[`assetlist 1`] = ` ] }, { + typeAsset: 'sdk.Factory', description: 'Governance Token of Harbor protocol on Comdex network', denomUnits: [ { @@ -88,6 +89,34 @@ exports[`assetlist 1`] = ` svg: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.svg' } ] + }, + { + description: 'My ibc token', + denomUnits: [ + { + denom: 'uibc', + exponent: 0 + }, + { + denom: 'ibc', + exponent: 6 + } + ], + base: 'ibc/A358FDF578F3483381C3191F86E4C6859E76100', + name: 'IBC', + display: 'ibc', + symbol: 'IBC', + logoURIs: { + png: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.png', + svg: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.svg' + }, + coingeckoId: 'ibc', + images: [ + { + png: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.png', + svg: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.svg' + } + ] } ] }" diff --git a/__tests__/__snapshots__/default-values.test.ts.snap b/__tests__/__snapshots__/default-values.test.ts.snap new file mode 100644 index 0000000..2dc73f5 --- /dev/null +++ b/__tests__/__snapshots__/default-values.test.ts.snap @@ -0,0 +1,126 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`defaultValue 1`] = ` +"{ + $schema: '../assetlist.schema.json', + chainName: 'comdex', + assets: [ + { + description: 'Native Token of Comdex Protocol', + denomUnits: [ + { + denom: 'ucmdx', + exponent: 0 + }, + { + denom: 'cmdx', + exponent: 6 + } + ], + base: 'ucmdx', + name: 'Comdex', + display: 'cmdx', + symbol: 'CMDX', + logoURIs: { + png: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmdx.png', + svg: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmdx.svg' + }, + coingeckoId: 'comdex', + images: [ + { + png: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmdx.png', + svg: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmdx.svg' + } + ], + assetType: 'unknown' + }, + { + assetType: 'sdk.Factory', + description: 'Governance Token of Harbor protocol on Comdex network', + denomUnits: [ + { + denom: 'uharbor', + exponent: 0 + }, + { + denom: 'harbor', + exponent: 6 + } + ], + base: 'uharbor', + name: 'Harbor', + display: 'harbor', + symbol: 'HARBOR', + logoURIs: { + png: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/harbor.png', + svg: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/harbor.svg' + }, + coingeckoId: 'harbor-2', + images: [ + { + png: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/harbor.png', + svg: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/harbor.svg' + } + ] + }, + { + description: 'Stable Token of Harbor protocol on Comdex network', + denomUnits: [ + { + denom: 'ucmst', + exponent: 0 + }, + { + denom: 'cmst', + exponent: 6 + } + ], + base: 'ucmst', + name: 'CMST', + display: 'cmst', + symbol: 'CMST', + logoURIs: { + png: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.png', + svg: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.svg' + }, + coingeckoId: 'composite', + images: [ + { + png: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.png', + svg: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.svg' + } + ], + assetType: 'unknown' + }, + { + description: 'My ibc token', + denomUnits: [ + { + denom: 'uibc', + exponent: 0 + }, + { + denom: 'ibc', + exponent: 6 + } + ], + base: 'ibc/A358FDF578F3483381C3191F86E4C6859E76100', + name: 'IBC', + display: 'ibc', + symbol: 'IBC', + logoURIs: { + png: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.png', + svg: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.svg' + }, + coingeckoId: 'ibc', + images: [ + { + png: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.png', + svg: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.svg' + } + ], + assetType: 'ibc' + } + ] +}" +`; diff --git a/__tests__/__snapshots__/includes.test.ts.snap b/__tests__/__snapshots__/includes.test.ts.snap new file mode 100644 index 0000000..35a8c5c --- /dev/null +++ b/__tests__/__snapshots__/includes.test.ts.snap @@ -0,0 +1,218 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AssetList Modification 1`] = ` +"{ + assets: [ + { + denomUnits: [ + { + denom: 'ucmdx' + }, + { + denom: 'cmdx' + } + ], + base: 'ucmdx' + }, + { + assetType: 'sdk.Factory', + denomUnits: [ + { + denom: 'uharbor' + }, + { + denom: 'harbor' + } + ], + base: 'uharbor' + }, + { + denomUnits: [ + { + denom: 'ucmst' + }, + { + denom: 'cmst' + } + ], + base: 'ucmst' + }, + { + denomUnits: [ + { + denom: 'uibc' + }, + { + denom: 'ibc' + } + ], + base: 'ibc/A358FDF578F3483381C3191F86E4C6859E76100' + } + ] +}" +`; + +exports[`AssetList Modification 2 1`] = ` +"{ + assets: [ + { + denomUnits: [ + { + denom: 'ucmdx', + exponent: 0 + }, + { + denom: 'cmdx', + exponent: 6 + } + ], + base: 'ucmdx' + }, + { + assetType: 'sdk.Factory', + denomUnits: [ + { + denom: 'uharbor', + exponent: 0 + }, + { + denom: 'harbor', + exponent: 6 + } + ], + base: 'uharbor' + }, + { + denomUnits: [ + { + denom: 'ucmst', + exponent: 0 + }, + { + denom: 'cmst', + exponent: 6 + } + ], + base: 'ucmst' + }, + { + denomUnits: [ + { + denom: 'uibc', + exponent: 0 + }, + { + denom: 'ibc', + exponent: 6 + } + ], + base: 'ibc/A358FDF578F3483381C3191F86E4C6859E76100' + } + ] +}" +`; + +exports[`AssetList Modification 3 1`] = ` +"{ + assets: [ + { + denomUnits: [ + { + denom: 'ucmdx', + exponent: 0 + }, + { + denom: 'cmdx', + exponent: 6 + } + ], + logos: { + png: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmdx.png' + } + }, + { + denomUnits: [ + { + denom: 'uharbor', + exponent: 0 + }, + { + denom: 'harbor', + exponent: 6 + } + ], + logos: { + png: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/harbor.png' + } + }, + { + denomUnits: [ + { + denom: 'ucmst', + exponent: 0 + }, + { + denom: 'cmst', + exponent: 6 + } + ], + logos: { + png: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.png' + } + }, + { + denomUnits: [ + { + denom: 'uibc', + exponent: 0 + }, + { + denom: 'ibc', + exponent: 6 + } + ], + logos: { + png: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.png' + } + } + ] +}" +`; + +exports[`Chain Modification 3 1`] = ` +"{ + chainName: 'comdex', + prettyName: 'Comdex', + chainId: 'comdex-1', + bech32Prefix: 'comdex', + fees: { + feeTokens: [ + { + denom: 'ucmdx', + fixedMinGasPrice: 0, + lowGasPrice: 0, + averageGasPrice: 0.025, + highGasPrice: 0.04 + } + ] + }, + codebase: { + cosmwasmVersion: 'v0.41.0', + cosmwasmEnabled: true, + versions: [ + { + name: 'v9.0.0' + }, + { + name: 'v10.0.0' + }, + { + name: 'v11.5.0' + }, + { + name: 'v13.3.0' + } + ] + } +}" +`; diff --git a/__tests__/__snapshots__/property-rename.test.ts.snap b/__tests__/__snapshots__/property-rename.test.ts.snap index 570eeca..a58f21d 100644 --- a/__tests__/__snapshots__/property-rename.test.ts.snap +++ b/__tests__/__snapshots__/property-rename.test.ts.snap @@ -34,7 +34,7 @@ exports[`assetlist 1`] = ` ] }, { - typeAsset: 'sdk.Coin', + typeAsset: 'sdk.Factory', description: 'Governance Token of Harbor protocol on Comdex network', denominations: [ { @@ -89,6 +89,34 @@ exports[`assetlist 1`] = ` svg: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.svg' } ] + }, + { + description: 'My ibc token', + denominations: [ + { + denom: 'uibc', + exponent: 0 + }, + { + denom: 'ibc', + exponent: 6 + } + ], + base: 'ibc/A358FDF578F3483381C3191F86E4C6859E76100', + name: 'IBC', + display: 'ibc', + symbol: 'IBC', + logoURIs: { + png: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.png', + svg: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.svg' + }, + coingeckoId: 'ibc', + images: [ + { + png: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.png', + svg: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.svg' + } + ] } ] }" @@ -128,7 +156,7 @@ exports[`replacer 1`] = ` ] }, { - typeAsset: 'sdk.Coin', + typeAsset: 'sdk.Factory', description: 'Governance Token of Harbor protocol on Comdex network', denominations: [ { @@ -183,6 +211,34 @@ exports[`replacer 1`] = ` svg: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.svg' } ] + }, + { + description: 'My ibc token', + denominations: [ + { + denom: 'uibc', + exponent: 0 + }, + { + denom: 'ibc', + exponent: 6 + } + ], + base: 'ibc/A358FDF578F3483381C3191F86E4C6859E76100', + name: 'IBC', + display: 'ibc', + symbol: 'IBC', + logoURIs: { + png: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.png', + svg: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.svg' + }, + coingeckoId: 'ibc', + images: [ + { + png: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.png', + svg: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.svg' + } + ] } ] }" diff --git a/__tests__/__snapshots__/stringify.json.test.ts.snap b/__tests__/__snapshots__/stringify.json.test.ts.snap index 58cdc66..16ee9a1 100644 --- a/__tests__/__snapshots__/stringify.json.test.ts.snap +++ b/__tests__/__snapshots__/stringify.json.test.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`applies replacer function if provided 1`] = `"{"firstName": "Alice", "lastName": "Johnson", "age": undefined}"`; +exports[`applies replacer function if provided 1`] = `"[{"firstName": "Alice", "lastName": "Johnson", "age": 20}, {"firstName": "Dana", "lastName": "Johnson", "age": 46}]"`; exports[`handles complex nested objects with arrays 1`] = ` "{ diff --git a/__tests__/__snapshots__/stringify.test.ts.snap b/__tests__/__snapshots__/stringify.test.ts.snap index 5f38ca1..8a0886e 100644 --- a/__tests__/__snapshots__/stringify.test.ts.snap +++ b/__tests__/__snapshots__/stringify.test.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`applies replacer function if provided 1`] = `"{firstName: 'Alice', lastName: 'Johnson', age: undefined}"`; +exports[`applies replacer function if provided 1`] = `"{firstName: 'Alice', lastName: 'Johnson', age: 45}"`; exports[`handles complex nested objects with arrays 1`] = ` "{ diff --git a/__tests__/camel.assets.json.test.ts b/__tests__/camel.assets.json.test.ts index 6131482..2e71c39 100644 --- a/__tests__/camel.assets.json.test.ts +++ b/__tests__/camel.assets.json.test.ts @@ -1,97 +1,7 @@ import { jsonStringify } from "../src"; -const assetlist = { - "$schema": "../assetlist.schema.json", - "chain_name": "comdex", - "assets": [ - { - "description": "Native Token of Comdex Protocol", - "denom_units": [ - { - "denom": "ucmdx", - "exponent": 0 - }, - { - "denom": "cmdx", - "exponent": 6 - } - ], - "base": "ucmdx", - "name": "Comdex", - "display": "cmdx", - "symbol": "CMDX", - "logo_URIs": { - "png": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmdx.png", - "svg": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmdx.svg" - }, - "coingecko_id": "comdex", - "images": [ - { - "png": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmdx.png", - "svg": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmdx.svg" - } - ] - }, - { - "description": "Governance Token of Harbor protocol on Comdex network", - "denom_units": [ - { - "denom": "uharbor", - "exponent": 0 - }, - { - "denom": "harbor", - "exponent": 6 - } - ], - "base": "uharbor", - "name": "Harbor", - "display": "harbor", - "symbol": "HARBOR", - "logo_URIs": { - "png": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/harbor.png", - "svg": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/harbor.svg" - }, - "coingecko_id": "harbor-2", - "images": [ - { - "png": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/harbor.png", - "svg": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/harbor.svg" - } - ] - }, - { - "description": "Stable Token of Harbor protocol on Comdex network", - "denom_units": [ - { - "denom": "ucmst", - "exponent": 0 - }, - { - "denom": "cmst", - "exponent": 6 - } - ], - "base": "ucmst", - "name": "CMST", - "display": "cmst", - "symbol": "CMST", - "logo_URIs": { - "png": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.png", - "svg": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.svg" - }, - "coingecko_id": "composite", - "images": [ - { - "png": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.png", - "svg": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.svg" - } - ] - } - ] -}; - +import assetList from '../__fixtures__/assets.json'; it('assetlist', () => { - expect(jsonStringify(assetlist, { camelCase: true, space: 2 })).toMatchSnapshot(); + expect(jsonStringify(assetList, { camelCase: true, space: 2 })).toMatchSnapshot(); }); \ No newline at end of file diff --git a/__tests__/camel.assets.test.ts b/__tests__/camel.assets.test.ts index 56d4528..5698295 100644 --- a/__tests__/camel.assets.test.ts +++ b/__tests__/camel.assets.test.ts @@ -1,97 +1,7 @@ import { jsStringify } from "../src"; -const assetlist = { - "$schema": "../assetlist.schema.json", - "chain_name": "comdex", - "assets": [ - { - "description": "Native Token of Comdex Protocol", - "denom_units": [ - { - "denom": "ucmdx", - "exponent": 0 - }, - { - "denom": "cmdx", - "exponent": 6 - } - ], - "base": "ucmdx", - "name": "Comdex", - "display": "cmdx", - "symbol": "CMDX", - "logo_URIs": { - "png": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmdx.png", - "svg": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmdx.svg" - }, - "coingecko_id": "comdex", - "images": [ - { - "png": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmdx.png", - "svg": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmdx.svg" - } - ] - }, - { - "description": "Governance Token of Harbor protocol on Comdex network", - "denom_units": [ - { - "denom": "uharbor", - "exponent": 0 - }, - { - "denom": "harbor", - "exponent": 6 - } - ], - "base": "uharbor", - "name": "Harbor", - "display": "harbor", - "symbol": "HARBOR", - "logo_URIs": { - "png": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/harbor.png", - "svg": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/harbor.svg" - }, - "coingecko_id": "harbor-2", - "images": [ - { - "png": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/harbor.png", - "svg": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/harbor.svg" - } - ] - }, - { - "description": "Stable Token of Harbor protocol on Comdex network", - "denom_units": [ - { - "denom": "ucmst", - "exponent": 0 - }, - { - "denom": "cmst", - "exponent": 6 - } - ], - "base": "ucmst", - "name": "CMST", - "display": "cmst", - "symbol": "CMST", - "logo_URIs": { - "png": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.png", - "svg": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.svg" - }, - "coingecko_id": "composite", - "images": [ - { - "png": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.png", - "svg": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.svg" - } - ] - } - ] -}; - +import assetList from '../__fixtures__/assets.json'; it('assetlist', () => { - expect(jsStringify(assetlist, { camelCase: true, space: 2 })).toMatchSnapshot(); + expect(jsStringify(assetList, { camelCase: true, space: 2 })).toMatchSnapshot(); }); \ No newline at end of file diff --git a/__tests__/camel.chain.json.test.ts b/__tests__/camel.chain.json.test.ts index db39316..3f3fa95 100644 --- a/__tests__/camel.chain.json.test.ts +++ b/__tests__/camel.chain.json.test.ts @@ -1,395 +1,6 @@ import { jsonStringify } from "../src"; -const chain = { - "$schema": "../chain.schema.json", - "chain_name": "comdex", - "status": "live", - "network_type": "mainnet", - "website": "https://comdex.one/", - "pretty_name": "Comdex", - "chain_id": "comdex-1", - "bech32_prefix": "comdex", - "slip44": 118, - "fees": { - "fee_tokens": [ - { - "denom": "ucmdx", - "fixed_min_gas_price": 0, - "low_gas_price": 0, - "average_gas_price": 0.025, - "high_gas_price": 0.04 - } - ] - }, - "staking": { - "staking_tokens": [ - { - "denom": "ucmdx" - } - ] - }, - "codebase": { - "git_repo": "https://github.com/comdex-official/comdex", - "recommended_version": "v13.4.0", - "compatible_versions": [ - "v13.4.0" - ], - "binaries": { - "linux/amd64": "https://github.com/comdex-official/comdex/releases/download/v13.4.0/comdex-linux-amd64.tar.gz" - }, - "cosmos_sdk_version": "v0.47.5", - "consensus": { - "type": "cometbft", - "version": "0.37.2" - }, - "cosmwasm_version": "v0.41.0", - "cosmwasm_enabled": true, - "genesis": { - "genesis_url": "https://comdex-mainnet-genesis.s3.ap-southeast-1.amazonaws.com/genesis.json" - }, - "versions": [ - { - "name": "v9.0.0", - "recommended_version": "v9.0.0", - "compatible_versions": [ - "v9.0.0" - ], - "cosmwasm_enabled": true, - "next_version_name": "v10.0.0" - }, - { - "name": "v10.0.0", - "recommended_version": "v10.0.0", - "compatible_versions": [ - "v10.0.0" - ], - "cosmwasm_enabled": true, - "next_version_name": "v11.5.0" - }, - { - "name": "v11.5.0", - "height": 8184000, - "proposal": 154, - "recommended_version": "v11.5.2", - "compatible_versions": [ - "v11.5.2" - ], - "cosmwasm_enabled": true, - "next_version_name": "v13.3.0" - }, - { - "name": "v13.3.0", - "proposal": 216, - "height": 10981900, - "recommended_version": "v13.4.0", - "compatible_versions": [ - "v13.4.0" - ], - "binaries": { - "linux/amd64": "https://github.com/comdex-official/comdex/releases/download/v13.4.0/comdex-linux-amd64.tar.gz" - }, - "cosmos_sdk_version": "v0.47.5", - "consensus": { - "type": "cometbft", - "version": "0.37.2" - }, - "cosmwasm_version": "v0.41.0", - "cosmwasm_enabled": true, - "next_version_name": "" - } - ] - }, - "daemon_name": "comdex", - "node_home": "$HOME/.comdex", - "key_algos": [ - "secp256k1" - ], - "logo_URIs": { - "png": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmdx.png", - "svg": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmdx.svg" - }, - "peers": { - "seeds": [ - { - "id": "7ca14a1d156299999eba9c394ca060368022d52f", - "address": "54.194.178.110:26656" - }, - { - "id": "ade4d8bc8cbe014af6ebdf3cb7b1e9ad36f412c0", - "address": "seeds.polkachu.com:13156", - "provider": "Polkachu" - }, - { - "id": "c30dacf15e97a30b78792c7fa817fd2ef529b820", - "address": "comdex.seed.stavr.tech:2026", - "provider": "🔥STAVR🔥" - }, - { - "id": "20e1000e88125698264454a884812746c2eb4807", - "address": "seeds.lavenderfive.com:13156", - "provider": "Lavender.Five Nodes 🐝" - }, - { - "id": "ebc272824924ea1a27ea3183dd0b9ba713494f83", - "address": "comdex-mainnet-seed.autostake.com:26776", - "provider": "AutoStake 🛡️ Slash Protected" - }, - { - "id": "6596d143fd128b2394b27cd7846bda099ca5a193", - "address": "seeds.goldenratiostaking.net:1621", - "provider": "Golden Ratio Staking" - }, - { - "id": "8542cd7e6bf9d260fef543bc49e59be5a3fa9074", - "address": "seed.publicnode.com:26656", - "provider": "Allnodes ⚡️ Nodes & Staking" - }, - { - "id": "c28827cb96c14c905b127b92065a3fb4cd77d7f6", - "address": "seeds.whispernode.com:13156", - "provider": "WhisperNode 🤐" - }, - { - "id": "88ba33fbdf0279efaf27cff629f3cf72814d4069", - "address": "seed-comdex-01.stakeflow.io:10007", - "provider": "Stakeflow" - }, - { - "id": "df949a46ae6529ae1e09b034b49716468d5cc7e9", - "address": "seeds.stakerhouse.com:10456", - "provider": "StakerHouse" - } - ], - "persistent_peers": [ - { - "id": "d478882a80674fa10a32da63cc20cae13e3a2a57", - "address": "43.204.0.243:26656" - }, - { - "id": "d8b74791ee56f1b345d822f62bd9bc969668d8df", - "address": "194.163.128.55:36656" - }, - { - "id": "ebc272824924ea1a27ea3183dd0b9ba713494f83", - "address": "comdex-mainnet-peer.autostake.com:26776", - "provider": "AutoStake 🛡️ Slash Protecteds" - }, - { - "id": "88ba33fbdf0279efaf27cff629f3cf72814d4069", - "address": "peer-comdex-01.stakeflow.io:10007", - "provider": "Stakeflow" - } - ] - }, - "apis": { - "rpc": [ - { - "address": "https://rpc.comdex.one", - "provider": "comdex" - }, - { - "address": "https://comdex-rpc.polkachu.com", - "provider": "Polkachu" - }, - { - "address": "https://comdex.rpc.m.stavr.tech", - "provider": "🔥STAVR🔥" - }, - { - "address": "https://rpc.comdex.chaintools.tech/", - "provider": "ChainTools" - }, - { - "address": "https://comdex-rpc.lavenderfive.com/", - "provider": "Lavender.Five Nodes 🐝" - }, - { - "address": "https://rpc-comdex.cosmos-spaces.cloud", - "provider": "Cosmos Spaces" - }, - { - "address": "https://rpc-comdex.whispernode.com:443", - "provider": "WhisperNode 🤐" - }, - { - "address": "https://comdex-mainnet-rpc.autostake.com:443", - "provider": "AutoStake 🛡️ Slash Protected" - }, - { - "address": "https://comdex-rpc.w3coins.io", - "provider": "w3coins" - }, - { - "address": "https://comdex-rpc.stakerhouse.com", - "provider": "StakerHouse" - }, - { - "address": "https://comdex-rpc.publicnode.com:443", - "provider": "Allnodes ⚡️ Nodes & Staking" - }, - { - "address": "https://rpc-comdex-01.stakeflow.io", - "provider": "Stakeflow" - }, - { - "address": "https://comdex-rpc.validatornode.com", - "provider": "ValidatorNode" - } - ], - "rest": [ - { - "address": "https://rest.comdex.one", - "provider": "comdex" - }, - { - "address": "https://api.comdex.chaintools.tech/", - "provider": "ChainTools" - }, - { - "address": "https://comdex-api.polkachu.com", - "provider": "Polkachu" - }, - { - "address": "https://comdex.api.m.stavr.tech", - "provider": "🔥STAVR🔥" - }, - { - "address": "https://comdex-api.lavenderfive.com/", - "provider": "Lavender.Five Nodes 🐝" - }, - { - "address": "https://api-comdex.cosmos-spaces.cloud", - "provider": "Cosmos Spaces" - }, - { - "address": "https://comdex-mainnet-lcd.autostake.com:443", - "provider": "AutoStake 🛡️ Slash Protected" - }, - { - "address": "https://lcd-comdex.whispernode.com:443", - "provider": "WhisperNode 🤐" - }, - { - "address": "https://comdex-api.w3coins.io", - "provider": "w3coins" - }, - { - "address": "https://comdex-rest.stakerhouse.com", - "provider": "StakerHouse" - }, - { - "address": "https://comdex-rest.publicnode.com", - "provider": "Allnodes ⚡️ Nodes & Staking" - }, - { - "address": "https://api-comdex-01.stakeflow.io", - "provider": "Stakeflow" - }, - { - "address": "https://comdex-api.validatornode.com", - "provider": "ValidatorNode" - } - ], - "grpc": [ - { - "address": "grpc-comdex-ia.cosmosia.notional.ventures:443", - "provider": "Notional" - }, - { - "address": "comdex.grpcui.chaintools.host:443", - "provider": "ChainTools" - }, - { - "address": "comdex-grpc.polkachu.com:13190", - "provider": "Polkachu" - }, - { - "address": "comdex.grpc.m.stavr.tech:104", - "provider": "🔥STAVR🔥" - }, - { - "address": "grpc-comdex.cosmos-spaces.cloud:2300", - "provider": "Cosmos Spaces" - }, - { - "address": "comdex-grpc.lavenderfive.com:443", - "provider": "Lavender.Five Nodes 🐝" - }, - { - "address": "comdex-mainnet-lcd.autostake.com:443", - "provider": "AutoStake 🛡️ Slash Protected" - }, - { - "address": "comdex-grpc.w3coins.io:13190", - "provider": "w3coins" - }, - { - "address": "comdex-grpc.publicnode.com:443", - "provider": "Allnodes ⚡️ Nodes & Staking" - }, - { - "address": "grpc-comdex-01.stakeflow.io:10002", - "provider": "Stakeflow" - }, - { - "address": "comdex-grpc.stakerhouse.com:443", - "provider": "StakerHouse" - } - ] - }, - "explorers": [ - { - "kind": "ezstaking", - "url": "https://ezstaking.app/comdex", - "tx_page": "https://ezstaking.app/comdex/txs/${txHash}", - "account_page": "https://ezstaking.app/comdex/account/${accountAddress}" - }, - { - "kind": "mintscan", - "url": "https://www.mintscan.io/comdex", - "tx_page": "https://www.mintscan.io/comdex/transactions/${txHash}", - "account_page": "https://www.mintscan.io/comdex/accounts/${accountAddress}" - }, - { - "kind": "🔥STAVR🔥", - "url": "https://explorer.stavr.tech/Comdex-Mainnet", - "tx_page": "https://explorer.stavr.tech/Comdex-Mainnet/txs/${txHash}", - "account_page": "https://explorer.stavr.tech/Comdex-Mainnet/accounts/${accountAddress}" - }, - { - "kind": "aneka", - "url": "https://comdex.aneka.io/", - "tx_page": "https://comdex.aneka.io/txs/${txHash}" - }, - { - "kind": "ping.pub", - "url": "https://ping.pub/comdex", - "tx_page": "https://ping.pub/comdex/tx/${txHash}" - }, - { - "kind": "atomscan", - "url": "https://atomscan.com/comdex", - "tx_page": "https://atomscan.com/comdex/transactions/${txHash}", - "account_page": "https://atomscan.com/comdex/accounts/${accountAddress}" - }, - { - "kind": "Stakeflow", - "url": "https://stakeflow.io/comdex", - "account_page": "https://stakeflow.io/comdex/accounts/${accountAddress}" - }, - { - "kind": "ValidatorNode", - "url": "https://explorer.validatornode.com/comdex", - "tx_page": "https://explorer.validatornode.com/comdex/tx/${txHash}" - } - ], - "images": [ - { - "png": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmdx.png", - "svg": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmdx.svg" - } - ] -}; +import chain from '../__fixtures__/chain.json'; it('chain', () => { expect(jsonStringify(chain, { camelCase: true, space: 2 })).toMatchSnapshot(); diff --git a/__tests__/camel.chain.test.ts b/__tests__/camel.chain.test.ts index b0ab764..904b280 100644 --- a/__tests__/camel.chain.test.ts +++ b/__tests__/camel.chain.test.ts @@ -1,395 +1,6 @@ import { jsStringify } from "../src"; -const chain = { - "$schema": "../chain.schema.json", - "chain_name": "comdex", - "status": "live", - "network_type": "mainnet", - "website": "https://comdex.one/", - "pretty_name": "Comdex", - "chain_id": "comdex-1", - "bech32_prefix": "comdex", - "slip44": 118, - "fees": { - "fee_tokens": [ - { - "denom": "ucmdx", - "fixed_min_gas_price": 0, - "low_gas_price": 0, - "average_gas_price": 0.025, - "high_gas_price": 0.04 - } - ] - }, - "staking": { - "staking_tokens": [ - { - "denom": "ucmdx" - } - ] - }, - "codebase": { - "git_repo": "https://github.com/comdex-official/comdex", - "recommended_version": "v13.4.0", - "compatible_versions": [ - "v13.4.0" - ], - "binaries": { - "linux/amd64": "https://github.com/comdex-official/comdex/releases/download/v13.4.0/comdex-linux-amd64.tar.gz" - }, - "cosmos_sdk_version": "v0.47.5", - "consensus": { - "type": "cometbft", - "version": "0.37.2" - }, - "cosmwasm_version": "v0.41.0", - "cosmwasm_enabled": true, - "genesis": { - "genesis_url": "https://comdex-mainnet-genesis.s3.ap-southeast-1.amazonaws.com/genesis.json" - }, - "versions": [ - { - "name": "v9.0.0", - "recommended_version": "v9.0.0", - "compatible_versions": [ - "v9.0.0" - ], - "cosmwasm_enabled": true, - "next_version_name": "v10.0.0" - }, - { - "name": "v10.0.0", - "recommended_version": "v10.0.0", - "compatible_versions": [ - "v10.0.0" - ], - "cosmwasm_enabled": true, - "next_version_name": "v11.5.0" - }, - { - "name": "v11.5.0", - "height": 8184000, - "proposal": 154, - "recommended_version": "v11.5.2", - "compatible_versions": [ - "v11.5.2" - ], - "cosmwasm_enabled": true, - "next_version_name": "v13.3.0" - }, - { - "name": "v13.3.0", - "proposal": 216, - "height": 10981900, - "recommended_version": "v13.4.0", - "compatible_versions": [ - "v13.4.0" - ], - "binaries": { - "linux/amd64": "https://github.com/comdex-official/comdex/releases/download/v13.4.0/comdex-linux-amd64.tar.gz" - }, - "cosmos_sdk_version": "v0.47.5", - "consensus": { - "type": "cometbft", - "version": "0.37.2" - }, - "cosmwasm_version": "v0.41.0", - "cosmwasm_enabled": true, - "next_version_name": "" - } - ] - }, - "daemon_name": "comdex", - "node_home": "$HOME/.comdex", - "key_algos": [ - "secp256k1" - ], - "logo_URIs": { - "png": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmdx.png", - "svg": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmdx.svg" - }, - "peers": { - "seeds": [ - { - "id": "7ca14a1d156299999eba9c394ca060368022d52f", - "address": "54.194.178.110:26656" - }, - { - "id": "ade4d8bc8cbe014af6ebdf3cb7b1e9ad36f412c0", - "address": "seeds.polkachu.com:13156", - "provider": "Polkachu" - }, - { - "id": "c30dacf15e97a30b78792c7fa817fd2ef529b820", - "address": "comdex.seed.stavr.tech:2026", - "provider": "🔥STAVR🔥" - }, - { - "id": "20e1000e88125698264454a884812746c2eb4807", - "address": "seeds.lavenderfive.com:13156", - "provider": "Lavender.Five Nodes 🐝" - }, - { - "id": "ebc272824924ea1a27ea3183dd0b9ba713494f83", - "address": "comdex-mainnet-seed.autostake.com:26776", - "provider": "AutoStake 🛡️ Slash Protected" - }, - { - "id": "6596d143fd128b2394b27cd7846bda099ca5a193", - "address": "seeds.goldenratiostaking.net:1621", - "provider": "Golden Ratio Staking" - }, - { - "id": "8542cd7e6bf9d260fef543bc49e59be5a3fa9074", - "address": "seed.publicnode.com:26656", - "provider": "Allnodes ⚡️ Nodes & Staking" - }, - { - "id": "c28827cb96c14c905b127b92065a3fb4cd77d7f6", - "address": "seeds.whispernode.com:13156", - "provider": "WhisperNode 🤐" - }, - { - "id": "88ba33fbdf0279efaf27cff629f3cf72814d4069", - "address": "seed-comdex-01.stakeflow.io:10007", - "provider": "Stakeflow" - }, - { - "id": "df949a46ae6529ae1e09b034b49716468d5cc7e9", - "address": "seeds.stakerhouse.com:10456", - "provider": "StakerHouse" - } - ], - "persistent_peers": [ - { - "id": "d478882a80674fa10a32da63cc20cae13e3a2a57", - "address": "43.204.0.243:26656" - }, - { - "id": "d8b74791ee56f1b345d822f62bd9bc969668d8df", - "address": "194.163.128.55:36656" - }, - { - "id": "ebc272824924ea1a27ea3183dd0b9ba713494f83", - "address": "comdex-mainnet-peer.autostake.com:26776", - "provider": "AutoStake 🛡️ Slash Protecteds" - }, - { - "id": "88ba33fbdf0279efaf27cff629f3cf72814d4069", - "address": "peer-comdex-01.stakeflow.io:10007", - "provider": "Stakeflow" - } - ] - }, - "apis": { - "rpc": [ - { - "address": "https://rpc.comdex.one", - "provider": "comdex" - }, - { - "address": "https://comdex-rpc.polkachu.com", - "provider": "Polkachu" - }, - { - "address": "https://comdex.rpc.m.stavr.tech", - "provider": "🔥STAVR🔥" - }, - { - "address": "https://rpc.comdex.chaintools.tech/", - "provider": "ChainTools" - }, - { - "address": "https://comdex-rpc.lavenderfive.com/", - "provider": "Lavender.Five Nodes 🐝" - }, - { - "address": "https://rpc-comdex.cosmos-spaces.cloud", - "provider": "Cosmos Spaces" - }, - { - "address": "https://rpc-comdex.whispernode.com:443", - "provider": "WhisperNode 🤐" - }, - { - "address": "https://comdex-mainnet-rpc.autostake.com:443", - "provider": "AutoStake 🛡️ Slash Protected" - }, - { - "address": "https://comdex-rpc.w3coins.io", - "provider": "w3coins" - }, - { - "address": "https://comdex-rpc.stakerhouse.com", - "provider": "StakerHouse" - }, - { - "address": "https://comdex-rpc.publicnode.com:443", - "provider": "Allnodes ⚡️ Nodes & Staking" - }, - { - "address": "https://rpc-comdex-01.stakeflow.io", - "provider": "Stakeflow" - }, - { - "address": "https://comdex-rpc.validatornode.com", - "provider": "ValidatorNode" - } - ], - "rest": [ - { - "address": "https://rest.comdex.one", - "provider": "comdex" - }, - { - "address": "https://api.comdex.chaintools.tech/", - "provider": "ChainTools" - }, - { - "address": "https://comdex-api.polkachu.com", - "provider": "Polkachu" - }, - { - "address": "https://comdex.api.m.stavr.tech", - "provider": "🔥STAVR🔥" - }, - { - "address": "https://comdex-api.lavenderfive.com/", - "provider": "Lavender.Five Nodes 🐝" - }, - { - "address": "https://api-comdex.cosmos-spaces.cloud", - "provider": "Cosmos Spaces" - }, - { - "address": "https://comdex-mainnet-lcd.autostake.com:443", - "provider": "AutoStake 🛡️ Slash Protected" - }, - { - "address": "https://lcd-comdex.whispernode.com:443", - "provider": "WhisperNode 🤐" - }, - { - "address": "https://comdex-api.w3coins.io", - "provider": "w3coins" - }, - { - "address": "https://comdex-rest.stakerhouse.com", - "provider": "StakerHouse" - }, - { - "address": "https://comdex-rest.publicnode.com", - "provider": "Allnodes ⚡️ Nodes & Staking" - }, - { - "address": "https://api-comdex-01.stakeflow.io", - "provider": "Stakeflow" - }, - { - "address": "https://comdex-api.validatornode.com", - "provider": "ValidatorNode" - } - ], - "grpc": [ - { - "address": "grpc-comdex-ia.cosmosia.notional.ventures:443", - "provider": "Notional" - }, - { - "address": "comdex.grpcui.chaintools.host:443", - "provider": "ChainTools" - }, - { - "address": "comdex-grpc.polkachu.com:13190", - "provider": "Polkachu" - }, - { - "address": "comdex.grpc.m.stavr.tech:104", - "provider": "🔥STAVR🔥" - }, - { - "address": "grpc-comdex.cosmos-spaces.cloud:2300", - "provider": "Cosmos Spaces" - }, - { - "address": "comdex-grpc.lavenderfive.com:443", - "provider": "Lavender.Five Nodes 🐝" - }, - { - "address": "comdex-mainnet-lcd.autostake.com:443", - "provider": "AutoStake 🛡️ Slash Protected" - }, - { - "address": "comdex-grpc.w3coins.io:13190", - "provider": "w3coins" - }, - { - "address": "comdex-grpc.publicnode.com:443", - "provider": "Allnodes ⚡️ Nodes & Staking" - }, - { - "address": "grpc-comdex-01.stakeflow.io:10002", - "provider": "Stakeflow" - }, - { - "address": "comdex-grpc.stakerhouse.com:443", - "provider": "StakerHouse" - } - ] - }, - "explorers": [ - { - "kind": "ezstaking", - "url": "https://ezstaking.app/comdex", - "tx_page": "https://ezstaking.app/comdex/txs/${txHash}", - "account_page": "https://ezstaking.app/comdex/account/${accountAddress}" - }, - { - "kind": "mintscan", - "url": "https://www.mintscan.io/comdex", - "tx_page": "https://www.mintscan.io/comdex/transactions/${txHash}", - "account_page": "https://www.mintscan.io/comdex/accounts/${accountAddress}" - }, - { - "kind": "🔥STAVR🔥", - "url": "https://explorer.stavr.tech/Comdex-Mainnet", - "tx_page": "https://explorer.stavr.tech/Comdex-Mainnet/txs/${txHash}", - "account_page": "https://explorer.stavr.tech/Comdex-Mainnet/accounts/${accountAddress}" - }, - { - "kind": "aneka", - "url": "https://comdex.aneka.io/", - "tx_page": "https://comdex.aneka.io/txs/${txHash}" - }, - { - "kind": "ping.pub", - "url": "https://ping.pub/comdex", - "tx_page": "https://ping.pub/comdex/tx/${txHash}" - }, - { - "kind": "atomscan", - "url": "https://atomscan.com/comdex", - "tx_page": "https://atomscan.com/comdex/transactions/${txHash}", - "account_page": "https://atomscan.com/comdex/accounts/${accountAddress}" - }, - { - "kind": "Stakeflow", - "url": "https://stakeflow.io/comdex", - "account_page": "https://stakeflow.io/comdex/accounts/${accountAddress}" - }, - { - "kind": "ValidatorNode", - "url": "https://explorer.validatornode.com/comdex", - "tx_page": "https://explorer.validatornode.com/comdex/tx/${txHash}" - } - ], - "images": [ - { - "png": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmdx.png", - "svg": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmdx.svg" - } - ] -}; +import chain from '../__fixtures__/chain.json'; it('chain', () => { expect(jsStringify(chain, { camelCase: true, space: 2 })).toMatchSnapshot(); diff --git a/__tests__/default-values.test.ts b/__tests__/default-values.test.ts new file mode 100644 index 0000000..ef3ce78 --- /dev/null +++ b/__tests__/default-values.test.ts @@ -0,0 +1,39 @@ +import { jsStringify, JSStringifyOptions, JSStringifySetterOptions } from "../src"; +import { Asset, AssetList } from '../test-utils'; +import assetList from '../__fixtures__/assets.json'; + +it('defaultValue', () => { + const options: JSStringifyOptions = { + camelCase: true, + space: 2, + defaultValuesSetter: { + "/assets/*/type_asset": function (options: JSStringifySetterOptions): any { + const asset = options.obj; + switch (true) { + case asset.base.startsWith('factory/'): + return 'sdk.Factory'; + + case asset.base.startsWith('ft') && options.root.chain_name === 'bitsong': + return 'bitsong'; + + case asset.base.startsWith('erc20/'): + return 'erc.Token'; + + case asset.base.startsWith('ibc/'): + return 'ibc' + + case asset.base.startsWith('cw20:'): + return 'cw20' + + default: + return 'unknown' + } + } + }, + propertyRenameMap: { + '/assets/*/type_asset': 'asset_type' + } + }; + const jsonString = jsStringify(assetList, options); + expect(jsonString).toMatchSnapshot(); +}); \ No newline at end of file diff --git a/__tests__/expand-paths.test.ts b/__tests__/expand-paths.test.ts new file mode 100644 index 0000000..2be53cf --- /dev/null +++ b/__tests__/expand-paths.test.ts @@ -0,0 +1,115 @@ +const minimatch = require("minimatch").minimatch; + +function dirname(path) { + return path.substring(0, path.lastIndexOf('/')) || '/'; +} + + + +export function expandPaths(paths: string[]): string[] { + const pathSet = new Set(); + + paths.forEach(path => { + let currentPath = path; + // Ensure the path is added to the set + pathSet.add(currentPath); + + // Generate and add all parent directories to the set + while (currentPath !== '') { + const lastSlashIndex = currentPath.lastIndexOf('/'); + if (lastSlashIndex === -1) break; // No more slashes, stop processing + + currentPath = currentPath.substring(0, lastSlashIndex) || ''; + if (currentPath !== '') + pathSet.add(currentPath); + } + }); + + return sortPaths(Array.from(pathSet)); +} + +function sortPaths(paths) { + // First sort alphabetically + paths.sort((a, b) => a.localeCompare(b)); + + // Then sort by depth (number of '/' in the path) + paths.sort((a, b) => { + const depthA = (a.match(/\//g) || []).length; + const depthB = (b.match(/\//g) || []).length; + return depthB - depthA; // Sort from deepest to shallowest + }); + + return paths; +} + +function hasAncestor(currentPath, includePaths) { + return !!findNearestAncestor(currentPath, includePaths); +} + +function findNearestAncestor(currentPath, includePaths) { + let pathToCheck = currentPath; + while (pathToCheck !== '/' && pathToCheck !== '') { + if (includePaths.some(includePath => minimatch(pathToCheck + '/', includePath))) { + if (pathToCheck !== currentPath) + return pathToCheck; // Return the matching parent directory + } + pathToCheck = dirname(pathToCheck); // Move to the next parent directory + } + return null; // Return null if no matching parent is found +} + +// Tests +test('0', () => { + expect(expandPaths([ + '/assets/*/type_asset', + '/assets/*/denom_units', + '/assets/*/base' + ])).toEqual([ + "/assets/*/base", + "/assets/*/denom_units", + "/assets/*/type_asset", + "/assets/*", + "/assets", + ]); + + expect(expandPaths([ + '/chains/*', + '/chains/*/codebase' + ])).toEqual([ + "/chains/*/codebase", + "/chains/*", + "/chains", + ]); +}); + +test('1', () => { + expect(hasAncestor('/assets/0/base', expandPaths([ + '/assets/*/type_asset', + '/assets/*/denom_units', + '/assets/*/base' + ]))).toBe(true); + + expect(findNearestAncestor('/assets/0/denom_units/0/denom', [ + '/assets/*/type_asset', + '/assets/*/denom_units', + '/assets/*/base' + ])).toBe('/assets/0/denom_units'); + + expect(findNearestAncestor('/chain/0', [ + '/assets/*/type_asset', + '/assets/*/denom_units', + '/assets/*/base' + ])).toBeNull(); + + expect(findNearestAncestor('/assets/0/type_asset', expandPaths([ + '/assets/*/type_asset', + '/assets/*/denom_units', + '/assets/*/base' + ]))).toBe('/assets/0'); + + expect(findNearestAncestor('/chains/0/codebase/cosmwasm_version', [ + '/chains/*', + '/chains/*/codebase' + ])).toBe('/chains/0/codebase'); + +}); \ No newline at end of file diff --git a/__tests__/includes.test.ts b/__tests__/includes.test.ts new file mode 100644 index 0000000..747a8dc --- /dev/null +++ b/__tests__/includes.test.ts @@ -0,0 +1,82 @@ +import { jsStringify, JSStringifyOptions, JSStringifySetterOptions } from "../src"; +import assetList from '../__fixtures__/assets.json'; +import chain from '../__fixtures__/chain.json'; + +it('AssetList Modification', () => { + const options: JSStringifyOptions = { + camelCase: true, + space: 2, + propertyRenameMap: { + '/assets/*/type_asset': 'asset_type' + }, + include: [ + '/assets/*/type_asset', + '/assets/*/denom_units/*/denom', + '/assets/*/base' + ], + }; + const jsonString = jsStringify(assetList, options); + expect(jsonString).toMatchSnapshot(); +}); + +it('AssetList Modification 2', () => { + const options: JSStringifyOptions = { + camelCase: true, + space: 2, + propertyRenameMap: { + '/assets/*/type_asset': 'asset_type' + }, + include: [ + '/assets/*/type_asset', + '/assets/*/denom_units', + '/assets/*/base' + ], + }; + const jsonString = jsStringify(assetList, options); + expect(jsonString).toMatchSnapshot(); +}); + +it('AssetList Modification 3', () => { + const options: JSStringifyOptions = { + camelCase: true, + space: 2, + propertyRenameMap: { + '/assets/*/type_asset': 'asset_type', + '/assets/*/logo_URIs': 'logos' + }, + include: [ + '/assets/*/logo_URIs', + '/assets/*/denom_units', + ], + exclude: [ + '/assets/*/logo_URIs/svg' + ], + }; + const jsonString = jsStringify(assetList, options); + expect(jsonString).toMatchSnapshot(); +}); + +it('Chain Modification 3', () => { + const options: JSStringifyOptions = { + camelCase: true, + space: 2, + propertyRenameMap: { + + }, + include: [ + '/fees/fee_tokens', + '/bech32_prefix', + '/chain_id', + '/pretty_name', + '/chain_name', + '/codebase/cosmso_sdk_version', + '/codebase/cosmwasm_version', + '/codebase/cosmwasm_enabled', + '/codebase/versions/*/name', + ], + exclude: [ + ], + }; + const jsonString = jsStringify(chain, options); + expect(jsonString).toMatchSnapshot(); +}); \ No newline at end of file diff --git a/__tests__/property-rename.test.ts b/__tests__/property-rename.test.ts index eb778e8..5fb229c 100644 --- a/__tests__/property-rename.test.ts +++ b/__tests__/property-rename.test.ts @@ -1,98 +1,7 @@ import { minimatch } from "minimatch"; -import { jsStringify } from "../src"; - -const assetlist = { - "$schema": "../assetlist.schema.json", - "chain_name": "comdex", - "assets": [ - { - "description": "Native Token of Comdex Protocol", - "denom_units": [ - { - "denom": "ucmdx", - "exponent": 0 - }, - { - "denom": "cmdx", - "exponent": 6 - } - ], - "base": "ucmdx", - "name": "Comdex", - "display": "cmdx", - "symbol": "CMDX", - "logo_URIs": { - "png": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmdx.png", - "svg": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmdx.svg" - }, - "coingecko_id": "comdex", - "images": [ - { - "png": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmdx.png", - "svg": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmdx.svg" - } - ] - }, - { - "type_asset": "sdk.Coin", - "description": "Governance Token of Harbor protocol on Comdex network", - "denom_units": [ - { - "denom": "uharbor", - "exponent": 0 - }, - { - "denom": "harbor", - "exponent": 6 - } - ], - "base": "uharbor", - "name": "Harbor", - "display": "harbor", - "symbol": "HARBOR", - "logo_URIs": { - "png": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/harbor.png", - "svg": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/harbor.svg" - }, - "coingecko_id": "harbor-2", - "images": [ - { - "png": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/harbor.png", - "svg": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/harbor.svg" - } - ] - }, - { - "description": "Stable Token of Harbor protocol on Comdex network", - "denom_units": [ - { - "denom": "ucmst", - "exponent": 0 - }, - { - "denom": "cmst", - "exponent": 6 - } - ], - "base": "ucmst", - "name": "CMST", - "display": "cmst", - "symbol": "CMST", - "logo_URIs": { - "png": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.png", - "svg": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.svg" - }, - "coingecko_id": "composite", - "images": [ - { - "png": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.png", - "svg": "https://raw.githubusercontent.com/cosmos/chain-registry/master/comdex/images/cmst.svg" - } - ] - } - ] -}; +import { jsStringify, JSStringifyOptions, JSStringifyReplacer, JSStringifyPropertyReplacerOptions, JSStringifySetterOptions } from "../src"; +import assetList from '../__fixtures__/assets.json'; it('assetlist', () => { @@ -105,27 +14,23 @@ it('assetlist', () => { } }; - const jsonString = jsStringify(assetlist, options); + const jsonString = jsStringify(assetList, options); expect(jsonString).toMatchSnapshot(); }); -function propertyReplacer( - currentKey: string, - currentPath: string, - propertyRenameMap: { [pattern: string]: string } -): string { - let finalKey = currentKey; - Object.keys(propertyRenameMap).forEach(pattern => { - if (minimatch(currentPath, pattern)) { - finalKey = propertyRenameMap[pattern]; +function propertyReplacer(options: JSStringifyPropertyReplacerOptions): string { + let finalKey = options.currentKey; + Object.keys(options.propertyRenameMap).forEach(pattern => { + if (minimatch(options.currentPath, pattern)) { + finalKey = options.propertyRenameMap[pattern]; } }); return finalKey; } it('replacer', () => { - const options = { + const options: JSStringifyOptions = { camelCase: true, space: 2, propertyRenameMap: { @@ -134,6 +39,6 @@ it('replacer', () => { }, propertyReplacer }; - const jsonString = jsStringify(assetlist, options); + const jsonString = jsStringify(assetList, options); expect(jsonString).toMatchSnapshot(); -}); \ No newline at end of file +}); diff --git a/__tests__/stringify.json.test.ts b/__tests__/stringify.json.test.ts index 6e6bd33..3875961 100644 --- a/__tests__/stringify.json.test.ts +++ b/__tests__/stringify.json.test.ts @@ -1,4 +1,4 @@ -import { jsonStringify } from '../src'; +import { jsonStringify, JSStringifyPropertyReplacerOptions } from '../src'; it('serializes simple objects without quotes on keys where possible', () => { const obj = { @@ -56,17 +56,41 @@ it('properly escapes strings when necessary', () => { expect(output).toMatchSnapshot(); }); +interface Person { + firstName: string; + lastName: string; + age: number +} + it('applies replacer function if provided', () => { - const obj = { - firstName: 'Alice', - lastName: 'Johnson', - age: 30 - }; - const replacer = (key: string, value: any) => { - if (key === 'age') return undefined; - return value; - }; - const output = jsonStringify(obj, { replacer }); + const obj: Person[] = [ + { + firstName: 'Alice', + lastName: 'Johnson', + age: 30 + }, + { + firstName: 'Dana', + lastName: 'Johnson', + age: 30 + } + ] + const output = jsonStringify(obj, { + valueReplacer: { + '*': (opts: JSStringifyPropertyReplacerOptions) => { + if (opts.obj.lastName === 'Johnson') { + if (opts.currentKey === 'age') { + return 20; + } + } + return opts.value; + }, + '/*/age': (opts: JSStringifyPropertyReplacerOptions) => { + if (opts.obj.firstName === 'Dana') return 46; + return opts.value; + }, + } + }); expect(output).toMatchSnapshot(); }); diff --git a/__tests__/stringify.test.ts b/__tests__/stringify.test.ts index cb3d44f..1c4ef75 100644 --- a/__tests__/stringify.test.ts +++ b/__tests__/stringify.test.ts @@ -1,4 +1,4 @@ -import { jsStringify } from '../src'; +import { jsStringify, JSStringifyPropertyReplacerOptions, JSStringifyReplacer } from '../src'; it('serializes simple objects without quotes on keys where possible', () => { const obj = { @@ -62,11 +62,15 @@ it('applies replacer function if provided', () => { lastName: 'Johnson', age: 30 }; - const replacer = (key: string, value: any) => { - if (key === 'age') return undefined; - return value; + const valueReplacer = (opts: JSStringifyPropertyReplacerOptions) => { + if (opts.currentKey === 'age') return 45; + return opts.value; }; - const output = jsStringify(obj, { replacer }); + const output = jsStringify(obj, { + valueReplacer: { + '/age': valueReplacer + } + }); expect(output).toMatchSnapshot(); }); diff --git a/package.json b/package.json index 2e05ef0..225700a 100644 --- a/package.json +++ b/package.json @@ -64,11 +64,14 @@ "esprima": "4.0.1", "jest-in-case": "1.0.2", "jest": "^29.5.0", - "minimatch": "^9.0.4", "prettier": "^2.8.7", "rimraf": "5.0.0", + "nested-obj": "^0.0.1", "ts-jest": "^29.1.0", "ts-node": "10.9.2", "typescript": "^5.0.4" + }, + "dependencies": { + "minimatch": "^9.0.4" } } \ No newline at end of file diff --git a/src/js.ts b/src/js.ts index ed16caf..54e896d 100644 --- a/src/js.ts +++ b/src/js.ts @@ -1,14 +1,38 @@ -import { camelCaseTransform, escapeStringForBacktickQuotes, escapeStringForDoubleQuotes, escapeStringForSingleQuotes, isSimpleKey } from "./utils"; +import { camelCaseTransform, dirname, escapeStringForBacktickQuotes, escapeStringForDoubleQuotes, escapeStringForSingleQuotes, isSimpleKey, shouldInclude } from "./utils"; +export interface JSStringifySetterOptions { + currentKey: string; + currentPath: string; + value: any; + obj: ObjType; + root: RootType; + defaultValuesMap: { [path: string]: any }; +}; + +export interface JSStringifyPropertyReplacerOptions { + currentKey: string; + currentPath: string; + propertyRenameMap: { [pattern: string]: string }; + obj: ObjType; + root: RootType + value?: any; +} + +export type JSStringifySetter = (options: JSStringifySetterOptions) => any; +export type JSStringifyReplacer = (options: JSStringifyPropertyReplacerOptions) => any; export interface JSStringifyOptions { space?: number; - replacer?: (key: string, value: any) => any | null; - propertyReplacer?: (currentKey: string, currentPath: string, propertyRenameMap: { [pattern: string]: string }) => string + propertyReplacer?: (options: JSStringifyPropertyReplacerOptions) => string + valueReplacer?: Record) => any>; quotes?: 'single' | 'double' | 'backtick'; inlineArrayLimit?: number; camelCase?: boolean; camelCaseFn?: (str: string) => string; - propertyRenameMap?: { [key: string]: string }; + include?: string[]; + exclude?: string[]; + defaultValuesMap?: { [path: string]: any }; + propertyRenameMap?: { [path: string]: any }; + defaultValuesSetter?: { [path: string]: JSStringifySetter } | JSStringifySetter; json?: boolean; } @@ -26,7 +50,9 @@ export function chooseQuotes(str: string, preferred: 'single' | 'double' | 'back } } -function matchesPattern(path, pattern) { +function matchesPattern(path: string, pattern: string) { + if (pattern === '*') return true; + if (path === pattern) return true; const pathSegments = path.split('/'); const patternSegments = pattern.split('/'); if (pathSegments.length !== patternSegments.length) { @@ -54,17 +80,20 @@ function defaultPropertyReplacer( return finalKey; } - export function jsStringify(obj: any, options?: JSStringifyOptions): string { const { space = 0, - replacer = null, propertyReplacer = null, + valueReplacer = {}, quotes = 'single', inlineArrayLimit = undefined, camelCase = false, camelCaseFn = camelCaseTransform, propertyRenameMap = {}, + defaultValuesMap = {}, + defaultValuesSetter = {}, + include = [], + exclude = [], json = false // JSON compliance mode } = options || {}; @@ -72,30 +101,140 @@ export function jsStringify(obj: any, options?: JSStringifyOptions): string { let indentLevel: number = 0; - const serialize = (obj: any, currentPath = "", isArray: boolean = false): string => { - if (replacer instanceof Function) { - obj = replacer.call(null, '', obj); // Call replacer for the root element initially + const serialize = (root: any, obj: any, currentPath = ""): string => { + if (valueReplacer[''] instanceof Function) { + obj = valueReplacer['']({ + currentKey: '', + currentPath, + obj, + propertyRenameMap, + root, + value: obj + }); // Call valueReplacer for the root element initially } if (Array.isArray(obj)) { const useInline = inlineArrayLimit !== undefined && obj.length <= inlineArrayLimit; indentLevel++; const result = '[' + (space && !useInline ? '\n' : '') + obj.map((item, index) => { - return ' '.repeat(useInline ? 0 : indentLevel * space) + serialize(item, `${currentPath}/${index}`, true); + return ' '.repeat(useInline ? 0 : indentLevel * space) + serialize(root, item, `${currentPath}/${index}`); }).join(',' + (space && !useInline ? '\n' : ' ')) + (space && !useInline ? '\n' + ' '.repeat((indentLevel - 1) * space) : '') + ']'; indentLevel--; return result; } else if (isObject(obj)) { indentLevel++; - const props = Object.keys(obj).map(key => { + + // Apply custom default values setter if available + Object.keys(valueReplacer).forEach(pattern => { + if (matchesPattern(currentPath, dirname(pattern))) { + const replacer: JSStringifyReplacer = valueReplacer[pattern]; + const property = pattern.split('/').pop(); // get the last segment as property name + if (property === '*') { + // Apply setter to all properties if needed + Object.keys(obj).forEach(prop => { + obj[prop] = replacer({ + currentKey: prop, + currentPath: `${currentPath}/${prop}`, + obj, + value: obj[prop], + root, + propertyRenameMap + }); + }); + } else if (property) { + obj[property] = replacer({ + currentKey: property, + currentPath, + obj, + value: obj[property], + root, + propertyRenameMap + }); + } + + } + }); + + // Apply custom default values setter if available + Object.keys(defaultValuesSetter).forEach(pattern => { + if (matchesPattern(currentPath, dirname(pattern))) { + const setter: JSStringifySetter = defaultValuesSetter[pattern]; + const property = pattern.split('/').pop(); // get the last segment as property name + if (property === '*') { + // Apply setter to all properties if needed + Object.keys(obj).forEach(prop => { + if (obj[prop] === undefined) { + obj[prop] = setter({ + currentKey: prop, + currentPath: `${currentPath}/${prop}`, + obj, + value: obj[prop], + root, + defaultValuesMap + }); + } + }); + } else if (property && obj[property] === undefined) { + obj[property] = setter({ + currentKey: property, + currentPath, + obj, + value: obj[property], + root, + defaultValuesMap + }); + } + } + }); + + // Apply default values based on currentPath + Object.keys(defaultValuesMap).forEach(pattern => { + if (matchesPattern(currentPath, pattern)) { + const property = pattern.split('/').pop(); // get the last segment as property name + if (property === '*') { + // Apply to all properties if needed + Object.keys(obj).forEach(prop => { + if (obj[prop] === undefined) { + obj[prop] = defaultValuesMap[pattern]; + } + }); + } else if (property && obj[property] === undefined) { + obj[property] = defaultValuesMap[pattern]; + } + } + }); + + + // INCLUDES EXCLUDES + + obj = Object.keys(obj).reduce((m, key) => { const fullPath = `${currentPath}/${key}`; - const value = replacer instanceof Function ? replacer.call(obj, key, obj[key]) : obj[key]; + if (shouldInclude(fullPath, { + exclude, + include + })) { + m[key] = obj[key]; + } + return m; + }, {}); + + + // CHANGE PROPERTY NAMES + const props = Object.keys(obj).map(key => { + const fullPath = `${currentPath}/${key}`; + const value = valueReplacer instanceof Function ? valueReplacer({ + currentKey: key, + currentPath: fullPath, + obj: obj[key], + propertyRenameMap, + root + }) : obj[key]; let replacedKey: string; switch (true) { case propertyReplacer instanceof Function: - replacedKey = propertyReplacer.call(obj, key, fullPath, propertyRenameMap); + replacedKey = propertyReplacer({ root, obj, currentKey: key, currentPath: fullPath, propertyRenameMap }); break; default: replacedKey = defaultPropertyReplacer(key, fullPath, propertyRenameMap); @@ -103,7 +242,7 @@ export function jsStringify(obj: any, options?: JSStringifyOptions): string { const finalKey = camelCase ? camelCaseFn(replacedKey) : replacedKey; const keyPart = json ? `"${finalKey}"` : isSimpleKey(finalKey) ? finalKey : `"${finalKey}"`; - const valuePart = serialize(value, fullPath); + const valuePart = serialize(root, value, fullPath); return ' '.repeat(indentLevel * space) + `${keyPart}: ${valuePart}`; }); const result = '{' + (space ? '\n' : '') + props.join(',' + (space ? '\n' : ' ')) + (space ? '\n' + ' '.repeat((indentLevel - 1) * space) : '') + '}'; @@ -116,5 +255,5 @@ export function jsStringify(obj: any, options?: JSStringifyOptions): string { } }; - return serialize(obj); + return serialize(obj, obj); } diff --git a/src/utils.ts b/src/utils.ts index f09fa44..6019953 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,3 +1,4 @@ +import { minimatch } from 'minimatch'; export function camelCaseTransform(key: string): string { return key.replace(/[-_\s]+(.)?/g, (_, c) => c ? c.toUpperCase() : ''); @@ -7,6 +8,10 @@ export function isSimpleKey(key: string): boolean { return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key); } +export function dirname(path: string): string { + return path.replace(/\/[^\/]*$/, ''); // Removes last segment after the last '/' +} + export function escapeStringForSingleQuotes(str: string): string { // Escape backslashes first str = str.replace(/\\/g, '\\\\'); @@ -43,3 +48,98 @@ export function escapeStringForBacktickQuotes(str: string): string { str = str.replace(/`/g, '\\`'); return str; } + + +const globPattern = /\*+([^+@!?\*\[\(]*)/; + +interface ShouldIncludeOptions { + include: string[]; + exclude: string[]; +} + +export function expandPaths(paths: string[]): string[] { + const pathSet = new Set(); + + paths.forEach(path => { + let currentPath = path; + // Ensure the path is added to the set + pathSet.add(currentPath); + + // Generate and add all parent directories to the set + while (currentPath !== '') { + const lastSlashIndex = currentPath.lastIndexOf('/'); + if (lastSlashIndex === -1) break; // No more slashes, stop processing + + currentPath = currentPath.substring(0, lastSlashIndex) || ''; + if (currentPath !== '') + pathSet.add(currentPath); + } + }); + + return sortPaths(Array.from(pathSet)); +} + +function sortPaths(paths) { + // First sort alphabetically + paths.sort((a, b) => a.localeCompare(b)); + + // Then sort by depth (number of '/' in the path) + paths.sort((a, b) => { + const depthA = (a.match(/\//g) || []).length; + const depthB = (b.match(/\//g) || []).length; + return depthB - depthA; // Sort from deepest to shallowest + }); + + return paths; +} + + +function hasAncestor(currentPath, includePaths) { + return !!findNearestAncestor(currentPath, includePaths); +} + +function findNearestAncestor(currentPath, includePaths) { + let pathToCheck = currentPath; + while (pathToCheck !== '/' && pathToCheck !== '') { + if (includePaths.some(includePath => minimatch(pathToCheck + '/', includePath))) { + if (pathToCheck !== currentPath) + return pathToCheck; // Return the matching parent directory + } + pathToCheck = dirname(pathToCheck); // Move to the next parent directory + } + return null; // Return null if no matching parent is found +} + +export const shouldInclude = (type: string, options: ShouldIncludeOptions): boolean => { + // Determine if 'include' and 'exclude' are effectively set + const includesEffectivelySet = options.include && options.include.length > 0; + const excludesEffectivelySet = options.exclude && options.exclude.length > 0; + + // Function to check if any patterns in the array match the type + const matchesPattern = (patterns: string[], type: string): boolean => + patterns.some(pattern => globPattern.test(pattern) ? minimatch(type, pattern) : type === pattern); + + const isIncluded = includesEffectivelySet ? matchesPattern(expandPaths(options.include), type) : true; + const isIncludedByAncestor = !!findNearestAncestor(type, options.include); + const isExcluded = excludesEffectivelySet ? matchesPattern(options.exclude, type) : false; + + const toInclude = isIncluded; + + // Apply the logic based on whether includes or excludes are effectively set + if (includesEffectivelySet && excludesEffectivelySet) { + if (isIncludedByAncestor && !isExcluded) { + return true; + } + return toInclude && !isExcluded; + } else if (includesEffectivelySet) { + if (isIncludedByAncestor) { + return true; + } + return toInclude; + } else if (excludesEffectivelySet) { + return !isExcluded; + } + + // Default behavior if neither is effectively set + return true; +} \ No newline at end of file diff --git a/test-utils/index.ts b/test-utils/index.ts new file mode 100644 index 0000000..e9489de --- /dev/null +++ b/test-utils/index.ts @@ -0,0 +1 @@ +export * from './interfaces'; \ No newline at end of file diff --git a/test-utils/interfaces.ts b/test-utils/interfaces.ts new file mode 100644 index 0000000..a5b5dde --- /dev/null +++ b/test-utils/interfaces.ts @@ -0,0 +1,90 @@ +export interface Asset { + deprecated?: boolean; + description?: string; + extended_description?: string; + denom_units: DenomUnit[]; + type_asset?: "sdk.coin" | "cw20" | "erc20" | "ics20" | "snip20" | "snip25" | "bitcoin-like" | "evm-base" | "svm-base" | "substrate"; + address?: string; + base: string; + name: string; + display: string; + symbol: string; + traces?: (IbcTransition | IbcCw20Transition | NonIbcTransition)[]; + ibc?: { + source_channel: string; + dst_channel: string; + source_denom: string; + }; + logo_URIs?: { + png?: string; + svg?: string; + }; + images?: { + image_sync?: Pointer; + png?: string; + svg?: string; + theme?: { + primary_color_hex?: string; + circle?: boolean; + dark_mode?: boolean; + }; + }[]; + coingecko_id?: string; + keywords?: string[]; + socials?: { + website?: string; + twitter?: string; + }; +} +export interface DenomUnit { + denom: string; + exponent: number; + aliases?: string[]; +} +export interface Pointer { + chain_name: string; + base_denom?: string; +} +export interface IbcTransition { + type: "ibc"; + counterparty: { + chain_name: string; + base_denom: string; + channel_id: string; + }; + chain: { + channel_id: string; + path: string; + }; +} +export interface IbcCw20Transition { + type: "ibc-cw20"; + counterparty: { + chain_name: string; + base_denom: string; + port: string; + channel_id: string; + }; + chain: { + port: string; + channel_id: string; + path: string; + }; +} +export interface NonIbcTransition { + type: "bridge" | "liquid-stake" | "synthetic" | "wrapped" | "additional-mintage" | "test-mintage"; + counterparty: { + chain_name: string; + base_denom: string; + contract?: string; + }; + chain?: { + contract: string; + }; + provider: string; +} +export interface AssetList { + $schema?: string; + chain_name: string; + assets: Asset[]; +} \ No newline at end of file diff --git a/types/js.d.ts b/types/js.d.ts index 320b820..75916b9 100644 --- a/types/js.d.ts +++ b/types/js.d.ts @@ -1,6 +1,9 @@ export interface JSStringifyOptions { space?: number; - replacer?: (this: any, key: string, value: any) => any | null; + replacer?: (key: string, value: any) => any | null; + propertyReplacer?: (currentKey: string, currentPath: string, propertyRenameMap: { + [pattern: string]: string; + }) => string; quotes?: 'single' | 'double' | 'backtick'; inlineArrayLimit?: number; camelCase?: boolean; @@ -8,6 +11,13 @@ export interface JSStringifyOptions { propertyRenameMap?: { [key: string]: string; }; + defaultValuesMap?: { + [path: string]: any; + }; + defaultValuesSetter?: { + [path: string]: (currentKey: string, currentPath: string, value: any, obj?: any) => any; + }; + json?: boolean; } export declare function chooseQuotes(str: string, preferred: 'single' | 'double' | 'backtick'): string; export declare function jsStringify(obj: any, options?: JSStringifyOptions): string; diff --git a/types/json.d.ts b/types/json.d.ts index 94177f4..afeb59e 100644 --- a/types/json.d.ts +++ b/types/json.d.ts @@ -1,9 +1,4 @@ -export interface JSONStringifyOptions { - space?: number; - replacer?: (this: any, key: string, value: any) => any; - quotes?: 'single' | 'double'; - inlineArrayLimit?: number; - camelCase?: boolean; - camelCaseFn?: (str: string) => string; +import { JSStringifyOptions } from "./js"; +export interface JSONStringifyOptions extends Omit { } export declare function jsonStringify(obj: any, options?: JSONStringifyOptions): string;