diff --git a/.gitignore b/.gitignore index da2292f97..f5d4aff4a 100644 --- a/.gitignore +++ b/.gitignore @@ -35,6 +35,7 @@ scripts/coverage # typescript packages/*/*.tsbuildinfo *.tsbuildinfo +packages/*/.tsc-build-cache # AI .sisyphus/ diff --git a/AGENTS.md b/AGENTS.md index e9941d065..1e040862e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -46,13 +46,15 @@ The monorepo uses a hierarchical configuration approach for different tools. For #### TypeScript -- `tsconfig.base.json` defines shared development-specific TypeScript settings for all other config files. -- `tsconfig.build.json` defines shared build-specific TypeScript settings for all other config files. -- `tsconfig.packages.json` defines shared development-specific TypeScript settings for all directories in `packages/`. -- `tsconfig.packages.build.json` defines shared build-specific TypeScript settings for all directories in `packages/`. -- `tsconfig.scripts.json` defines shared TypeScript settings for directories in `scripts/`. -- `packages/**/tsconfig.json` (and `scripts/create-package/package-template/tsconfig.json`) defines TypeScript settings for each package that are meant to be used by code editors and lint tasks. -- `packages/**/tsconfig.build.json` (and `scripts/create-package/package-template/tsconfig.build.json`) defines TypeScript settings for each package that are used to produce a build. +- `tsconfig.base.json` defines shared compiler defaults for all other config files. +- `tsconfig.json` defines TypeScript settings for repository scripts and editor features. +- `tsconfig.snap.json` defines shared settings for Snap package type checking. Snap bundles are built by `mm-snap`, not `tsc`. +- `tsconfig.library.json` defines shared source settings for library packages. +- `tsconfig.library.build.json` is the root solution for library declaration builds. +- The root `lint:tsc` script checks repository scripts with `tsconfig.json`, then checks each + workspace package configuration directly. It does not build Snap bundles with `tsc`. +- `packages/**/tsconfig.json` (and `scripts/create-package/package-template/tsconfig.json`) defines TypeScript settings for each package that are meant to be used by code editors and type checking. +- Library packages and the package template also have `tsconfig.build.json` files for `ts-bridge` declaration builds. Snap packages do not have build configs because `mm-snap` builds their bundles. - `scripts/create-package/tsconfig.json` customizes TypeScript settings for the `create-package` tool. #### Jest diff --git a/docs/processes/adding-new-packages.md b/docs/processes/adding-new-packages.md index 45bec7fc5..7cd4a8f3b 100644 --- a/docs/processes/adding-new-packages.md +++ b/docs/processes/adding-new-packages.md @@ -14,7 +14,8 @@ Manually creating a new monorepo package can be a tedious, even frustrating proc 3. Update `.github/CODEOWNERS` to assign a team as the owner of the new package. 4. Add your dependencies. - Do this as normal using `yarn`. - - Remember, if you are adding other monorepo packages as dependents, don't forget to add them to the `references` array in your package's `tsconfig.json` and `tsconfig.build.json`. + - Remember, if you are adding other monorepo packages as dependents, don't forget to add them to the `references` array in your package's `tsconfig.json` and, for library packages, `tsconfig.build.json`. + - `create-package` adds library packages to the root `tsconfig.json` and `tsconfig.library.build.json` solution references. Snap packages are checked with `tsconfig.json` and built with `mm-snap`, so they do not have a `tsconfig.build.json`. And that's it! diff --git a/jest.config.packages.js b/jest.config.packages.js index a7c6bc1e1..6fc6c3db3 100644 --- a/jest.config.packages.js +++ b/jest.config.packages.js @@ -78,7 +78,7 @@ module.exports = { // A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module // Here we ensure that Jest resolves `@metamask/*` imports to the uncompiled source code for packages that live in this repo. - // NOTE: This must be synchronized with the `paths` option in `tsconfig.base.json`. + // NOTE: This must be synchronized with the `paths` option in the package TypeScript configs. moduleNameMapper: { '^@metamask/json-rpc-engine/v2$': [ '/../json-rpc-engine/src/v2/index.ts', diff --git a/package.json b/package.json index 389acfa9e..34e699399 100644 --- a/package.json +++ b/package.json @@ -19,13 +19,14 @@ "changelog:validate": "yarn workspaces foreach --all --no-private --parallel --interlaced --verbose run changelog:validate", "create-release-branch": "create-release-branch --formatter oxfmt", "create-package": "tsx scripts/create-package", - "lint": "yarn lint:eslint && echo && yarn lint:misc --check && yarn constraints && yarn lint:dependencies && yarn readme-content:check", + "lint": "yarn lint:tsc && yarn lint:eslint && echo && yarn lint:misc --check && yarn constraints && yarn lint:dependencies && yarn readme-content:check", "lint:dependencies": "depcheck && yarn dedupe --check", "lint:dependencies:fix": "depcheck && yarn dedupe", "lint:eslint": "yarn eslint", "lint:fix": "yarn lint:eslint --fix --prune-suppressions && echo && yarn lint:misc --write && yarn constraints --fix && yarn lint:dependencies:fix && yarn readme-content:update", "lint:misc": "oxfmt --ignore-path .gitignore", "lint:misc:check": "yarn lint:misc --check", + "lint:tsc": "tsc --project tsconfig.json && yarn workspaces foreach --all exec tsc --project tsconfig.json --noEmit --exactOptionalPropertyTypes false", "prepack": "./scripts/prepack.sh", "readme-content:check": "tsx scripts/update-readme-content.ts --check", "readme-content:update": "tsx scripts/update-readme-content.ts", diff --git a/packages/bitcoin-wallet-snap/snap.config.ts b/packages/bitcoin-wallet-snap/snap.config.ts index 5fd9a71ec..e78c43244 100644 --- a/packages/bitcoin-wallet-snap/snap.config.ts +++ b/packages/bitcoin-wallet-snap/snap.config.ts @@ -6,6 +6,9 @@ dotenv(); const config: SnapConfig = { input: resolve(__dirname, 'src/index.ts'), + typescript: { + enabled: true, + }, server: { port: 8080, }, diff --git a/packages/bitcoin-wallet-snap/tsconfig.json b/packages/bitcoin-wallet-snap/tsconfig.json index 34352b8df..e01bf7d4b 100644 --- a/packages/bitcoin-wallet-snap/tsconfig.json +++ b/packages/bitcoin-wallet-snap/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../tsconfig.packages.json", + "extends": "../../tsconfig.snap.json", "compilerOptions": { "baseUrl": "./", "lib": ["ES2021", "DOM"], @@ -15,6 +15,11 @@ "moduleResolution": "bundler", "types": ["jest"] }, - "references": [{ "path": "../snap-networks-utils" }], - "include": ["**/*.ts", "**/*.tsx", "locales/*.json"] + "include": [ + "**/*.ts", + "**/*.tsx", + "locales/*.json", + "snap.manifest.json", + "src/**/*.json" + ] } diff --git a/packages/sample-snap/snap.config.ts b/packages/sample-snap/snap.config.ts index 4ed32b8d9..1493daa6c 100644 --- a/packages/sample-snap/snap.config.ts +++ b/packages/sample-snap/snap.config.ts @@ -5,6 +5,9 @@ import { resolve } from 'path'; const config: SnapConfig = { // eslint-disable-next-line no-restricted-globals input: resolve(__dirname, 'src/index.tsx'), + typescript: { + enabled: true, + }, server: { port: 8080, }, diff --git a/packages/sample-snap/tsconfig.json b/packages/sample-snap/tsconfig.json index 6db6f2381..8aa28b52c 100644 --- a/packages/sample-snap/tsconfig.json +++ b/packages/sample-snap/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../tsconfig.packages.json", + "extends": "../../tsconfig.snap.json", "compilerOptions": { "baseUrl": "./", "jsx": "react-jsx", diff --git a/packages/snap-networks-utils/tsconfig.build.json b/packages/snap-networks-utils/tsconfig.build.json index 02a0eea03..5befc515e 100644 --- a/packages/snap-networks-utils/tsconfig.build.json +++ b/packages/snap-networks-utils/tsconfig.build.json @@ -1,7 +1,14 @@ { - "extends": "../../tsconfig.packages.build.json", + "extends": "../../tsconfig.library.build.json", "compilerOptions": { "baseUrl": "./", + "composite": true, + "declaration": true, + "declarationMap": true, + "emitDeclarationOnly": true, + "inlineSources": true, + "noEmit": false, + "sourceMap": true, "outDir": "./dist", "rootDir": "./src" }, diff --git a/packages/snap-networks-utils/tsconfig.json b/packages/snap-networks-utils/tsconfig.json index 464677940..2a320253b 100644 --- a/packages/snap-networks-utils/tsconfig.json +++ b/packages/snap-networks-utils/tsconfig.json @@ -1,10 +1,9 @@ { - "extends": "../../tsconfig.packages.json", + "extends": "../../tsconfig.library.json", "compilerOptions": { "baseUrl": "./", "skipLibCheck": true, "types": ["jest"] }, - "references": [], "include": ["../../types", "./src"] } diff --git a/packages/solana-wallet-snap/snap.config.ts b/packages/solana-wallet-snap/snap.config.ts index 0d2268a0f..15321d1dd 100644 --- a/packages/solana-wallet-snap/snap.config.ts +++ b/packages/solana-wallet-snap/snap.config.ts @@ -27,6 +27,9 @@ const environment = { const config: SnapConfig = { input: resolve(__dirname, 'src/index.ts'), + typescript: { + enabled: true, + }, server: { port: 8080, }, diff --git a/packages/solana-wallet-snap/src/core/handlers/onClientRequest/validation.ts b/packages/solana-wallet-snap/src/core/handlers/onClientRequest/validation.ts index 94998ece1..63f679a7d 100644 --- a/packages/solana-wallet-snap/src/core/handlers/onClientRequest/validation.ts +++ b/packages/solana-wallet-snap/src/core/handlers/onClientRequest/validation.ts @@ -398,7 +398,9 @@ export const ValidationResponseStruct = object({ valid: boolean(), errors: array( object({ - code: enums(Object.values(SendErrorCodes)), + code: enums( + Object.values(SendErrorCodes) as [SendErrorCodes, ...SendErrorCodes[]], + ), }), ), }); @@ -423,7 +425,7 @@ export const ComputeFeeRequestStruct = object({ export const ComputeFeeResponseStruct = array( object({ - type: enums(Object.values(FeeType)), + type: enums(Object.values(FeeType) as [FeeType, ...FeeType[]]), asset: AssetStruct, }), ); diff --git a/packages/solana-wallet-snap/src/core/handlers/onKeyringRequest/Keyring.test.ts b/packages/solana-wallet-snap/src/core/handlers/onKeyringRequest/Keyring.test.ts index 25c37521a..ba29b25d3 100644 --- a/packages/solana-wallet-snap/src/core/handlers/onKeyringRequest/Keyring.test.ts +++ b/packages/solana-wallet-snap/src/core/handlers/onKeyringRequest/Keyring.test.ts @@ -10,6 +10,7 @@ import bs58 from 'bs58'; import type { AssetEntity } from '../../../entities'; import { asStrictKeyringAccount } from '../../../entities'; +import type { Caip10Address } from '../../constants/solana'; import { KnownCaip19Id, Network } from '../../constants/solana'; import type { AssetsService, @@ -414,7 +415,7 @@ describe('SolanaKeyring', () => { jsonrpc: '2.0', ...MOCK_SIGN_AND_SEND_TRANSACTION_REQUEST, } as unknown as JsonRpcRequest; - const mockResolvedAddress = `${mockScope}:resolved-address`; + const mockResolvedAddress: Caip10Address = `${mockScope}:resolved-address`; jest .spyOn(mockWalletService, 'resolveAccountAddress') diff --git a/packages/solana-wallet-snap/src/core/services/config/ConfigProvider.ts b/packages/solana-wallet-snap/src/core/services/config/ConfigProvider.ts index 5a00610bc..423467755 100644 --- a/packages/solana-wallet-snap/src/core/services/config/ConfigProvider.ts +++ b/packages/solana-wallet-snap/src/core/services/config/ConfigProvider.ts @@ -37,7 +37,7 @@ const CommaSeparatedListOfStringsStruct = coerce( const EnvStruct = object({ ENVIRONMENT: enums(['local', 'test', 'production']), - LOG_LEVEL: enums(Object.values(LogLevel)), + LOG_LEVEL: enums(Object.values(LogLevel) as [LogLevel, ...LogLevel[]]), RPC_URL_MAINNET_LIST: CommaSeparatedListOfUrlsStruct, RPC_URL_DEVNET_LIST: CommaSeparatedListOfUrlsStruct, RPC_URL_TESTNET_LIST: CommaSeparatedListOfUrlsStruct, diff --git a/packages/solana-wallet-snap/src/core/services/transaction-scan/TransactionScan.ts b/packages/solana-wallet-snap/src/core/services/transaction-scan/TransactionScan.ts index 9931999f6..8f82a5319 100644 --- a/packages/solana-wallet-snap/src/core/services/transaction-scan/TransactionScan.ts +++ b/packages/solana-wallet-snap/src/core/services/transaction-scan/TransactionScan.ts @@ -215,7 +215,7 @@ export class TransactionScanService { symbol: 'symbol' in asset.asset ? asset.asset.symbol : asset.asset_type, name: 'name' in asset.asset ? asset.asset.name : asset.asset_type, - logo: 'logo' in asset.asset ? asset.asset.logo : null, + logo: ('logo' in asset.asset ? asset.asset.logo : null) ?? null, value: asset.in?.value ?? asset.out?.value ?? null, price: asset.in?.usd_price ?? asset.out?.usd_price ?? null, }), @@ -230,7 +230,9 @@ export class TransactionScanService { type: 'type' in result.error_details ? result.error_details.type : null, code: - 'code' in result.error_details ? result.error_details.code : null, + ('code' in result.error_details + ? result.error_details.code + : null) ?? null, } : null, }; diff --git a/packages/solana-wallet-snap/src/core/services/wallet/structs.ts b/packages/solana-wallet-snap/src/core/services/wallet/structs.ts index 2687de0ce..71f6578e0 100644 --- a/packages/solana-wallet-snap/src/core/services/wallet/structs.ts +++ b/packages/solana-wallet-snap/src/core/services/wallet/structs.ts @@ -34,7 +34,9 @@ import { Base58Struct, Base64Struct } from '../../validation/structs'; * @see https://github.com/anza-xyz/wallet-standard/tree/master/packages/core/features/src */ -export const ScopeStringStruct = enums(Object.values(Network)); +export const ScopeStringStruct = enums( + Object.values(Network) as [Network, ...Network[]], +); // Sanitizing structs that transform values during validation const SanitizedSolanaAddressStruct = coerce( diff --git a/packages/solana-wallet-snap/src/core/validation/structs.ts b/packages/solana-wallet-snap/src/core/validation/structs.ts index f1eb9accb..2362c9795 100644 --- a/packages/solana-wallet-snap/src/core/validation/structs.ts +++ b/packages/solana-wallet-snap/src/core/validation/structs.ts @@ -65,9 +65,13 @@ export const GetAccounBalancesResponseStruct = record( export const ListAccountAssetsResponseStruct = array(CaipAssetTypeStruct); -export const SubmitRequestMethodStruct = enums(Object.values(SolMethod)); +export const SubmitRequestMethodStruct = enums( + Object.values(SolMethod) as [SolMethod, ...SolMethod[]], +); -export const NetworkStruct = enums(Object.values(Network)); +export const NetworkStruct = enums( + Object.values(Network) as [Network, ...Network[]], +); export const Curenc = enums([ 'btc', diff --git a/packages/solana-wallet-snap/src/index.ts b/packages/solana-wallet-snap/src/index.ts index 1b0772b6a..8867f9bdc 100644 --- a/packages/solana-wallet-snap/src/index.ts +++ b/packages/solana-wallet-snap/src/index.ts @@ -179,13 +179,12 @@ export const onCronjob: OnCronjobHandler = async ({ request }) => { _logger.log(request.method, request); const { method } = request; - assert( - method, - enums([ - ...Object.values(CronjobMethod), - ...Object.values(ScheduleBackgroundEventMethod), - ]), - ); + const validMethods = [ + ...Object.values(CronjobMethod), + ...Object.values(ScheduleBackgroundEventMethod), + ]; + + assert(method, enums(validMethods as [string, ...string[]])); const result = await withCatchAndThrowSnapError(async () => { _logger.log('Running cronjob', { method }); @@ -197,10 +196,7 @@ export const onCronjob: OnCronjobHandler = async ({ request }) => { if (!handler) { throw new MethodNotFoundError( - `Cronjob / ScheduleBackgroundEvent method ${String(method)} not found. Available methods: ${[ - ...Object.values(CronjobMethod), - ...Object.values(ScheduleBackgroundEventMethod), - ].join(',')}`, + `Cronjob / ScheduleBackgroundEvent method ${method} not found. Available methods: ${validMethods.toString()}`, ) as unknown as Error; } return handler({ request }); diff --git a/packages/solana-wallet-snap/tsconfig.json b/packages/solana-wallet-snap/tsconfig.json index 11f05f5bf..4b799ccc4 100644 --- a/packages/solana-wallet-snap/tsconfig.json +++ b/packages/solana-wallet-snap/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../tsconfig.packages.json", + "extends": "../../tsconfig.snap.json", "compilerOptions": { "baseUrl": "./", "jsx": "react-jsx", @@ -16,6 +16,11 @@ "moduleResolution": "bundler", "types": ["jest"] }, - "references": [{ "path": "../snap-networks-utils" }], - "include": ["**/*.ts", "**/*.tsx", "locales/*.json"] + "include": [ + "**/*.ts", + "**/*.tsx", + "locales/*.json", + "snap.manifest.json", + "src/**/*.json" + ] } diff --git a/packages/stellar-wallet-snap/snap.config.ts b/packages/stellar-wallet-snap/snap.config.ts index 046915b47..f33acfc21 100644 --- a/packages/stellar-wallet-snap/snap.config.ts +++ b/packages/stellar-wallet-snap/snap.config.ts @@ -6,6 +6,9 @@ dotenv(); const config: SnapConfig = { input: resolve(__dirname, 'src/index.ts'), + typescript: { + enabled: true, + }, server: { port: 8080, }, diff --git a/packages/stellar-wallet-snap/src/config.ts b/packages/stellar-wallet-snap/src/config.ts index cec727fae..9cecebaa0 100644 --- a/packages/stellar-wallet-snap/src/config.ts +++ b/packages/stellar-wallet-snap/src/config.ts @@ -61,7 +61,13 @@ const parseFloatStruct = ( /** * A struct for validating the network config. */ -const networkConfigStruct = object({ +type NetworkConfigStruct = { + rpcUrl: string; + horizonUrl: string; + explorerBaseUrl: string; +}; + +const networkConfigStruct: Struct = object({ rpcUrl: UrlStruct, horizonUrl: UrlStruct, explorerBaseUrl: UrlStruct, @@ -84,7 +90,10 @@ const selectedNetworkStruct = coerce( * If the log level is empty or missing, it defaults to silent. */ export const LogLevelStruct = coerce( - defaulted(enums(Object.values(LogLevel)), LogLevel.SILENT), + defaulted( + enums(Object.values(LogLevel) as [LogLevel, ...LogLevel[]]), + LogLevel.SILENT, + ), string(), (value: string) => (value === '' ? undefined : value.toLowerCase()), ); @@ -100,7 +109,40 @@ const networkConfigMapStruct = record( /** * A struct for validating the config. */ -const ConfigStruct = object({ +type ConfigValues = { + environment: Environment; + logLevel: LogLevel; + networks: Record; + selectedNetwork: KnownCaip2ChainId; + transaction: { + timeout: number; + pollingAttempts: number; + trackTransactionMaxReschedules: number; + baseFeeMultiplier: number; + maxFeeThresholdInXLM: number; + maxReconcileAttempts: number; + maxPendingTransactionAge: number; + }; + api: { + tokenApi: { baseUrl: string }; + staticApi: { baseUrl: string }; + priceApi: { baseUrl: string }; + securityAlertsApi: { baseUrl: string }; + }; + cache: { + ttlMilliseconds: { + spotPrices: number; + fiatExchangeRates: number; + historicalPrices: number; + baseFee: number; + loadOnChainAccount: number; + simulateTransaction: number; + sep41AssetBalance: number; + }; + }; +}; + +const ConfigStruct: Struct = object({ environment: enums(Object.values(Environment)), logLevel: LogLevelStruct, networks: networkConfigMapStruct, diff --git a/packages/stellar-wallet-snap/src/context.ts b/packages/stellar-wallet-snap/src/context.ts index 3d13f9d4f..a76666a66 100644 --- a/packages/stellar-wallet-snap/src/context.ts +++ b/packages/stellar-wallet-snap/src/context.ts @@ -120,9 +120,9 @@ const priceService = new PriceService({ }); const transactionScanService = new TransactionScanService({ - securityAlertsApiClient: new SecurityAlertsApiClient( - AppConfig.api.securityAlertsApi, - ), + securityAlertsApiClient: new SecurityAlertsApiClient({ + baseUrl: AppConfig.api.securityAlertsApi.baseUrl, + }), logger, }); diff --git a/packages/stellar-wallet-snap/src/services/account/AccountService.ts b/packages/stellar-wallet-snap/src/services/account/AccountService.ts index 7eb0a041a..7552ee521 100644 --- a/packages/stellar-wallet-snap/src/services/account/AccountService.ts +++ b/packages/stellar-wallet-snap/src/services/account/AccountService.ts @@ -165,7 +165,7 @@ export class AccountService { const returnAccounts = await batchesAll( rangeIndices, BATCH_DERIVATION_SIZE, - async (index) => { + async (index: number) => { let account = existingAccountsByIndex.get(index); if (account === undefined) { const wallet = await walletResolver(index); @@ -181,7 +181,8 @@ export class AccountService { ); const createdAccounts = returnAccounts.filter( - (account) => !existingAccountsByIndex.has(account.index), + (account: StellarKeyringAccount) => + !existingAccountsByIndex.has(account.index), ); // 4. Save all new accounts diff --git a/packages/stellar-wallet-snap/src/services/asset-metadata/AssetMetadataService.ts b/packages/stellar-wallet-snap/src/services/asset-metadata/AssetMetadataService.ts index b1bf742b9..36ead89c1 100644 --- a/packages/stellar-wallet-snap/src/services/asset-metadata/AssetMetadataService.ts +++ b/packages/stellar-wallet-snap/src/services/asset-metadata/AssetMetadataService.ts @@ -335,7 +335,8 @@ export class AssetMetadataService { assetIds, this.#sepAssetChunkSize, this.#sepAssetBatchSize, - async (chunk) => this.#networkService.getSep41AssetsData(chunk, scope), + async (chunk: KnownCaip19Sep41AssetId[]) => + this.#networkService.getSep41AssetsData(chunk, scope), ); const { assets, missingAssetIds } = @@ -365,7 +366,7 @@ export class AssetMetadataService { const settled = await batchesAllSettled( assetIds, this.#classicAssetBatchSize, - async (assetId) => + async (assetId: KnownCaip19ClassicAssetId) => this.#networkService.getClassicAssetData(assetId, scope), ); diff --git a/packages/stellar-wallet-snap/src/services/network/NetworkService.ts b/packages/stellar-wallet-snap/src/services/network/NetworkService.ts index 9e3393633..a74cd4415 100644 --- a/packages/stellar-wallet-snap/src/services/network/NetworkService.ts +++ b/packages/stellar-wallet-snap/src/services/network/NetworkService.ts @@ -302,7 +302,7 @@ export class NetworkService { const settled = await batchesAllSettled( accountAddresses, batchSize, - async (accountId) => this.loadOnChainAccount(accountId, scope), // Assume the onChainAccount scope is the same as the transaction scope + async (accountId: string) => this.loadOnChainAccount(accountId, scope), // Assume the onChainAccount scope is the same as the transaction scope ); const onChainAccounts: (OnChainAccount | null)[] = []; diff --git a/packages/stellar-wallet-snap/src/services/transaction/TransactionSynchronizeService.ts b/packages/stellar-wallet-snap/src/services/transaction/TransactionSynchronizeService.ts index 258bde51e..be3d072bf 100644 --- a/packages/stellar-wallet-snap/src/services/transaction/TransactionSynchronizeService.ts +++ b/packages/stellar-wallet-snap/src/services/transaction/TransactionSynchronizeService.ts @@ -256,7 +256,7 @@ export class TransactionSynchronizeService { const fetchResults = await batchesAllSettled( context.keyringAccounts, 10, - async (keyringAccount) => { + async (keyringAccount: StellarKeyringAccount) => { const lastScanToken = context.lastScanTokenByAccountId[keyringAccount.id] ?? null; @@ -339,7 +339,7 @@ export class TransactionSynchronizeService { const fetchResults = await batchesAllSettled( transactionIdsToFetch, 10, - async (transactionId) => + async (transactionId: string) => this.#fetchOnChainTransaction(transactionId, context.scope), ); diff --git a/packages/stellar-wallet-snap/src/utils/errors.test.ts b/packages/stellar-wallet-snap/src/utils/errors.test.ts index 59ad5f8e0..b572d8cd3 100644 --- a/packages/stellar-wallet-snap/src/utils/errors.test.ts +++ b/packages/stellar-wallet-snap/src/utils/errors.test.ts @@ -32,7 +32,7 @@ jest.mock('./logger'); jest.mock('./snap'); describe('errors', () => { - const mockLogger = logger as jest.Mocked; + const mockLogger = jest.mocked(logger); beforeEach(() => { jest.clearAllMocks(); diff --git a/packages/stellar-wallet-snap/tsconfig.json b/packages/stellar-wallet-snap/tsconfig.json index aa6bd53f5..3c44f956c 100644 --- a/packages/stellar-wallet-snap/tsconfig.json +++ b/packages/stellar-wallet-snap/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../tsconfig.packages.json", + "extends": "../../tsconfig.snap.json", "compilerOptions": { "baseUrl": "./", "resolveJsonModule": true /* lets us import JSON modules from within TypeScript modules. */, @@ -16,6 +16,11 @@ "moduleResolution": "bundler", "types": ["jest"] }, - "references": [{ "path": "../snap-networks-utils" }], - "include": ["**/*.ts", "**/*.tsx", "locales/*.json"] + "include": [ + "**/*.ts", + "**/*.tsx", + "locales/*.json", + "snap.manifest.json", + "tokenlists/*.json" + ] } diff --git a/packages/tron-wallet-snap/snap.config.ts b/packages/tron-wallet-snap/snap.config.ts index abb8f37d1..1b13685e9 100644 --- a/packages/tron-wallet-snap/snap.config.ts +++ b/packages/tron-wallet-snap/snap.config.ts @@ -7,6 +7,9 @@ dotenv(); const config: SnapConfig = { input: resolve(__dirname, 'src/index.ts'), + typescript: { + enabled: true, + }, server: { port: 8080, }, diff --git a/packages/tron-wallet-snap/src/caching/useCache.test.ts b/packages/tron-wallet-snap/src/caching/useCache.test.ts index 5ceaeb9d8..bfb302204 100644 --- a/packages/tron-wallet-snap/src/caching/useCache.test.ts +++ b/packages/tron-wallet-snap/src/caching/useCache.test.ts @@ -11,7 +11,7 @@ const cacheOptions: CacheOptions = { type WithUseCacheCallback = (payload: { actualExecutionSpy: jest.Mock, Serializable[]>; - cache: ICache; + cache: MockCache; testFunction: () => Promise; cachedTestFunction: () => Promise; cachedTestFunctionWithArgs: (arg1: string, arg2: number) => Promise; @@ -21,6 +21,11 @@ type WithUseCacheCallback = (payload: { }) => Promise; }) => void | Promise; +type MockCache = ICache & { + get: jest.Mock, [string]>; + set: jest.Mock, [string, Serializable, (number | undefined)?]>; +}; + /** * Wraps tests for `useCache` by creating fresh cached functions backed by a * mock cache. @@ -38,7 +43,7 @@ async function withUseCache(testFn: WithUseCacheCallback): Promise { const cache = { get: jest.fn().mockResolvedValue(undefined), set: jest.fn().mockResolvedValue(undefined), - } as unknown as ICache; + } as unknown as MockCache; // Define original functions const testFunction = async (): Promise => actualExecutionSpy(); diff --git a/packages/tron-wallet-snap/src/caching/useCacheUntil.test.ts b/packages/tron-wallet-snap/src/caching/useCacheUntil.test.ts index fe2351ef2..4c00c3127 100644 --- a/packages/tron-wallet-snap/src/caching/useCacheUntil.test.ts +++ b/packages/tron-wallet-snap/src/caching/useCacheUntil.test.ts @@ -13,15 +13,20 @@ const mockNow = 1700000000000; // Fixed timestamp for testing type WithUseCacheUntilCallback = (payload: { actualExecutionSpy: jest.Mock< - Promise>, + Promise>, Serializable[] >; - cache: ICache; + cache: MockCache; testFunction: () => Promise>; cachedTestFunction: () => Promise; - cachedTestFunctionWithArgs: (arg1: string, arg2: number) => Promise; + cachedTestFunctionWithArgs: (arg1: string) => Promise; }) => void | Promise; +type MockCache = ICache & { + get: jest.Mock, [string]>; + set: jest.Mock, [string, Serializable, (number | undefined)?]>; +}; + /** * Wraps tests for `useCacheUntil` by creating fresh cached functions backed by a * mock cache. @@ -37,7 +42,7 @@ async function withUseCacheUntil( // Reset mocks for each test const actualExecutionSpy = jest - .fn>, Serializable[]>() + .fn>, Serializable[]>() .mockResolvedValue({ result: 'test', expiresAt: mockNow + 60000, // Expires in 60 seconds @@ -47,14 +52,15 @@ async function withUseCacheUntil( const cache = { get: jest.fn().mockResolvedValue(undefined), set: jest.fn().mockResolvedValue(undefined), - } as unknown as ICache; + } as unknown as MockCache; // Define original functions const testFunction = async (): Promise> => - actualExecutionSpy(); + (await actualExecutionSpy()) as ResultWithExpiry; const testFunctionWithArgs = async ( arg1: string, - ): Promise> => actualExecutionSpy(arg1); + ): Promise> => + (await actualExecutionSpy(arg1)) as ResultWithExpiry; // Create cached versions const cachedTestFunction = useCacheUntil(testFunction, cache, { @@ -291,7 +297,7 @@ describe('useCacheUntil', () => { it('handles anonymous functions with a default name', async () => { await withUseCacheUntil(async ({ cache, actualExecutionSpy }) => { const anonymousFunction = async (): Promise> => - actualExecutionSpy(); + (await actualExecutionSpy()) as ResultWithExpiry; Object.defineProperty(anonymousFunction, 'name', { value: null }); const cachedAnonymousFunction = useCacheUntil( diff --git a/packages/tron-wallet-snap/src/clients/token-api/TokenApiClient.ts b/packages/tron-wallet-snap/src/clients/token-api/TokenApiClient.ts index f9e7494a3..9269e9539 100644 --- a/packages/tron-wallet-snap/src/clients/token-api/TokenApiClient.ts +++ b/packages/tron-wallet-snap/src/clients/token-api/TokenApiClient.ts @@ -111,7 +111,7 @@ export class TokenApiClient { // Fetch metadata for each chunk const tokenMetadataResponses = ( await Promise.all( - assetTypeChunks.map(async (chunk) => + assetTypeChunks.map(async (chunk: TokenCaipAssetType[]) => this.#fetchTokenMetadataBatch(chunk), ), ) @@ -129,7 +129,8 @@ export class TokenApiClient { */ assetTypes.forEach((assetType) => { const tokenMetadata = tokenMetadataResponses.find( - (item) => item.assetId === assetType, + (item: Infer[number]) => + item.assetId === assetType, ); if (!tokenMetadata) { diff --git a/packages/tron-wallet-snap/src/services/assets/adapters/CoreAssetsAdapter.test.ts b/packages/tron-wallet-snap/src/services/assets/adapters/CoreAssetsAdapter.test.ts index 4413174ea..f24274971 100644 --- a/packages/tron-wallet-snap/src/services/assets/adapters/CoreAssetsAdapter.test.ts +++ b/packages/tron-wallet-snap/src/services/assets/adapters/CoreAssetsAdapter.test.ts @@ -290,7 +290,7 @@ describe('CoreAssetsAdapter', () => { chainId: Network.Nile, }); mockAssetsProvider.getAccountAssetsByScope.mockImplementation( - async (scope) => { + async (scope: `${string}:${string}`) => { if (scope === Network.Mainnet) { return { [MAINNET_ASSET_ID]: mainnetAsset }; } @@ -328,7 +328,7 @@ describe('CoreAssetsAdapter', () => { it('rejects when any scope request fails', async () => { await withCoreAssetsAdapter(async ({ adapter, mockAssetsProvider }) => { mockAssetsProvider.getAccountAssetsByScope.mockImplementation( - async (scope) => { + async (scope: `${string}:${string}`) => { if (scope === Network.Nile) { throw new Error('nile failed'); } diff --git a/packages/tron-wallet-snap/src/services/assets/adapters/CoreAssetsAdapter.ts b/packages/tron-wallet-snap/src/services/assets/adapters/CoreAssetsAdapter.ts index dcead6166..5a2382909 100644 --- a/packages/tron-wallet-snap/src/services/assets/adapters/CoreAssetsAdapter.ts +++ b/packages/tron-wallet-snap/src/services/assets/adapters/CoreAssetsAdapter.ts @@ -1,4 +1,4 @@ -import type { Caip19AssetId } from '@metamask/assets-controller'; +import type { Asset, Caip19AssetId } from '@metamask/assets-controller'; import { KeyringEvent } from '@metamask/keyring-api'; import type { AccountAssetListUpdatedEvent, @@ -112,7 +112,7 @@ export class CoreAssetsAdapter { accountId, ); - return Object.values(controllerAssets).map((asset) => + return Object.values(controllerAssets).map((asset: Asset) => mapControllerAsset(accountId, asset), ); } @@ -124,7 +124,7 @@ export class CoreAssetsAdapter { this.#getAccountAssetsByScope(Network.Shasta, accountId), ]); - const allUnmappedAssets = [ + const allUnmappedAssets: Asset[] = [ ...Object.values(mainnetAssets), ...Object.values(nileAssets), ...Object.values(shastaAssets), diff --git a/packages/tron-wallet-snap/src/services/config/ConfigProvider.ts b/packages/tron-wallet-snap/src/services/config/ConfigProvider.ts index 0ca3a4b21..cc9ea5955 100644 --- a/packages/tron-wallet-snap/src/services/config/ConfigProvider.ts +++ b/packages/tron-wallet-snap/src/services/config/ConfigProvider.ts @@ -13,7 +13,7 @@ import { Duration } from '@metamask/utils'; import { Network, Networks } from '../../constants'; -const ENVIRONMENT_TO_ACTIVE_NETWORKS = { +const ENVIRONMENT_TO_ACTIVE_NETWORKS: Record = { production: [Network.Mainnet], local: [Network.Mainnet], test: [Network.Mainnet], @@ -27,7 +27,7 @@ const CommaSeparatedListOfUrlsStruct = coerce( const EnvStruct = object({ ENVIRONMENT: enums(['local', 'test', 'production']), - LOG_LEVEL: enums(Object.values(LogLevel)), + LOG_LEVEL: enums(Object.values(LogLevel) as [LogLevel, ...LogLevel[]]), RPC_URL_LIST_MAINNET: CommaSeparatedListOfUrlsStruct, RPC_URL_LIST_NILE_TESTNET: CommaSeparatedListOfUrlsStruct, RPC_URL_LIST_SHASTA_TESTNET: CommaSeparatedListOfUrlsStruct, diff --git a/packages/tron-wallet-snap/tsconfig.json b/packages/tron-wallet-snap/tsconfig.json index aa6bd53f5..f785f54b9 100644 --- a/packages/tron-wallet-snap/tsconfig.json +++ b/packages/tron-wallet-snap/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../tsconfig.packages.json", + "extends": "../../tsconfig.snap.json", "compilerOptions": { "baseUrl": "./", "resolveJsonModule": true /* lets us import JSON modules from within TypeScript modules. */, @@ -16,6 +16,12 @@ "moduleResolution": "bundler", "types": ["jest"] }, - "references": [{ "path": "../snap-networks-utils" }], - "include": ["**/*.ts", "**/*.tsx", "locales/*.json"] + "include": [ + "**/*.ts", + "**/*.tsx", + "locales/*.json", + "messages.json", + "snap.manifest.json", + "src/**/*.json" + ] } diff --git a/scripts/create-package/cli.test.ts b/scripts/create-package/cli.test.ts index 330f9838d..acd975d1c 100644 --- a/scripts/create-package/cli.test.ts +++ b/scripts/create-package/cli.test.ts @@ -44,13 +44,15 @@ describe('create-package/cli', () => { beforeEach(() => { // yargs calls process.exit() with 1 on failure and sometimes 0 on success. // We have to intercept it. - jest.spyOn(process, 'exit').mockImplementation((code?: number) => { - if (code === 1) { - throw new Error('exit: 1'); - } else { - return undefined as never; - } - }); + jest + .spyOn(process, 'exit') + .mockImplementation((code?: string | number | null) => { + if (code === 1) { + throw new Error('exit: 1'); + } else { + return undefined as never; + } + }); // We actually check these. jest.spyOn(console, 'error'); @@ -81,7 +83,7 @@ describe('create-package/cli', () => { jest.spyOn(utils, 'readMonorepoFiles').mockResolvedValue({ tsConfig: {}, - tsConfigBuild: {}, + tsConfigLibraryBuild: {}, nodeVersions: '>=18.0.0', // TODO: Replace `any` with type // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -107,7 +109,7 @@ describe('create-package/cli', () => { jest.spyOn(utils, 'readMonorepoFiles').mockResolvedValue({ tsConfig: {}, - tsConfigBuild: {}, + tsConfigLibraryBuild: {}, nodeVersions: '>=18.0.0', // TODO: Replace `any` with type // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/scripts/create-package/commands.test.ts b/scripts/create-package/commands.test.ts index cb6889d83..5994a55fe 100644 --- a/scripts/create-package/commands.test.ts +++ b/scripts/create-package/commands.test.ts @@ -16,11 +16,8 @@ describe('create-package/commands', () => { describe('createPackageHandler', () => { it('should create the expected package', async () => { (utils.readMonorepoFiles as jest.Mock).mockResolvedValue({ - tsConfig: { - references: [{ path: '../packages/foo' }], - }, - tsConfigBuild: { - references: [{ path: '../packages/foo' }], + tsConfigLibraryBuild: { + references: [{ path: '../packages/foo/tsconfig.build.json' }], }, nodeVersions: '>=18.0.0', }); @@ -44,11 +41,8 @@ describe('create-package/commands', () => { currentYear: '2023', }, { - tsConfig: { - references: [{ path: '../packages/foo' }], - }, - tsConfigBuild: { - references: [{ path: '../packages/foo' }], + tsConfigLibraryBuild: { + references: [{ path: '../packages/foo/tsconfig.build.json' }], }, nodeVersions: '>=18.0.0', }, diff --git a/scripts/create-package/constants.ts b/scripts/create-package/constants.ts index dcf79cfc0..65029a13d 100644 --- a/scripts/create-package/constants.ts +++ b/scripts/create-package/constants.ts @@ -4,7 +4,7 @@ export const MonorepoFiles = { PackageJson: 'package.json', TsConfig: 'tsconfig.json', - TsConfigBuild: 'tsconfig.build.json', + TsConfigLibraryBuild: 'tsconfig.library.build.json', } as const; export type MonorepoFiles = (typeof MonorepoFiles)[keyof typeof MonorepoFiles]; diff --git a/scripts/create-package/package-template/tsconfig.build.json b/scripts/create-package/package-template/tsconfig.build.json index 02a0eea03..5befc515e 100644 --- a/scripts/create-package/package-template/tsconfig.build.json +++ b/scripts/create-package/package-template/tsconfig.build.json @@ -1,7 +1,14 @@ { - "extends": "../../tsconfig.packages.build.json", + "extends": "../../tsconfig.library.build.json", "compilerOptions": { "baseUrl": "./", + "composite": true, + "declaration": true, + "declarationMap": true, + "emitDeclarationOnly": true, + "inlineSources": true, + "noEmit": false, + "sourceMap": true, "outDir": "./dist", "rootDir": "./src" }, diff --git a/scripts/create-package/package-template/tsconfig.json b/scripts/create-package/package-template/tsconfig.json index 025ba2ef7..fdd699a96 100644 --- a/scripts/create-package/package-template/tsconfig.json +++ b/scripts/create-package/package-template/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../tsconfig.packages.json", + "extends": "../../tsconfig.library.json", "compilerOptions": { "baseUrl": "./" }, diff --git a/scripts/create-package/tsconfig.json b/scripts/create-package/tsconfig.json index ffa98185c..bcab5431a 100644 --- a/scripts/create-package/tsconfig.json +++ b/scripts/create-package/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../tsconfig.scripts.json", + "extends": "../../tsconfig.json", "compilerOptions": { "baseUrl": "./" } diff --git a/scripts/create-package/utils.test.ts b/scripts/create-package/utils.test.ts index ad8c264f0..6156b4e34 100644 --- a/scripts/create-package/utils.test.ts +++ b/scripts/create-package/utils.test.ts @@ -32,11 +32,8 @@ jest.mock('./fs-utils', () => ({ describe('create-package/utils', () => { describe('readMonorepoFiles', () => { - const tsConfig = JSON.stringify({ - references: [{ path: '../packages/foo' }], - }); - const tsConfigBuild = JSON.stringify({ - references: [{ path: '../packages/foo' }], + const tsConfigLibraryBuild = JSON.stringify({ + references: [{ path: '../packages/foo/tsconfig.build.json' }], }); const packageJson = JSON.stringify({ engines: { node: '>=18.0.0' }, @@ -46,10 +43,8 @@ describe('create-package/utils', () => { (fs.promises.readFile as jest.Mock).mockImplementation( async (filePath: string) => { switch (path.basename(filePath)) { - case MonorepoFiles.TsConfig: - return tsConfig; - case MonorepoFiles.TsConfigBuild: - return tsConfigBuild; + case MonorepoFiles.TsConfigLibraryBuild: + return tsConfigLibraryBuild; case MonorepoFiles.PackageJson: return packageJson; default: @@ -61,8 +56,7 @@ describe('create-package/utils', () => { const monorepoFileData = await readMonorepoFiles(); expect(monorepoFileData).toStrictEqual({ - tsConfig: commentJson.parse(tsConfig), - tsConfigBuild: commentJson.parse(tsConfigBuild), + tsConfigLibraryBuild: commentJson.parse(tsConfigLibraryBuild), nodeVersions: '>=18.0.0', }); }); @@ -79,11 +73,8 @@ describe('create-package/utils', () => { }; const monorepoFileData = { - tsConfig: { - references: [{ path: './packages/bar' }], - }, - tsConfigBuild: { - references: [{ path: './packages/bar' }], + tsConfigLibraryBuild: { + references: [{ path: './packages/bar/tsconfig.build.json' }], }, nodeVersions: '>=18.0.0', }; @@ -125,27 +116,14 @@ describe('create-package/utils', () => { ); // Writing monorepo files - expect(fs.promises.writeFile).toHaveBeenCalledTimes(2); - expect(format).toHaveBeenCalledTimes(2); - expect(fs.promises.writeFile).toHaveBeenCalledWith( - expect.stringMatching(/tsconfig\.json$/u), - JSON.stringify( - { - references: [ - { path: './packages/bar' }, - { path: './packages/foo' }, - ], - }, - null, - 2, - ), - ); + expect(fs.promises.writeFile).toHaveBeenCalledTimes(1); + expect(format).toHaveBeenCalledTimes(1); expect(fs.promises.writeFile).toHaveBeenCalledWith( - expect.stringMatching(/tsconfig\.build\.json$/u), + expect.stringMatching(/tsconfig\.library\.build\.json$/u), JSON.stringify( { references: [ - { path: './packages/bar' }, + { path: './packages/bar/tsconfig.build.json' }, { path: './packages/foo/tsconfig.build.json' }, ], }, @@ -174,11 +152,8 @@ describe('create-package/utils', () => { }; const monorepoFileData = { - tsConfig: { - references: [{ path: './packages/bar' }], - }, - tsConfigBuild: { - references: [{ path: './packages/bar' }], + tsConfigLibraryBuild: { + references: [{ path: './packages/bar/tsconfig.build.json' }], }, nodeVersions: '20.0.0', }; @@ -208,11 +183,8 @@ describe('create-package/utils', () => { }; const monorepoFileData = { - tsConfig: { - references: [{ path: './packages/bar' }], - }, - tsConfigBuild: { - references: [{ path: './packages/bar' }], + tsConfigLibraryBuild: { + references: [{ path: './packages/bar/tsconfig.build.json' }], }, nodeVersions: '20.0.0', }; diff --git a/scripts/create-package/utils.ts b/scripts/create-package/utils.ts index eea75955a..d91efebad 100644 --- a/scripts/create-package/utils.ts +++ b/scripts/create-package/utils.ts @@ -11,8 +11,10 @@ import { readAllFiles, writeFiles } from './fs-utils'; const PACKAGE_TEMPLATE_DIR = path.join(__dirname, 'package-template'); const REPO_ROOT = path.join(__dirname, '..', '..'); -const REPO_TS_CONFIG = path.join(REPO_ROOT, MonorepoFiles.TsConfig); -const REPO_TS_CONFIG_BUILD = path.join(REPO_ROOT, MonorepoFiles.TsConfigBuild); +const REPO_TS_CONFIG_LIBRARY_BUILD = path.join( + REPO_ROOT, + MonorepoFiles.TsConfigLibraryBuild, +); const REPO_PACKAGE_JSON = path.join(REPO_ROOT, MonorepoFiles.PackageJson); const PACKAGES_PATH = path.join(REPO_ROOT, 'packages'); @@ -42,8 +44,7 @@ export type PackageData = Readonly<{ * Data parsed from relevant monorepo files. */ type MonorepoFileData = { - tsConfig: Tsconfig; - tsConfigBuild: Tsconfig; + tsConfigLibraryBuild: Tsconfig; nodeVersions: string; }; @@ -69,15 +70,15 @@ type PackageJson = { * @returns A map of file paths to file contents. */ export async function readMonorepoFiles(): Promise { - const [tsConfig, tsConfigBuild, packageJson] = await Promise.all([ - fs.readFile(REPO_TS_CONFIG, 'utf-8'), - fs.readFile(REPO_TS_CONFIG_BUILD, 'utf-8'), + const [tsConfigLibraryBuild, packageJson] = await Promise.all([ + fs.readFile(REPO_TS_CONFIG_LIBRARY_BUILD, 'utf-8'), fs.readFile(REPO_PACKAGE_JSON, 'utf-8'), ]); return { - tsConfig: commentJson.parse(tsConfig) as unknown as Tsconfig, - tsConfigBuild: commentJson.parse(tsConfigBuild) as unknown as Tsconfig, + tsConfigLibraryBuild: commentJson.parse( + tsConfigLibraryBuild, + ) as unknown as Tsconfig, nodeVersions: (JSON.parse(packageJson) as PackageJson).engines.node, }; } @@ -111,12 +112,8 @@ export async function finalizeAndWriteData( // Write monorepo files updateTsConfigs(packageData, monorepoFileData); await writeJsonFile( - REPO_TS_CONFIG, - commentJson.stringify(monorepoFileData.tsConfig, null, 2), - ); - await writeJsonFile( - REPO_TS_CONFIG_BUILD, - commentJson.stringify(monorepoFileData.tsConfigBuild, null, 2), + REPO_TS_CONFIG_LIBRARY_BUILD, + commentJson.stringify(monorepoFileData.tsConfigLibraryBuild, null, 2), ); // Postprocess @@ -155,19 +152,14 @@ function updateTsConfigs( packageData: PackageData, monorepoFileData: MonorepoFileData, ): void { - const { tsConfig, tsConfigBuild } = monorepoFileData; - - tsConfig.references.push({ - path: `./${path.basename(PACKAGES_PATH)}/${packageData.directoryName}`, - }); - tsConfig.references.sort((a, b) => a.path.localeCompare(b.path)); + const { tsConfigLibraryBuild } = monorepoFileData; - tsConfigBuild.references.push({ + tsConfigLibraryBuild.references.push({ path: `./${path.basename(PACKAGES_PATH)}/${ packageData.directoryName }/tsconfig.build.json`, }); - tsConfigBuild.references.sort((a, b) => a.path.localeCompare(b.path)); + tsConfigLibraryBuild.references.sort((a, b) => a.path.localeCompare(b.path)); } /** diff --git a/tsconfig.base.json b/tsconfig.base.json index ab31b1bc9..d38882705 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -3,7 +3,6 @@ * This configuration is extended by all other TypeScript configurations. */ "compilerOptions": { - "composite": true, "esModuleInterop": true, "isolatedModules": true, "lib": ["ES2020", "DOM"], diff --git a/tsconfig.build.json b/tsconfig.build.json deleted file mode 100644 index e5a321b17..000000000 --- a/tsconfig.build.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - /** - * Solution-style config for library packages that emit types via `ts-bridge`. - * `create-package` adds new library packages to `references`. Snap packages - * do not use this file; they are built with `mm-snap`. - */ - "references": [ - { - "path": "./packages/snap-networks-utils/tsconfig.build.json" - } - ], - "files": [], - "include": [] -} diff --git a/tsconfig.json b/tsconfig.json index 23df98f6d..36dd6ba84 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,33 +1,18 @@ { /** - * This configuration is used by the `lint` script in `package.json`, and by editors such as - * VSCode for TypeScript-related features. + * Repository-level configuration used by the `lint` script and editors such as VSCode. */ "extends": "./tsconfig.base.json", "compilerOptions": { + "baseUrl": "./", + "forceConsistentCasingInFileNames": true, + "lib": ["ES2020"], "noEmit": true, + "noErrorTruncation": true, + "noUncheckedIndexedAccess": true, "skipLibCheck": true }, - "references": [ - { - "path": "./packages/bitcoin-wallet-snap" - }, - { - "path": "./packages/sample-snap" - }, - { - "path": "./packages/snap-networks-utils" - }, - { - "path": "./packages/solana-wallet-snap" - }, - { - "path": "./packages/stellar-wallet-snap" - }, - { - "path": "./packages/tron-wallet-snap" - } - ], "files": [], - "include": ["./docs", "./tests", "./scripts"] + "include": ["./docs", "./tests", "./scripts"], + "exclude": ["**/node_modules"] } diff --git a/tsconfig.library.build.json b/tsconfig.library.build.json new file mode 100644 index 000000000..2eebe7f8b --- /dev/null +++ b/tsconfig.library.build.json @@ -0,0 +1,23 @@ +{ + /** + * Root solution for library package declaration builds. Snap packages are not included because + * their bundles are built by mm-snap. + */ + "extends": "./tsconfig.library.json", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "emitDeclarationOnly": true, + "inlineSources": true, + "noEmit": false, + "skipLibCheck": true, + "sourceMap": true + }, + "references": [ + { + "path": "./packages/snap-networks-utils/tsconfig.build.json" + } + ], + "files": [], + "include": [] +} diff --git a/tsconfig.library.json b/tsconfig.library.json new file mode 100644 index 000000000..bce0bbbfa --- /dev/null +++ b/tsconfig.library.json @@ -0,0 +1,25 @@ +{ + /** + * Shared settings for library package source and editor configurations. + */ + "extends": "./tsconfig.base.json", + "compilerOptions": { + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "noErrorTruncation": true, + "noUncheckedIndexedAccess": true, + "noEmit": true, + /** + * Resolve local `@metamask/*` imports to source so editors and TypeScript checks use the + * uncompiled monorepo packages. + * + * NOTE: This must be synchronized with the `moduleNameMapper` option in + * `jest.config.packages.js`. + */ + "paths": { + "@metamask/snap-networks-utils/*": ["../snap-networks-utils/src/*"], + "@metamask/*": ["../*/src"] + }, + "skipLibCheck": true + } +} diff --git a/tsconfig.packages.build.json b/tsconfig.packages.build.json deleted file mode 100644 index e971538b7..000000000 --- a/tsconfig.packages.build.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - /** - * This configuration is extended by the `tsconfig.build.json` configuration in each package. - */ - "extends": "./tsconfig.packages.json", - "compilerOptions": { - "declaration": true, - "declarationMap": true, - "emitDeclarationOnly": true, - "inlineSources": true, - "sourceMap": true, - "skipLibCheck": true - }, - "exclude": ["./jest.config.packages.ts", "**/*.test.ts", "**/jest.config.ts"] -} diff --git a/tsconfig.packages.json b/tsconfig.packages.json deleted file mode 100644 index a655abc1f..000000000 --- a/tsconfig.packages.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - /** - * This configuration is extended by the `tsconfig.json` configuration in each package. - */ - "extends": "./tsconfig.base.json", - "compilerOptions": { - /** - * Here we ensure that TypeScript resolves `@metamask/*` imports to the - * uncompiled source code for packages that live in this repo. - * - * NOTE: This must be synchronized with the `moduleNameMapper` option in - * `jest.config.packages.js`. - */ - "paths": { - "@metamask/*": ["../*/src"] - } - } -} diff --git a/tsconfig.scripts.json b/tsconfig.scripts.json deleted file mode 100644 index b4adc2c51..000000000 --- a/tsconfig.scripts.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - /** - * This configuration is intended for the `scripts/` directory, both for linting and for editor - * TypeScript-related features. - * - * It's currently not actually used for that purpose, but it will be in a future PR. - * - * This is also extended by the `tsconfig.json` file in `scripts/create-package/`, which _is_ - * actively used to support TypeScript-related editor features in that directory. - */ - "extends": "./tsconfig.base.json", - "compilerOptions": { - "baseUrl": "./", - "exactOptionalPropertyTypes": true, - "forceConsistentCasingInFileNames": true, - "lib": ["ES2020"], - "noEmit": true, - "noErrorTruncation": true, - "noUncheckedIndexedAccess": true - }, - "include": ["./scripts/**/*.ts"], - "exclude": ["**/node_modules"] -} diff --git a/tsconfig.snap.json b/tsconfig.snap.json new file mode 100644 index 000000000..a5a896c2d --- /dev/null +++ b/tsconfig.snap.json @@ -0,0 +1,22 @@ +{ + /** + * Shared settings for Snap package TypeScript checking. Snap bundles are built by mm-snap, not + * by TypeScript. + */ + "extends": "./tsconfig.base.json", + "compilerOptions": { + "noEmit": true, + "forceConsistentCasingInFileNames": true, + "jsx": "react-jsx", + "jsxImportSource": "@metamask/snaps-sdk", + "noErrorTruncation": true, + "noUncheckedIndexedAccess": true, + "noEmit": true, + "paths": { + "@metamask/snap-networks-utils/*": ["../snap-networks-utils/src/*"], + "@metamask/*": ["../*/src"] + }, + "skipLibCheck": true, + "types": ["jest"] + } +}