From a1751a88d5f5e551bf925a6cd76614cb035ffff0 Mon Sep 17 00:00:00 2001 From: Rafa Cardenas <253999660+rafa-stacks@users.noreply.github.com> Date: Wed, 25 Mar 2026 21:59:33 -0600 Subject: [PATCH 01/12] fix: metadata update --- src/pg/stacks-core-pg-store.ts | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/pg/stacks-core-pg-store.ts b/src/pg/stacks-core-pg-store.ts index 490fc3a..31c44d8 100644 --- a/src/pg/stacks-core-pg-store.ts +++ b/src/pg/stacks-core-pg-store.ts @@ -18,6 +18,7 @@ import { DbProcessedTokenUpdateBundle, DbRateLimitedHost, DbRateLimitedHostInsert, + DbMetadataInsert, DbMetadataAttributeInsert, } from './types'; import { dbSipNumberToDbTokenType } from '../token-processor/util/helpers'; @@ -546,9 +547,20 @@ export class StacksCorePgStore extends BasePgStoreModule { // Write new metadata if (args.values.metadataLocales && args.values.metadataLocales.length > 0) { for (const locale of args.values.metadataLocales) { - delete (locale.metadata as Record)['id']; + const metadataValues: DbMetadataInsert = { + sip: locale.metadata.sip, + token_id: args.id, + name: locale.metadata.name, + l10n_locale: locale.metadata.l10n_locale, + l10n_uri: locale.metadata.l10n_uri, + l10n_default: locale.metadata.l10n_default, + description: locale.metadata.description, + image: locale.metadata.image, + cached_image: locale.metadata.cached_image, + cached_thumbnail_image: locale.metadata.cached_thumbnail_image, + }; const metadataInsert = await sql<{ id: number }[]>` - INSERT INTO metadata ${sql(locale.metadata)} RETURNING id + INSERT INTO metadata ${sql(metadataValues)} RETURNING id `; const metadataId = metadataInsert[0].id; if (locale.attributes && locale.attributes.length > 0) { From 5644cea2a68a2a2fb0edae5c5df8d1a338bc9831 Mon Sep 17 00:00:00 2001 From: Rafa Cardenas <253999660+rafa-stacks@users.noreply.github.com> Date: Wed, 25 Mar 2026 22:19:17 -0600 Subject: [PATCH 02/12] fix server version schema --- src/api/schemas.ts | 15 ++++++++++++--- src/pg/stacks-core-pg-store.ts | 3 ++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/api/schemas.ts b/src/api/schemas.ts index 2db68e8..b54a1b3 100644 --- a/src/api/schemas.ts +++ b/src/api/schemas.ts @@ -1,12 +1,21 @@ import { SwaggerOptions } from '@fastify/swagger'; import { Static, TSchema, Type } from '@sinclair/typebox'; +import { isProdEnv, logger, SERVER_VERSION } from '@stacks/api-toolkit'; import { readFileSync } from 'fs'; import { resolve } from 'path'; const Nullable = (type: T) => Type.Union([type, Type.Null()]); -const packageJsonPath = resolve(__dirname, '../../package.json'); -const { version } = JSON.parse(readFileSync(packageJsonPath, 'utf-8')) as { version: string }; +const openApiVersion = (() => { + if (isProdEnv) return SERVER_VERSION.tag; + try { + const packageJsonPath = resolve(__dirname, '../../package.json'); + return (JSON.parse(readFileSync(packageJsonPath, 'utf-8')) as { version: string }).version; + } catch (error) { + logger.error(error, 'Error reading version from package.json'); + return SERVER_VERSION.tag; + } +})(); export const OpenApiSchemaOptions: SwaggerOptions = { openapi: { @@ -14,7 +23,7 @@ export const OpenApiSchemaOptions: SwaggerOptions = { title: 'Token Metadata API', description: 'Welcome to the API reference overview for the [Token Metadata API](https://docs.hiro.so/token-metadata-api). Service that indexes metadata for every SIP-009, SIP-010, and SIP-013 Token in the Stacks blockchain and exposes it via REST API endpoints.', - version, + version: openApiVersion, }, externalDocs: { url: 'https://github.com/hirosystems/token-metadata-api', diff --git a/src/pg/stacks-core-pg-store.ts b/src/pg/stacks-core-pg-store.ts index 31c44d8..2a19778 100644 --- a/src/pg/stacks-core-pg-store.ts +++ b/src/pg/stacks-core-pg-store.ts @@ -20,6 +20,7 @@ import { DbRateLimitedHostInsert, DbMetadataInsert, DbMetadataAttributeInsert, + DbMetadataPropertyInsert, } from './types'; import { dbSipNumberToDbTokenType } from '../token-processor/util/helpers'; import { DecodedStacksBlock } from '../stacks-core/stacks-core-block-processor'; @@ -573,7 +574,7 @@ export class StacksCorePgStore extends BasePgStoreModule { await sql`INSERT INTO metadata_attributes ${sql(values)}`; } if (locale.properties && locale.properties.length > 0) { - const values = locale.properties.map(property => ({ + const values: DbMetadataPropertyInsert[] = locale.properties.map(property => ({ name: property.name, value: typeof property.value == 'boolean' From 5eb929d836326d4e8a6c1909e18194698c86c685 Mon Sep 17 00:00:00 2001 From: Rafa Cardenas <253999660+rafa-stacks@users.noreply.github.com> Date: Wed, 25 Mar 2026 22:26:51 -0600 Subject: [PATCH 03/12] undici --- src/token-processor/stacks-node/stacks-node-rpc-client.ts | 2 -- src/token-processor/util/metadata-helpers.ts | 1 - 2 files changed, 3 deletions(-) diff --git a/src/token-processor/stacks-node/stacks-node-rpc-client.ts b/src/token-processor/stacks-node/stacks-node-rpc-client.ts index 78d2ace..333361a 100644 --- a/src/token-processor/stacks-node/stacks-node-rpc-client.ts +++ b/src/token-processor/stacks-node/stacks-node-rpc-client.ts @@ -79,7 +79,6 @@ export class StacksNodeRpcClient { try { const result = await request(url, { method: 'GET', - throwOnError: true, }); const text = await result.body.text(); if (result.statusCode >= 400) { @@ -114,7 +113,6 @@ export class StacksNodeRpcClient { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body), - throwOnError: true, }); const text = await result.body.text(); if (result.statusCode >= 400) { diff --git a/src/token-processor/util/metadata-helpers.ts b/src/token-processor/util/metadata-helpers.ts index 2a2bd5e..50bae46 100644 --- a/src/token-processor/util/metadata-helpers.ts +++ b/src/token-processor/util/metadata-helpers.ts @@ -266,7 +266,6 @@ export async function fetchMetadata( logger.info(`MetadataFetch for ${contract_principal}#${token_number} from ${url}`); const result = await request(url, { method: 'GET', - throwOnError: true, headers, dispatcher: // Disable during tests so we can inject a global mock agent. From ed9ad5b386fbf650b6f400688f249bd7dba60457 Mon Sep 17 00:00:00 2001 From: Rafa Cardenas <253999660+rafa-stacks@users.noreply.github.com> Date: Thu, 26 Mar 2026 10:43:41 -0600 Subject: [PATCH 04/12] upgrade to node v24 --- .nvmrc | 2 +- Dockerfile | 2 +- package-lock.json | 56 +++++++++++++++++++++++++++++++++-------------- package.json | 4 ++-- 4 files changed, 43 insertions(+), 21 deletions(-) diff --git a/.nvmrc b/.nvmrc index 2bd5a0a..a45fd52 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -22 +24 diff --git a/Dockerfile b/Dockerfile index 0c36d56..58a088a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:22-alpine +FROM node:24-alpine WORKDIR /app COPY . . diff --git a/package-lock.json b/package-lock.json index e1f4a54..9318130 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,7 +19,7 @@ "@stacks/codec": "^1.6.0", "@stacks/node-publisher-client": "^2.0.5", "@stacks/transactions": "^7.3.1", - "@types/node": "^22.0.0", + "@types/node": "^24.0.0", "bignumber.js": "^10.0.2", "env-schema": "^7.0.0", "fastify": "^5.8.2", @@ -53,7 +53,7 @@ "typescript": "^5.9.3" }, "engines": { - "node": ">=22" + "node": ">=24" } }, "../stacks-node-publisher/client": { @@ -2258,6 +2258,7 @@ "resolved": "https://registry.npmjs.org/@redis/client/-/client-5.11.0.tgz", "integrity": "sha512-GHoprlNQD51Xq2Ztd94HHV94MdFZQ3CVrpA04Fz8MVoHM0B7SlbmPEVIjwTbcv58z8QyjnrOuikS0rWF03k5dQ==", "license": "MIT", + "peer": true, "dependencies": { "cluster-key-slot": "1.1.2" }, @@ -2564,7 +2565,17 @@ "version": "0.28.20", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.28.20.tgz", "integrity": "sha512-QCF3BGfacwD+3CKhGsMeixnwOmX4AWgm61nKkNdRStyLVu0mpVFYlDSY8gVBOOED1oSwzbJauIWl/+REj8K5+w==", - "license": "MIT" + "license": "MIT", + "peer": true + }, + "node_modules/@stacks/api-toolkit/node_modules/@types/node": { + "version": "22.19.15", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.15.tgz", + "integrity": "sha512-F0R/h2+dsy5wJAUe3tAU6oqa2qbWY5TpNfL/RGmo1y38hiyO1w3x2jPtt76wmuaJI4DQnOBu21cNXQ2STIUUWg==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } }, "node_modules/@stacks/api-toolkit/node_modules/avvio": { "version": "8.4.0", @@ -2850,6 +2861,12 @@ "real-require": "^0.2.0" } }, + "node_modules/@stacks/api-toolkit/node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "license": "MIT" + }, "node_modules/@stacks/api-toolkit/node_modules/yargs": { "version": "17.3.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.3.1.tgz", @@ -3153,12 +3170,13 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.19.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.3.tgz", - "integrity": "sha512-1N9SBnWYOJTrNZCdh/yJE+t910Y128BoyY+zBLWhL3r0TYzlTmFdXrPwHL9DyFZmlEXNQQolTZh3KHV31QDhyA==", + "version": "24.12.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.0.tgz", + "integrity": "sha512-GYDxsZi3ChgmckRT9HPU0WEhKLP08ev/Yfcq2AstjrDASOYCSXeyjDsHg4v5t4jOj7cyDX3vmprafKlWIG9MXQ==", "license": "MIT", + "peer": true, "dependencies": { - "undici-types": "~6.21.0" + "undici-types": "~7.16.0" } }, "node_modules/@types/pg": { @@ -3220,6 +3238,7 @@ "integrity": "sha512-Gn3aqnvNl4NGc6x3/Bqk1AOn0thyTU9bqDRhiRnUWezgvr2OnhYCWCgC8zXXRVqBsIL1pSDt7T9nJUe0oM0kDQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/regexpp": "^4.12.2", "@typescript-eslint/scope-manager": "8.57.1", @@ -3249,6 +3268,7 @@ "integrity": "sha512-k4eNDan0EIMTT/dUKc/g+rsJ6wcHYhNPdY19VoX/EOtaAG8DLtKCykhrUnuHPYvinn5jhAPgD2Qw9hXBwrahsw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.57.1", "@typescript-eslint/types": "8.57.1", @@ -3851,6 +3871,7 @@ "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -4318,7 +4339,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==", - "peer": true, "engines": { "node": ">=4" } @@ -5253,6 +5273,7 @@ "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -5411,6 +5432,7 @@ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -8331,8 +8353,7 @@ "node_modules/packet-reader": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", - "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==", - "peer": true + "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" }, "node_modules/parent-module": { "version": "1.0.1", @@ -8459,8 +8480,7 @@ "node_modules/pg-connection-string": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz", - "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==", - "peer": true + "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==" }, "node_modules/pg-int8": { "version": "1.0.1", @@ -8474,7 +8494,6 @@ "version": "3.5.2", "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.5.2.tgz", "integrity": "sha512-His3Fh17Z4eg7oANLob6ZvH8xIVen3phEZh2QuyrIl4dQSDVEabNducv6ysROKpDNPSD+12tONZVWfSgMvDD9w==", - "peer": true, "peerDependencies": { "pg": ">=8.0" } @@ -8503,7 +8522,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", - "peer": true, "dependencies": { "split2": "^4.1.0" } @@ -8521,6 +8539,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -8648,6 +8667,7 @@ "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", "dev": true, "license": "MIT", + "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -10007,6 +10027,7 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -10044,9 +10065,9 @@ } }, "node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", "license": "MIT" }, "node_modules/unrs-resolver": { @@ -10056,6 +10077,7 @@ "dev": true, "hasInstallScript": true, "license": "MIT", + "peer": true, "dependencies": { "napi-postinstall": "^0.3.0" }, diff --git a/package.json b/package.json index a954aa5..518109c 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "author": "Hiro Systems PBC (https://hiro.so)", "license": "GPL-3.0", "engines": { - "node": ">=22" + "node": ">=24" }, "scripts": { "build": "rimraf ./dist && tsc --project tsconfig.build.json", @@ -65,7 +65,7 @@ "@stacks/codec": "^1.6.0", "@stacks/node-publisher-client": "^2.0.5", "@stacks/transactions": "^7.3.1", - "@types/node": "^22.0.0", + "@types/node": "^24.0.0", "bignumber.js": "^10.0.2", "env-schema": "^7.0.0", "fastify": "^5.8.2", From dec5a13f7c0b5eecabde8713dc052981abd21cfe Mon Sep 17 00:00:00 2001 From: Rafa Cardenas <253999660+rafa-stacks@users.noreply.github.com> Date: Thu, 26 Mar 2026 13:26:13 -0600 Subject: [PATCH 05/12] esm --- eslint.config.js => eslint.config.cjs | 0 package-lock.json | 43 +++++++++---------- package.json | 15 ++++--- src/admin-rpc/init.ts | 12 +++--- src/api/@types/fastify/index.d.ts | 4 +- src/api/@types/node-pg-migrate/index.d.ts | 3 -- src/api/init.ts | 18 ++++---- src/api/routes/ft.ts | 8 ++-- src/api/routes/nft.ts | 8 ++-- src/api/routes/search.ts | 6 +-- src/api/routes/sft.ts | 8 ++-- src/api/routes/status.ts | 4 +- src/api/schemas.ts | 6 ++- src/api/util/cache.ts | 4 +- src/api/util/errors.ts | 8 ++-- src/api/util/helpers.ts | 4 +- src/index.ts | 16 +++---- src/pg/errors.ts | 2 +- src/pg/pg-store.ts | 14 +++--- src/pg/stacks-core-pg-store.ts | 10 ++--- src/pg/types.ts | 2 +- src/stacks-core/snp-event-stream.ts | 4 +- .../stacks-core-block-processor.ts | 4 +- src/token-processor/images/image-cache.ts | 8 ++-- src/token-processor/queue/helpers.ts | 2 +- src/token-processor/queue/job-queue.ts | 12 +++--- src/token-processor/queue/job/job.ts | 12 +++--- .../queue/job/process-smart-contract-job.ts | 8 ++-- .../queue/job/process-token-job.ts | 12 +++--- .../queue/job/update-token-supply-job.ts | 8 ++-- .../stacks-node/stacks-node-rpc-client.ts | 6 +-- .../token-processor-metrics.ts | 2 +- src/token-processor/util/errors.ts | 4 +- src/token-processor/util/helpers.ts | 2 +- src/token-processor/util/metadata-helpers.ts | 12 +++--- src/token-processor/util/sip-validation.ts | 4 +- tests/admin/admin-rpc.test.ts | 12 +++--- tests/api/cache.test.ts | 8 ++-- tests/api/ft.test.ts | 8 ++-- tests/api/nft.test.ts | 8 ++-- tests/api/parse-contract-identifiers.test.ts | 2 +- tests/api/search.test.ts | 8 ++-- tests/api/sft.test.ts | 8 ++-- tests/api/status.test.ts | 6 +-- tests/helpers.ts | 10 ++--- tests/stacks-core/block-processor.test.ts | 10 ++--- tests/stacks-core/decode-block.test.ts | 6 ++- tests/stacks-core/ft-events.test.ts | 10 ++--- tests/stacks-core/nft-events.test.ts | 10 ++--- tests/stacks-core/notifications.test.ts | 10 ++--- tests/stacks-core/reorg.test.ts | 10 ++--- tests/stacks-core/sft-events.test.ts | 10 ++--- tests/stacks-core/smart-contracts.test.ts | 10 ++--- tests/token-queue/image-cache.test.ts | 8 ++-- tests/token-queue/job-queue.test.ts | 10 ++--- tests/token-queue/job.test.ts | 14 +++--- tests/token-queue/metadata-helpers.test.ts | 6 +-- .../process-smart-contract-job.test.ts | 10 ++--- tests/token-queue/process-token-job.test.ts | 16 +++---- tests/token-queue/sip-validation.test.ts | 4 +- .../stacks-node-rpc-client.test.ts | 8 ++-- .../update-token-supply-job.test.ts | 10 ++--- tsconfig.json | 8 ++-- util/openapi-generator.ts | 4 +- 64 files changed, 274 insertions(+), 265 deletions(-) rename eslint.config.js => eslint.config.cjs (100%) delete mode 100644 src/api/@types/node-pg-migrate/index.d.ts diff --git a/eslint.config.js b/eslint.config.cjs similarity index 100% rename from eslint.config.js rename to eslint.config.cjs diff --git a/package-lock.json b/package-lock.json index 9318130..b6f712d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,7 +26,7 @@ "fastify-metrics": "^12.1.0", "json5": "^2.2.3", "node-pg-migrate": "^8.0.4", - "p-queue": "^6.6.2", + "p-queue": "^8.1.0", "sharp": "^0.34.5", "undici": "^7.24.4" }, @@ -8277,15 +8277,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -8317,31 +8308,37 @@ } }, "node_modules/p-queue": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", - "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-8.1.1.tgz", + "integrity": "sha512-aNZ+VfjobsWryoiPnEApGGmf5WmNsCo9xu8dfaYamG5qaLP7ClhLN6NgsFe6SwJ2UbLEBK5dv9x8Mn5+RVhMWQ==", "license": "MIT", "dependencies": { - "eventemitter3": "^4.0.4", - "p-timeout": "^3.2.0" + "eventemitter3": "^5.0.1", + "p-timeout": "^6.1.2" }, "engines": { - "node": ">=8" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-queue/node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "license": "MIT" + }, "node_modules/p-timeout": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", - "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.4.tgz", + "integrity": "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==", "license": "MIT", - "dependencies": { - "p-finally": "^1.0.0" - }, "engines": { - "node": ">=8" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/package-json-from-dist": { diff --git a/package.json b/package.json index 518109c..3111d55 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,14 @@ { - "name": "@hirosystems/token-metadata-api", + "name": "@stx-labs/token-metadata-api", "description": "A microservice that indexes metadata for all Fungible, Non-Fungible, and Semi-Fungible Tokens in the Stacks blockchain and exposes it via JSON REST API endpoints", "version": "2.2.1", "repository": { "type": "git", - "url": "https://github.com/hirosystems/token-metadata-api.git" + "url": "https://github.com/stx-labs/token-metadata-api.git" }, + "type": "module", "main": "index.js", - "author": "Hiro Systems PBC (https://hiro.so)", + "author": "Stacks Labs", "license": "GPL-3.0", "engines": { "node": ">=24" @@ -16,7 +17,7 @@ "build": "rimraf ./dist && tsc --project tsconfig.build.json", "build:client": "npm run generate:git-info && npm run generate:openapi && npm run generate:client", "start": "node ./dist/src/index.js", - "start-ts": "ts-node ./src/index.ts", + "start-ts": "node --import tsx ./src/index.ts", "test": "npm run testenv:run && NODE_ENV=test node --import tsx --import ./tests/setup-env.ts --test --test-concurrency=1; EXIT=$?; npm run testenv:stop; exit $EXIT", "test:admin": "npm run test -- ./tests/admin/*.test.ts", "test:api": "npm run test -- ./tests/api/*.test.ts", @@ -24,10 +25,10 @@ "test:token-queue": "npm run test -- ./tests/token-queue/*.test.ts", "testenv:run": "node --import tsx ./tests/setup.ts up", "testenv:stop": "node --import tsx ./tests/setup.ts down", - "migrate": "ts-node node_modules/.bin/node-pg-migrate -j ts", + "migrate": "node --import tsx node_modules/.bin/node-pg-migrate -j ts", "lint:eslint": "eslint . --ext .js,.jsx,.ts,.tsx -f unix", "lint:prettier": "prettier --check src/**/*.ts tests/**/*.ts migrations/**/*.ts", - "generate:openapi": "rimraf ./openapi.yaml && node -r ts-node/register ./util/openapi-generator.ts", + "generate:openapi": "rimraf ./openapi.yaml && node --import tsx ./util/openapi-generator.ts", "generate:git-info": "rimraf .git-info && node_modules/.bin/api-toolkit-git-info", "generate:client": "openapi-typescript ./openapi.yaml -o ./client/src/generated/schema.d.ts" }, @@ -72,7 +73,7 @@ "fastify-metrics": "^12.1.0", "json5": "^2.2.3", "node-pg-migrate": "^8.0.4", - "p-queue": "^6.6.2", + "p-queue": "^8.1.0", "sharp": "^0.34.5", "undici": "^7.24.4" } diff --git a/src/admin-rpc/init.ts b/src/admin-rpc/init.ts index 44dcfa5..e781d9a 100644 --- a/src/admin-rpc/init.ts +++ b/src/admin-rpc/init.ts @@ -1,16 +1,16 @@ import Fastify, { FastifyPluginCallback } from 'fastify'; import { TypeBoxTypeProvider } from '@fastify/type-provider-typebox'; -import { PgStore } from '../pg/pg-store'; +import { PgStore } from '../pg/pg-store.js'; import { Server } from 'http'; import { Type } from '@sinclair/typebox'; -import { SmartContractRegEx } from '../api/schemas'; +import { SmartContractRegEx } from '../api/schemas.js'; import { logger, PINO_LOGGER_CONFIG } from '@stacks/api-toolkit'; -import { reprocessTokenImageCache } from '../token-processor/images/image-cache'; -import { ENV } from '../env'; -import { JobQueue } from '../token-processor/queue/job-queue'; +import { reprocessTokenImageCache } from '../token-processor/images/image-cache.js'; +import { ENV } from '../env.js'; +import { JobQueue } from '../token-processor/queue/job-queue.js'; import { createClient } from '@stacks/blockchain-api-client'; import { ClarityAbi } from '@stacks/transactions'; -import { getSmartContractSip } from '../token-processor/util/sip-validation'; +import { getSmartContractSip } from '../token-processor/util/sip-validation.js'; export const AdminApi: FastifyPluginCallback, Server, TypeBoxTypeProvider> = ( fastify, diff --git a/src/api/@types/fastify/index.d.ts b/src/api/@types/fastify/index.d.ts index ca87463..473b298 100644 --- a/src/api/@types/fastify/index.d.ts +++ b/src/api/@types/fastify/index.d.ts @@ -1,5 +1,5 @@ -import { PgStore } from '../../../pg/pg-store'; -import { JobQueue } from '../../../token-processor/queue/job-queue'; +import { PgStore } from '../../../pg/pg-store.js'; +import { JobQueue } from '../../../token-processor/queue/job-queue.js'; declare module 'fastify' { export interface FastifyInstance< diff --git a/src/api/@types/node-pg-migrate/index.d.ts b/src/api/@types/node-pg-migrate/index.d.ts deleted file mode 100644 index 6f41e0b..0000000 --- a/src/api/@types/node-pg-migrate/index.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare module 'node-pg-migrate' { - export * from 'node-pg-migrate/dist/bundle'; -} diff --git a/src/api/init.ts b/src/api/init.ts index 0ee605e..cae7308 100644 --- a/src/api/init.ts +++ b/src/api/init.ts @@ -1,15 +1,17 @@ import Fastify, { FastifyPluginAsync } from 'fastify'; import { TypeBoxTypeProvider } from '@fastify/type-provider-typebox'; -import { FtRoutes } from './routes/ft'; -import { NftRoutes } from './routes/nft'; -import { SftRoutes } from './routes/sft'; -import { SearchRoutes } from './routes/search'; -import { PgStore } from '../pg/pg-store'; +import { FtRoutes } from './routes/ft.js'; +import { NftRoutes } from './routes/nft.js'; +import { SftRoutes } from './routes/sft.js'; +import { SearchRoutes } from './routes/search.js'; +import { PgStore } from '../pg/pg-store.js'; import FastifyCors from '@fastify/cors'; -import { StatusRoutes } from './routes/status'; -import FastifyMetrics, { IFastifyMetrics } from 'fastify-metrics'; +import { StatusRoutes } from './routes/status.js'; +import FastifyMetricsModule from 'fastify-metrics'; +import type { IFastifyMetrics } from 'fastify-metrics'; +const FastifyMetrics = FastifyMetricsModule.default ?? FastifyMetricsModule; import { Server } from 'http'; -import { isProdEnv } from './util/helpers'; +import { isProdEnv } from './util/helpers.js'; import { PINO_LOGGER_CONFIG } from '@stacks/api-toolkit'; export const Api: FastifyPluginAsync, Server, TypeBoxTypeProvider> = async ( diff --git a/src/api/routes/ft.ts b/src/api/routes/ft.ts index d11bbfe..ac4d233 100644 --- a/src/api/routes/ft.ts +++ b/src/api/routes/ft.ts @@ -15,10 +15,10 @@ import { PaginatedResponse, StacksAddressParam, TokenQuerystringParams, -} from '../schemas'; -import { handleChainTipCache, handleTokenCache } from '../util/cache'; -import { generateTokenErrorResponse, TokenErrorResponseSchema } from '../util/errors'; -import { parseMetadataLocaleBundle } from '../util/helpers'; +} from '../schemas.js'; +import { handleChainTipCache, handleTokenCache } from '../util/cache.js'; +import { generateTokenErrorResponse, TokenErrorResponseSchema } from '../util/errors.js'; +import { parseMetadataLocaleBundle } from '../util/helpers.js'; const IndexRoutes: FastifyPluginCallback, Server, TypeBoxTypeProvider> = ( fastify, diff --git a/src/api/routes/nft.ts b/src/api/routes/nft.ts index 47cd0fe..39f0d08 100644 --- a/src/api/routes/nft.ts +++ b/src/api/routes/nft.ts @@ -7,10 +7,10 @@ import { NftPrincipalParam, TokenIdParam, TokenQuerystringParams, -} from '../schemas'; -import { handleTokenCache } from '../util/cache'; -import { parseMetadataLocaleBundle } from '../util/helpers'; -import { generateTokenErrorResponse, TokenErrorResponseSchema } from '../util/errors'; +} from '../schemas.js'; +import { handleTokenCache } from '../util/cache.js'; +import { parseMetadataLocaleBundle } from '../util/helpers.js'; +import { generateTokenErrorResponse, TokenErrorResponseSchema } from '../util/errors.js'; export const NftRoutes: FastifyPluginCallback, Server, TypeBoxTypeProvider> = ( fastify, diff --git a/src/api/routes/search.ts b/src/api/routes/search.ts index c9368f6..61f4e74 100644 --- a/src/api/routes/search.ts +++ b/src/api/routes/search.ts @@ -1,9 +1,9 @@ import { TypeBoxTypeProvider } from '@fastify/type-provider-typebox'; import { FastifyPluginCallback } from 'fastify'; import { Server } from 'http'; -import { SearchQuerystringParams, SearchResponse } from '../schemas'; -import { handleBulkTokenCache } from '../util/cache'; -import { parseContractIdentifiers } from '../util/helpers'; +import { SearchQuerystringParams, SearchResponse } from '../schemas.js'; +import { handleBulkTokenCache } from '../util/cache.js'; +import { parseContractIdentifiers } from '../util/helpers.js'; export const SearchRoutes: FastifyPluginCallback< Record, diff --git a/src/api/routes/sft.ts b/src/api/routes/sft.ts index 6e11ced..f260719 100644 --- a/src/api/routes/sft.ts +++ b/src/api/routes/sft.ts @@ -7,10 +7,10 @@ import { SftPrincipalParam, TokenIdParam, TokenQuerystringParams, -} from '../schemas'; -import { handleTokenCache } from '../util/cache'; -import { parseMetadataLocaleBundle } from '../util/helpers'; -import { generateTokenErrorResponse, TokenErrorResponseSchema } from '../util/errors'; +} from '../schemas.js'; +import { handleTokenCache } from '../util/cache.js'; +import { parseMetadataLocaleBundle } from '../util/helpers.js'; +import { generateTokenErrorResponse, TokenErrorResponseSchema } from '../util/errors.js'; export const SftRoutes: FastifyPluginCallback, Server, TypeBoxTypeProvider> = ( fastify, diff --git a/src/api/routes/status.ts b/src/api/routes/status.ts index 17eec91..be0642f 100644 --- a/src/api/routes/status.ts +++ b/src/api/routes/status.ts @@ -1,9 +1,9 @@ import { TypeBoxTypeProvider } from '@fastify/type-provider-typebox'; import { FastifyPluginCallback } from 'fastify'; import { Server } from 'http'; -import { ApiStatusResponse } from '../schemas'; +import { ApiStatusResponse } from '../schemas.js'; import { SERVER_VERSION } from '@stacks/api-toolkit'; -import { handleChainTipCache } from '../util/cache'; +import { handleChainTipCache } from '../util/cache.js'; export const StatusRoutes: FastifyPluginCallback< Record, diff --git a/src/api/schemas.ts b/src/api/schemas.ts index b54a1b3..ad58e1a 100644 --- a/src/api/schemas.ts +++ b/src/api/schemas.ts @@ -2,7 +2,11 @@ import { SwaggerOptions } from '@fastify/swagger'; import { Static, TSchema, Type } from '@sinclair/typebox'; import { isProdEnv, logger, SERVER_VERSION } from '@stacks/api-toolkit'; import { readFileSync } from 'fs'; -import { resolve } from 'path'; +import { fileURLToPath } from 'url'; +import { dirname, resolve } from 'path'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); const Nullable = (type: T) => Type.Union([type, Type.Null()]); diff --git a/src/api/util/cache.ts b/src/api/util/cache.ts index 9c1a9e1..6d4a897 100644 --- a/src/api/util/cache.ts +++ b/src/api/util/cache.ts @@ -1,7 +1,7 @@ import { FastifyReply, FastifyRequest } from 'fastify'; -import { SmartContractRegEx } from '../schemas'; +import { SmartContractRegEx } from '../schemas.js'; import { CACHE_CONTROL_MUST_REVALIDATE, parseIfNoneMatchHeader } from '@stacks/api-toolkit'; -import { parseContractIdentifiers } from './helpers'; +import { parseContractIdentifiers } from './helpers.js'; enum ETagType { chainTip = 'chain_tip', diff --git a/src/api/util/errors.ts b/src/api/util/errors.ts index e5486ed..7b641af 100644 --- a/src/api/util/errors.ts +++ b/src/api/util/errors.ts @@ -7,7 +7,7 @@ import { TokenNotProcessedResponse, NotFoundResponse, ContractNotFoundResponse, -} from '../schemas'; +} from '../schemas.js'; import { ContractNotFoundError, InvalidContractError, @@ -15,9 +15,9 @@ import { TokenLocaleNotFoundError, TokenNotFoundError, TokenNotProcessedError, -} from '../../pg/errors'; -import { setReplyNonCacheable } from './cache'; -import { DbJobInvalidReason } from '../../pg/types'; +} from '../../pg/errors.js'; +import { setReplyNonCacheable } from './cache.js'; +import { DbJobInvalidReason } from '../../pg/types.js'; export const TokenErrorResponseSchema = { 404: NotFoundResponse, diff --git a/src/api/util/helpers.ts b/src/api/util/helpers.ts index 1029175..f121606 100644 --- a/src/api/util/helpers.ts +++ b/src/api/util/helpers.ts @@ -1,5 +1,5 @@ -import { DbMetadataLocaleBundle } from '../../pg/types'; -import { MetadataPropertiesType, MetadataType, MetadataValueType } from '../schemas'; +import { DbMetadataLocaleBundle } from '../../pg/types.js'; +import { MetadataPropertiesType, MetadataType, MetadataValueType } from '../schemas.js'; export const isDevEnv = process.env.NODE_ENV === 'development'; export const isTestEnv = process.env.NODE_ENV === 'test'; diff --git a/src/index.ts b/src/index.ts index 3df8d42..eab44e9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,12 +1,12 @@ -import { PgStore } from './pg/pg-store'; -import { JobQueue } from './token-processor/queue/job-queue'; -import { buildApiServer, buildPromServer } from './api/init'; -import { TokenProcessorMetrics } from './token-processor/token-processor-metrics'; -import { ENV } from './env'; -import { buildAdminRpcServer } from './admin-rpc/init'; -import { isProdEnv } from './api/util/helpers'; +import { PgStore } from './pg/pg-store.js'; +import { JobQueue } from './token-processor/queue/job-queue.js'; +import { buildApiServer, buildPromServer } from './api/init.js'; +import { TokenProcessorMetrics } from './token-processor/token-processor-metrics.js'; +import { ENV } from './env.js'; +import { buildAdminRpcServer } from './admin-rpc/init.js'; +import { isProdEnv } from './api/util/helpers.js'; import { buildProfilerServer, logger, registerShutdownConfig } from '@stacks/api-toolkit'; -import { buildSnpEventStreamHandler } from './stacks-core/snp-event-stream'; +import { buildSnpEventStreamHandler } from './stacks-core/snp-event-stream.js'; import { StacksNetworkName } from '@stacks/network'; /** diff --git a/src/pg/errors.ts b/src/pg/errors.ts index 5c2e691..bb06b7a 100644 --- a/src/pg/errors.ts +++ b/src/pg/errors.ts @@ -1,4 +1,4 @@ -import { DbJobInvalidReason } from './types'; +import { DbJobInvalidReason } from './types.js'; export class TokenNotFoundError extends Error { constructor() { diff --git a/src/pg/pg-store.ts b/src/pg/pg-store.ts index 241ca03..62bef65 100644 --- a/src/pg/pg-store.ts +++ b/src/pg/pg-store.ts @@ -1,4 +1,4 @@ -import { ENV } from '../env'; +import { ENV } from '../env.js'; import { DbSmartContract, DbJobStatus, @@ -18,7 +18,7 @@ import { DbFungibleTokenOrder, DbJobInvalidReason, DbBlock, -} from './types'; +} from './types.js'; import { ContractNotFoundError, InvalidContractError, @@ -26,8 +26,8 @@ import { TokenLocaleNotFoundError, TokenNotFoundError, TokenNotProcessedError, -} from './errors'; -import { FtOrderBy, Order } from '../api/schemas'; +} from './errors.js'; +import { FtOrderBy, Order } from '../api/schemas.js'; import { BasePgStore, PgSqlClient, @@ -36,7 +36,11 @@ import { runMigrations, } from '@stacks/api-toolkit'; import * as path from 'path'; -import { StacksCorePgStore } from './stacks-core-pg-store'; +import { fileURLToPath } from 'url'; +import { StacksCorePgStore } from './stacks-core-pg-store.js'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); export const MIGRATIONS_DIR = path.join(__dirname, '../../migrations'); diff --git a/src/pg/stacks-core-pg-store.ts b/src/pg/stacks-core-pg-store.ts index 2a19778..a4d0e8e 100644 --- a/src/pg/stacks-core-pg-store.ts +++ b/src/pg/stacks-core-pg-store.ts @@ -1,11 +1,11 @@ import { BasePgStoreModule, PgSqlClient, batchIterate } from '@stacks/api-toolkit'; -import { ENV } from '../env'; +import { ENV } from '../env.js'; import { NftMintEvent, SftMintEvent, SmartContractDeployment, TokenMetadataUpdateNotification, -} from '../token-processor/util/sip-validation'; +} from '../token-processor/util/sip-validation.js'; import { DbSmartContractInsert, DbTokenType, @@ -21,9 +21,9 @@ import { DbMetadataInsert, DbMetadataAttributeInsert, DbMetadataPropertyInsert, -} from './types'; -import { dbSipNumberToDbTokenType } from '../token-processor/util/helpers'; -import { DecodedStacksBlock } from '../stacks-core/stacks-core-block-processor'; +} from './types.js'; +import { dbSipNumberToDbTokenType } from '../token-processor/util/helpers.js'; +import { DecodedStacksBlock } from '../stacks-core/stacks-core-block-processor.js'; export class StacksCorePgStore extends BasePgStoreModule { /** diff --git a/src/pg/types.ts b/src/pg/types.ts index db2b38a..a85b35b 100644 --- a/src/pg/types.ts +++ b/src/pg/types.ts @@ -1,5 +1,5 @@ import { PgJsonb, PgNumeric } from '@stacks/api-toolkit'; -import { FtOrderBy, Order } from '../api/schemas'; +import { FtOrderBy, Order } from '../api/schemas.js'; export type DbBlock = { index_block_hash: string; diff --git a/src/stacks-core/snp-event-stream.ts b/src/stacks-core/snp-event-stream.ts index 7c1a214..c3b4a04 100644 --- a/src/stacks-core/snp-event-stream.ts +++ b/src/stacks-core/snp-event-stream.ts @@ -1,9 +1,9 @@ import { SERVER_VERSION } from '@stacks/api-toolkit'; import { logger as defaultLogger } from '@stacks/api-toolkit'; import { EventEmitter } from 'node:events'; -import { decodeStacksCoreBlock, StacksCoreBlockProcessor } from './stacks-core-block-processor'; +import { decodeStacksCoreBlock, StacksCoreBlockProcessor } from './stacks-core-block-processor.js'; import { StacksMessageStream, MessagePath, Message } from '@stacks/node-publisher-client'; -import { PgStore } from '../pg/pg-store'; +import { PgStore } from '../pg/pg-store.js'; /** * Handles the SNP event stream and processes Stacks Core blocks. diff --git a/src/stacks-core/stacks-core-block-processor.ts b/src/stacks-core/stacks-core-block-processor.ts index 0da6e19..6e6dd99 100644 --- a/src/stacks-core/stacks-core-block-processor.ts +++ b/src/stacks-core/stacks-core-block-processor.ts @@ -7,14 +7,14 @@ import { SftMintEvent, SmartContractDeployment, TokenMetadataUpdateNotification, -} from '../token-processor/util/sip-validation'; +} from '../token-processor/util/sip-validation.js'; import { ClarityTypeID, decodeClarityValue, DecodedTxResult, decodeTransaction, } from '@stacks/codec'; -import { StacksCorePgStore } from '../pg/stacks-core-pg-store'; +import { StacksCorePgStore } from '../pg/stacks-core-pg-store.js'; import { logger, stopwatch } from '@stacks/api-toolkit'; import { NewBlockContractEvent, diff --git a/src/token-processor/images/image-cache.ts b/src/token-processor/images/image-cache.ts index 38ab826..6d3135c 100644 --- a/src/token-processor/images/image-cache.ts +++ b/src/token-processor/images/image-cache.ts @@ -1,7 +1,7 @@ -import { ENV } from '../../env'; -import { parseDataUrl, getFetchableMetadataUrl } from '../util/metadata-helpers'; +import { ENV } from '../../env.js'; +import { parseDataUrl, getFetchableMetadataUrl } from '../util/metadata-helpers.js'; import { logger } from '@stacks/api-toolkit'; -import { PgStore } from '../../pg/pg-store'; +import { PgStore } from '../../pg/pg-store.js'; import { Readable } from 'node:stream'; import sharp from 'sharp'; import fs from 'fs'; @@ -13,7 +13,7 @@ import { UndiciCauseTypeError, ImageHttpError, ImageParseError, -} from '../util/errors'; +} from '../util/errors.js'; import { pipeline } from 'node:stream/promises'; import { Storage } from '@google-cloud/storage'; diff --git a/src/token-processor/queue/helpers.ts b/src/token-processor/queue/helpers.ts index 223e2cf..6f44989 100644 --- a/src/token-processor/queue/helpers.ts +++ b/src/token-processor/queue/helpers.ts @@ -1,4 +1,4 @@ -import { ENV } from '../../env'; +import { ENV } from '../../env.js'; export enum JobQueueProcessingMode { /** diff --git a/src/token-processor/queue/job-queue.ts b/src/token-processor/queue/job-queue.ts index 2b26b5c..63b8b4c 100644 --- a/src/token-processor/queue/job-queue.ts +++ b/src/token-processor/queue/job-queue.ts @@ -1,12 +1,12 @@ import PQueue from 'p-queue'; -import { PgStore } from '../../pg/pg-store'; -import { DbJob, DbJobStatus } from '../../pg/types'; -import { ENV } from '../../env'; -import { ProcessSmartContractJob } from './job/process-smart-contract-job'; -import { ProcessTokenJob } from './job/process-token-job'; +import { PgStore } from '../../pg/pg-store.js'; +import { DbJob, DbJobStatus } from '../../pg/types.js'; +import { ENV } from '../../env.js'; +import { ProcessSmartContractJob } from './job/process-smart-contract-job.js'; +import { ProcessTokenJob } from './job/process-token-job.js'; import { logger, timeout } from '@stacks/api-toolkit'; import { StacksNetworkName } from '@stacks/network'; -import { UpdateTokenSupplyJob } from './job/update-token-supply-job'; +import { UpdateTokenSupplyJob } from './job/update-token-supply-job.js'; /** * A priority queue that organizes all necessary work for contract ingestion and token metadata diff --git a/src/token-processor/queue/job/job.ts b/src/token-processor/queue/job/job.ts index adb698a..55aef94 100644 --- a/src/token-processor/queue/job/job.ts +++ b/src/token-processor/queue/job/job.ts @@ -1,10 +1,10 @@ import { logger, resolveOrTimeout, stopwatch } from '@stacks/api-toolkit'; -import { ENV } from '../../../env'; -import { PgStore } from '../../../pg/pg-store'; -import { DbJob, DbJobInvalidReason, DbJobStatus } from '../../../pg/types'; -import { getUserErrorInvalidReason, TooManyRequestsHttpError, UserError } from '../../util/errors'; -import { RetryableJobError } from '../errors'; -import { getJobQueueProcessingMode, JobQueueProcessingMode } from '../helpers'; +import { ENV } from '../../../env.js'; +import { PgStore } from '../../../pg/pg-store.js'; +import { DbJob, DbJobInvalidReason, DbJobStatus } from '../../../pg/types.js'; +import { getUserErrorInvalidReason, TooManyRequestsHttpError, UserError } from '../../util/errors.js'; +import { RetryableJobError } from '../errors.js'; +import { getJobQueueProcessingMode, JobQueueProcessingMode } from '../helpers.js'; import { StacksNetworkName } from '@stacks/network'; /** diff --git a/src/token-processor/queue/job/process-smart-contract-job.ts b/src/token-processor/queue/job/process-smart-contract-job.ts index 9c15d77..7a32a11 100644 --- a/src/token-processor/queue/job/process-smart-contract-job.ts +++ b/src/token-processor/queue/job/process-smart-contract-job.ts @@ -1,7 +1,7 @@ -import { ENV } from '../../../env'; -import { DbSipNumber, DbSmartContract } from '../../../pg/types'; -import { Job } from './job'; -import { StacksNodeRpcClient } from '../../stacks-node/stacks-node-rpc-client'; +import { ENV } from '../../../env.js'; +import { DbSipNumber, DbSmartContract } from '../../../pg/types.js'; +import { Job } from './job.js'; +import { StacksNodeRpcClient } from '../../stacks-node/stacks-node-rpc-client.js'; import { logger } from '@stacks/api-toolkit'; /** diff --git a/src/token-processor/queue/job/process-token-job.ts b/src/token-processor/queue/job/process-token-job.ts index 472046f..b851fb6 100644 --- a/src/token-processor/queue/job/process-token-job.ts +++ b/src/token-processor/queue/job/process-token-job.ts @@ -6,16 +6,16 @@ import { DbSmartContract, DbToken, DbTokenType, -} from '../../../pg/types'; -import { StacksNodeRpcClient } from '../../stacks-node/stacks-node-rpc-client'; -import { SmartContractClarityError } from '../../util/errors'; +} from '../../../pg/types.js'; +import { StacksNodeRpcClient } from '../../stacks-node/stacks-node-rpc-client.js'; +import { SmartContractClarityError } from '../../util/errors.js'; import { fetchAllMetadataLocalesFromBaseUri, getFetchableMetadataUrl, getTokenSpecificUri, -} from '../../util/metadata-helpers'; -import { RetryableJobError } from '../errors'; -import { Job } from './job'; +} from '../../util/metadata-helpers.js'; +import { RetryableJobError } from '../errors.js'; +import { Job } from './job.js'; import { PgNumeric, logger } from '@stacks/api-toolkit'; /** diff --git a/src/token-processor/queue/job/update-token-supply-job.ts b/src/token-processor/queue/job/update-token-supply-job.ts index d3a85f5..7e8a512 100644 --- a/src/token-processor/queue/job/update-token-supply-job.ts +++ b/src/token-processor/queue/job/update-token-supply-job.ts @@ -1,9 +1,9 @@ import { cvToHex, uintCV } from '@stacks/transactions'; import { ClarityValueUInt, decodeClarityValueToRepr } from '@stacks/codec'; -import { DbSmartContract, DbToken, DbTokenType } from '../../../pg/types'; -import { StacksNodeRpcClient } from '../../stacks-node/stacks-node-rpc-client'; -import { SmartContractClarityError } from '../../util/errors'; -import { Job } from './job'; +import { DbSmartContract, DbToken, DbTokenType } from '../../../pg/types.js'; +import { StacksNodeRpcClient } from '../../stacks-node/stacks-node-rpc-client.js'; +import { SmartContractClarityError } from '../../util/errors.js'; +import { Job } from './job.js'; import { PgNumeric, logger } from '@stacks/api-toolkit'; /** diff --git a/src/token-processor/stacks-node/stacks-node-rpc-client.ts b/src/token-processor/stacks-node/stacks-node-rpc-client.ts index 333361a..5c45b81 100644 --- a/src/token-processor/stacks-node/stacks-node-rpc-client.ts +++ b/src/token-processor/stacks-node/stacks-node-rpc-client.ts @@ -1,12 +1,12 @@ import { ClarityTypeID, ClarityValue, ClarityValueUInt, decodeClarityValue } from '@stacks/codec'; import { request, errors } from 'undici'; -import { ENV } from '../../env'; -import { RetryableJobError } from '../queue/errors'; +import { ENV } from '../../env.js'; +import { RetryableJobError } from '../queue/errors.js'; import { SmartContractClarityError, StacksNodeJsonParseError, StacksNodeHttpError, -} from '../util/errors'; +} from '../util/errors.js'; import { ClarityAbi, getAddressFromPrivateKey, makeRandomPrivKey } from '@stacks/transactions'; import { StacksNetworkName } from '@stacks/network'; diff --git a/src/token-processor/token-processor-metrics.ts b/src/token-processor/token-processor-metrics.ts index 71cfae7..db67f77 100644 --- a/src/token-processor/token-processor-metrics.ts +++ b/src/token-processor/token-processor-metrics.ts @@ -1,5 +1,5 @@ import * as prom from 'prom-client'; -import { PgStore } from '../pg/pg-store'; +import { PgStore } from '../pg/pg-store.js'; export class TokenProcessorMetrics { readonly token_metadata_block_height: prom.Gauge; diff --git a/src/token-processor/util/errors.ts b/src/token-processor/util/errors.ts index 7dc3e71..99b529c 100644 --- a/src/token-processor/util/errors.ts +++ b/src/token-processor/util/errors.ts @@ -1,6 +1,6 @@ import { errors } from 'undici'; -import { parseRetryAfterResponseHeader } from './helpers'; -import { DbJobInvalidReason } from '../../pg/types'; +import { parseRetryAfterResponseHeader } from './helpers.js'; +import { DbJobInvalidReason } from '../../pg/types.js'; export interface UndiciCauseTypeError extends TypeError { cause?: unknown; diff --git a/src/token-processor/util/helpers.ts b/src/token-processor/util/helpers.ts index bc22bbb..76ce222 100644 --- a/src/token-processor/util/helpers.ts +++ b/src/token-processor/util/helpers.ts @@ -1,5 +1,5 @@ import { errors } from 'undici'; -import { DbSipNumber, DbTokenType } from '../../pg/types'; +import { DbSipNumber, DbTokenType } from '../../pg/types.js'; export function dbSipNumberToDbTokenType(sip: DbSipNumber): DbTokenType { switch (sip) { diff --git a/src/token-processor/util/metadata-helpers.ts b/src/token-processor/util/metadata-helpers.ts index 50bae46..74fd1d0 100644 --- a/src/token-processor/util/metadata-helpers.ts +++ b/src/token-processor/util/metadata-helpers.ts @@ -8,8 +8,8 @@ import { DbMetadataPropertyInsert, DbSmartContract, DbToken, -} from '../../pg/types'; -import { ENV } from '../../env'; +} from '../../pg/types.js'; +import { ENV } from '../../env.js'; import { MetadataHttpError, MetadataParseError, @@ -17,9 +17,9 @@ import { MetadataTimeoutError, TooManyRequestsHttpError, UndiciCauseTypeError, -} from './errors'; -import { RetryableJobError } from '../queue/errors'; -import { processImageCache } from '../images/image-cache'; +} from './errors.js'; +import { RetryableJobError } from '../queue/errors.js'; +import { processImageCache } from '../images/image-cache.js'; import { RawMetadataLocale, RawMetadataLocalizationCType, @@ -27,7 +27,7 @@ import { RawMetadataPropertiesCType, RawMetadataCType, RawMetadata, -} from './types'; +} from './types.js'; import { logger } from '@stacks/api-toolkit'; const METADATA_FETCH_HTTP_AGENT = new Agent({ diff --git a/src/token-processor/util/sip-validation.ts b/src/token-processor/util/sip-validation.ts index 042b33c..8b4edab 100644 --- a/src/token-processor/util/sip-validation.ts +++ b/src/token-processor/util/sip-validation.ts @@ -8,8 +8,8 @@ import { decodeClarityValue, TxPayloadTypeID, } from '@stacks/codec'; -import { DbSipNumber } from '../../pg/types'; -import { DecodedStacksTransaction } from '../../stacks-core/stacks-core-block-processor'; +import { DbSipNumber } from '../../pg/types.js'; +import { DecodedStacksTransaction } from '../../stacks-core/stacks-core-block-processor.js'; import { NewBlockContractEvent } from '@stacks/node-publisher-client'; const FtTraitFunctions: ClarityAbiFunction[] = [ diff --git a/tests/admin/admin-rpc.test.ts b/tests/admin/admin-rpc.test.ts index 2f0759c..93461bb 100644 --- a/tests/admin/admin-rpc.test.ts +++ b/tests/admin/admin-rpc.test.ts @@ -1,17 +1,17 @@ import { strict as assert } from 'node:assert'; import { after, afterEach, before, beforeEach, describe, test } from 'node:test'; import { cycleMigrations } from '@stacks/api-toolkit'; -import { buildAdminRpcServer } from '../../src/admin-rpc/init'; -import { ENV } from '../../src/env'; -import { MIGRATIONS_DIR, PgStore } from '../../src/pg/pg-store'; -import { DbJobStatus, DbSipNumber } from '../../src/pg/types'; +import { buildAdminRpcServer } from '../../src/admin-rpc/init.js'; +import { ENV } from '../../src/env.js'; +import { MIGRATIONS_DIR, PgStore } from '../../src/pg/pg-store.js'; +import { DbJobStatus, DbSipNumber } from '../../src/pg/types.js'; import { insertAndEnqueueTestContractWithTokens, markAllJobsAsDone, SIP_010_ABI, TestFastifyServer, -} from '../helpers'; -import { JobQueue } from '../../src/token-processor/queue/job-queue'; +} from '../helpers.js'; +import { JobQueue } from '../../src/token-processor/queue/job-queue.js'; import nock from 'nock'; describe('Admin RPC', () => { diff --git a/tests/api/cache.test.ts b/tests/api/cache.test.ts index cfa03bb..945b933 100644 --- a/tests/api/cache.test.ts +++ b/tests/api/cache.test.ts @@ -1,13 +1,13 @@ import { strict as assert } from 'node:assert'; import { cycleMigrations } from '@stacks/api-toolkit'; -import { ENV } from '../../src/env'; -import { MIGRATIONS_DIR, PgStore } from '../../src/pg/pg-store'; -import { DbSipNumber } from '../../src/pg/types'; +import { ENV } from '../../src/env.js'; +import { MIGRATIONS_DIR, PgStore } from '../../src/pg/pg-store.js'; +import { DbSipNumber } from '../../src/pg/types.js'; import { TestFastifyServer, insertAndEnqueueTestContractWithTokens, startTestApiServer, -} from '../helpers'; +} from '../helpers.js'; import { afterEach, beforeEach, describe, test } from 'node:test'; describe('ETag cache', () => { diff --git a/tests/api/ft.test.ts b/tests/api/ft.test.ts index 76d9926..f537054 100644 --- a/tests/api/ft.test.ts +++ b/tests/api/ft.test.ts @@ -1,14 +1,14 @@ import { strict as assert } from 'node:assert'; import { cycleMigrations } from '@stacks/api-toolkit'; -import { ENV } from '../../src/env'; -import { MIGRATIONS_DIR, PgStore } from '../../src/pg/pg-store'; -import { DbFungibleTokenMetadataItem, DbSipNumber } from '../../src/pg/types'; +import { ENV } from '../../src/env.js'; +import { MIGRATIONS_DIR, PgStore } from '../../src/pg/pg-store.js'; +import { DbFungibleTokenMetadataItem, DbSipNumber } from '../../src/pg/types.js'; import { insertAndEnqueueTestContract, insertAndEnqueueTestContractWithTokens, startTestApiServer, TestFastifyServer, -} from '../helpers'; +} from '../helpers.js'; import { afterEach, beforeEach, describe, test } from 'node:test'; describe('FT routes', () => { diff --git a/tests/api/nft.test.ts b/tests/api/nft.test.ts index 13ecc48..7ccd7e9 100644 --- a/tests/api/nft.test.ts +++ b/tests/api/nft.test.ts @@ -1,14 +1,14 @@ import { strict as assert } from 'node:assert'; import { cycleMigrations } from '@stacks/api-toolkit'; -import { ENV } from '../../src/env'; -import { MIGRATIONS_DIR, PgStore } from '../../src/pg/pg-store'; +import { ENV } from '../../src/env.js'; +import { MIGRATIONS_DIR, PgStore } from '../../src/pg/pg-store.js'; import { insertAndEnqueueTestContract, insertAndEnqueueTestContractWithTokens, startTestApiServer, TestFastifyServer, -} from '../helpers'; -import { DbSipNumber } from '../../src/pg/types'; +} from '../helpers.js'; +import { DbSipNumber } from '../../src/pg/types.js'; import { afterEach, beforeEach, describe, test } from 'node:test'; describe('NFT routes', () => { diff --git a/tests/api/parse-contract-identifiers.test.ts b/tests/api/parse-contract-identifiers.test.ts index 6966e42..0b0fd3f 100644 --- a/tests/api/parse-contract-identifiers.test.ts +++ b/tests/api/parse-contract-identifiers.test.ts @@ -1,5 +1,5 @@ import { strict as assert } from 'node:assert'; -import { parseContractIdentifiers } from '../../src/api/util/helpers'; +import { parseContractIdentifiers } from '../../src/api/util/helpers.js'; import { describe, test } from 'node:test'; describe('parseContractIdentifiers', () => { diff --git a/tests/api/search.test.ts b/tests/api/search.test.ts index 97637bf..b877f5c 100644 --- a/tests/api/search.test.ts +++ b/tests/api/search.test.ts @@ -1,13 +1,13 @@ import { strict as assert } from 'node:assert'; import { cycleMigrations } from '@stacks/api-toolkit'; -import { ENV } from '../../src/env'; -import { MIGRATIONS_DIR, PgStore } from '../../src/pg/pg-store'; -import { DbSipNumber } from '../../src/pg/types'; +import { ENV } from '../../src/env.js'; +import { MIGRATIONS_DIR, PgStore } from '../../src/pg/pg-store.js'; +import { DbSipNumber } from '../../src/pg/types.js'; import { insertAndEnqueueTestContractWithTokens, startTestApiServer, TestFastifyServer, -} from '../helpers'; +} from '../helpers.js'; import { afterEach, beforeEach, describe, test } from 'node:test'; describe('Search routes', () => { diff --git a/tests/api/sft.test.ts b/tests/api/sft.test.ts index 5f4f58a..6c7e281 100644 --- a/tests/api/sft.test.ts +++ b/tests/api/sft.test.ts @@ -1,14 +1,14 @@ import { strict as assert } from 'node:assert'; import { cycleMigrations } from '@stacks/api-toolkit'; -import { ENV } from '../../src/env'; -import { MIGRATIONS_DIR, PgStore } from '../../src/pg/pg-store'; -import { DbSipNumber } from '../../src/pg/types'; +import { ENV } from '../../src/env.js'; +import { MIGRATIONS_DIR, PgStore } from '../../src/pg/pg-store.js'; +import { DbSipNumber } from '../../src/pg/types.js'; import { insertAndEnqueueTestContract, insertAndEnqueueTestContractWithTokens, startTestApiServer, TestFastifyServer, -} from '../helpers'; +} from '../helpers.js'; import { afterEach, beforeEach, describe, test } from 'node:test'; describe('SFT routes', () => { diff --git a/tests/api/status.test.ts b/tests/api/status.test.ts index efe7b92..240b371 100644 --- a/tests/api/status.test.ts +++ b/tests/api/status.test.ts @@ -1,8 +1,8 @@ import { strict as assert } from 'node:assert'; import { cycleMigrations } from '@stacks/api-toolkit'; -import { ENV } from '../../src/env'; -import { MIGRATIONS_DIR, PgStore } from '../../src/pg/pg-store'; -import { startTestApiServer, TestFastifyServer } from '../helpers'; +import { ENV } from '../../src/env.js'; +import { MIGRATIONS_DIR, PgStore } from '../../src/pg/pg-store.js'; +import { startTestApiServer, TestFastifyServer } from '../helpers.js'; import { afterEach, beforeEach, describe, test } from 'node:test'; describe('Status routes', () => { diff --git a/tests/helpers.ts b/tests/helpers.ts index 27bcc76..6d08728 100644 --- a/tests/helpers.ts +++ b/tests/helpers.ts @@ -1,16 +1,16 @@ import * as http from 'http'; -import { PgStore } from '../src/pg/pg-store'; -import { buildApiServer } from '../src/api/init'; +import { PgStore } from '../src/pg/pg-store.js'; +import { buildApiServer } from '../src/api/init.js'; import { FastifyBaseLogger, FastifyInstance } from 'fastify'; import { IncomingMessage, Server, ServerResponse } from 'http'; import { TypeBoxTypeProvider } from '@fastify/type-provider-typebox'; -import { SmartContractDeployment } from '../src/token-processor/util/sip-validation'; -import { DbJob, DbSipNumber, DbSmartContract, DbUpdateNotification } from '../src/pg/types'; +import { SmartContractDeployment } from '../src/token-processor/util/sip-validation.js'; +import { DbJob, DbSipNumber, DbSmartContract, DbUpdateNotification } from '../src/pg/types.js'; import { waiter } from '@stacks/api-toolkit'; import { DecodedStacksBlock, DecodedStacksTransaction, -} from '../src/stacks-core/stacks-core-block-processor'; +} from '../src/stacks-core/stacks-core-block-processor.js'; import { AnchorModeID, DecodedTxResult, diff --git a/tests/stacks-core/block-processor.test.ts b/tests/stacks-core/block-processor.test.ts index ec20b55..418eac6 100644 --- a/tests/stacks-core/block-processor.test.ts +++ b/tests/stacks-core/block-processor.test.ts @@ -1,16 +1,16 @@ import { strict as assert } from 'node:assert'; import { cvToHex, tupleCV, bufferCV, uintCV, stringUtf8CV } from '@stacks/transactions'; -import { DbSipNumber } from '../../src/pg/types'; +import { DbSipNumber } from '../../src/pg/types.js'; import { cycleMigrations } from '@stacks/api-toolkit'; -import { ENV } from '../../src/env'; -import { PgStore, MIGRATIONS_DIR } from '../../src/pg/pg-store'; +import { ENV } from '../../src/env.js'; +import { PgStore, MIGRATIONS_DIR } from '../../src/pg/pg-store.js'; import { insertAndEnqueueTestContractWithTokens, markAllJobsAsDone, TestTransactionBuilder, TestBlockBuilder, -} from '../helpers'; -import { StacksCoreBlockProcessor } from '../../src/stacks-core/stacks-core-block-processor'; +} from '../helpers.js'; +import { StacksCoreBlockProcessor } from '../../src/stacks-core/stacks-core-block-processor.js'; import { afterEach, beforeEach, describe, test } from 'node:test'; describe('block processor', () => { diff --git a/tests/stacks-core/decode-block.test.ts b/tests/stacks-core/decode-block.test.ts index 254195f..5005723 100644 --- a/tests/stacks-core/decode-block.test.ts +++ b/tests/stacks-core/decode-block.test.ts @@ -1,10 +1,14 @@ import { strict as assert } from 'node:assert'; import * as path from 'path'; import * as fs from 'fs'; +import { fileURLToPath } from 'url'; import { NewBlockMessage } from '@stacks/node-publisher-client'; -import { decodeStacksCoreBlock } from '../../src/stacks-core/stacks-core-block-processor'; +import { decodeStacksCoreBlock } from '../../src/stacks-core/stacks-core-block-processor.js'; import { describe, test } from 'node:test'; +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + describe('decode block', () => { test('decodes stacks 2.x block with burnchain op tx', () => { const blockMessage = JSON.parse( diff --git a/tests/stacks-core/ft-events.test.ts b/tests/stacks-core/ft-events.test.ts index 05de50e..037e684 100644 --- a/tests/stacks-core/ft-events.test.ts +++ b/tests/stacks-core/ft-events.test.ts @@ -1,15 +1,15 @@ import { strict as assert } from 'node:assert'; -import { DbProcessedTokenUpdateBundle, DbSipNumber } from '../../src/pg/types'; +import { DbProcessedTokenUpdateBundle, DbSipNumber } from '../../src/pg/types.js'; import { cycleMigrations } from '@stacks/api-toolkit'; -import { ENV } from '../../src/env'; -import { PgStore, MIGRATIONS_DIR } from '../../src/pg/pg-store'; +import { ENV } from '../../src/env.js'; +import { PgStore, MIGRATIONS_DIR } from '../../src/pg/pg-store.js'; import { insertAndEnqueueTestContractWithTokens, markAllJobsAsDone, TestTransactionBuilder, TestBlockBuilder, -} from '../helpers'; -import { StacksCoreBlockProcessor } from '../../src/stacks-core/stacks-core-block-processor'; +} from '../helpers.js'; +import { StacksCoreBlockProcessor } from '../../src/stacks-core/stacks-core-block-processor.js'; import { afterEach, beforeEach, describe, test } from 'node:test'; describe('ft events', () => { diff --git a/tests/stacks-core/nft-events.test.ts b/tests/stacks-core/nft-events.test.ts index a186e66..d838ef8 100644 --- a/tests/stacks-core/nft-events.test.ts +++ b/tests/stacks-core/nft-events.test.ts @@ -1,17 +1,17 @@ import { strict as assert } from 'node:assert'; import { cvToHex, uintCV } from '@stacks/transactions'; -import { DbSipNumber } from '../../src/pg/types'; +import { DbSipNumber } from '../../src/pg/types.js'; import { cycleMigrations } from '@stacks/api-toolkit'; -import { ENV } from '../../src/env'; -import { PgStore, MIGRATIONS_DIR } from '../../src/pg/pg-store'; +import { ENV } from '../../src/env.js'; +import { PgStore, MIGRATIONS_DIR } from '../../src/pg/pg-store.js'; import { insertAndEnqueueTestContractWithTokens, markAllJobsAsDone, TestTransactionBuilder, TestBlockBuilder, SIP_009_ABI, -} from '../helpers'; -import { StacksCoreBlockProcessor } from '../../src/stacks-core/stacks-core-block-processor'; +} from '../helpers.js'; +import { StacksCoreBlockProcessor } from '../../src/stacks-core/stacks-core-block-processor.js'; import { afterEach, beforeEach, describe, test } from 'node:test'; describe('nft events', () => { diff --git a/tests/stacks-core/notifications.test.ts b/tests/stacks-core/notifications.test.ts index 4dc2076..87f5769 100644 --- a/tests/stacks-core/notifications.test.ts +++ b/tests/stacks-core/notifications.test.ts @@ -1,9 +1,9 @@ import { strict as assert } from 'node:assert'; import { cvToHex, tupleCV, bufferCV, listCV, uintCV, stringUtf8CV } from '@stacks/transactions'; -import { DbSipNumber } from '../../src/pg/types'; +import { DbSipNumber } from '../../src/pg/types.js'; import { cycleMigrations } from '@stacks/api-toolkit'; -import { ENV } from '../../src/env'; -import { PgStore, MIGRATIONS_DIR } from '../../src/pg/pg-store'; +import { ENV } from '../../src/env.js'; +import { PgStore, MIGRATIONS_DIR } from '../../src/pg/pg-store.js'; import { getLatestContractTokenNotifications, getLatestTokenNotification, @@ -11,8 +11,8 @@ import { markAllJobsAsDone, TestTransactionBuilder, TestBlockBuilder, -} from '../helpers'; -import { StacksCoreBlockProcessor } from '../../src/stacks-core/stacks-core-block-processor'; +} from '../helpers.js'; +import { StacksCoreBlockProcessor } from '../../src/stacks-core/stacks-core-block-processor.js'; import { afterEach, beforeEach, describe, test } from 'node:test'; describe('token metadata notifications', () => { diff --git a/tests/stacks-core/reorg.test.ts b/tests/stacks-core/reorg.test.ts index d6a2c58..6a6aa75 100644 --- a/tests/stacks-core/reorg.test.ts +++ b/tests/stacks-core/reorg.test.ts @@ -1,17 +1,17 @@ import { strict as assert } from 'node:assert'; import { cvToHex, tupleCV, bufferCV, uintCV } from '@stacks/transactions'; -import { DbSipNumber } from '../../src/pg/types'; +import { DbSipNumber } from '../../src/pg/types.js'; import { cycleMigrations } from '@stacks/api-toolkit'; -import { ENV } from '../../src/env'; -import { PgStore, MIGRATIONS_DIR } from '../../src/pg/pg-store'; +import { ENV } from '../../src/env.js'; +import { PgStore, MIGRATIONS_DIR } from '../../src/pg/pg-store.js'; import { TestTransactionBuilder, TestBlockBuilder, SIP_009_ABI, SIP_010_ABI, markAllJobsAsDone, -} from '../helpers'; -import { StacksCoreBlockProcessor } from '../../src/stacks-core/stacks-core-block-processor'; +} from '../helpers.js'; +import { StacksCoreBlockProcessor } from '../../src/stacks-core/stacks-core-block-processor.js'; import { after, before, describe, test } from 'node:test'; describe('re-org handling', () => { diff --git a/tests/stacks-core/sft-events.test.ts b/tests/stacks-core/sft-events.test.ts index ff5da16..558b504 100644 --- a/tests/stacks-core/sft-events.test.ts +++ b/tests/stacks-core/sft-events.test.ts @@ -1,16 +1,16 @@ import { strict as assert } from 'node:assert'; import { cvToHex, tupleCV, bufferCV, uintCV } from '@stacks/transactions'; -import { DbSipNumber, DbTokenType } from '../../src/pg/types'; +import { DbSipNumber, DbTokenType } from '../../src/pg/types.js'; import { cycleMigrations } from '@stacks/api-toolkit'; -import { ENV } from '../../src/env'; -import { PgStore, MIGRATIONS_DIR } from '../../src/pg/pg-store'; +import { ENV } from '../../src/env.js'; +import { PgStore, MIGRATIONS_DIR } from '../../src/pg/pg-store.js'; import { insertAndEnqueueTestContract, TestTransactionBuilder, TestBlockBuilder, markAllJobsAsDone, -} from '../helpers'; -import { StacksCoreBlockProcessor } from '../../src/stacks-core/stacks-core-block-processor'; +} from '../helpers.js'; +import { StacksCoreBlockProcessor } from '../../src/stacks-core/stacks-core-block-processor.js'; import { afterEach, beforeEach, describe, test } from 'node:test'; describe('sft events', () => { diff --git a/tests/stacks-core/smart-contracts.test.ts b/tests/stacks-core/smart-contracts.test.ts index ae6f844..c1bf3fb 100644 --- a/tests/stacks-core/smart-contracts.test.ts +++ b/tests/stacks-core/smart-contracts.test.ts @@ -1,10 +1,10 @@ import { strict as assert } from 'node:assert'; -import { DbSipNumber } from '../../src/pg/types'; +import { DbSipNumber } from '../../src/pg/types.js'; import { cycleMigrations } from '@stacks/api-toolkit'; -import { ENV } from '../../src/env'; -import { PgStore, MIGRATIONS_DIR } from '../../src/pg/pg-store'; -import { SIP_009_ABI, TestTransactionBuilder, TestBlockBuilder } from '../helpers'; -import { StacksCoreBlockProcessor } from '../../src/stacks-core/stacks-core-block-processor'; +import { ENV } from '../../src/env.js'; +import { PgStore, MIGRATIONS_DIR } from '../../src/pg/pg-store.js'; +import { SIP_009_ABI, TestTransactionBuilder, TestBlockBuilder } from '../helpers.js'; +import { StacksCoreBlockProcessor } from '../../src/stacks-core/stacks-core-block-processor.js'; import { afterEach, beforeEach, describe, test } from 'node:test'; describe('contract deployments', () => { diff --git a/tests/token-queue/image-cache.test.ts b/tests/token-queue/image-cache.test.ts index dacd80e..d3efbb8 100644 --- a/tests/token-queue/image-cache.test.ts +++ b/tests/token-queue/image-cache.test.ts @@ -1,12 +1,12 @@ import { strict as assert } from 'node:assert'; -import { ENV } from '../../src/env'; -import { processImageCache } from '../../src/token-processor/images/image-cache'; -import { closeTestServer, startTestResponseServer, startTimeoutServer } from '../helpers'; +import { ENV } from '../../src/env.js'; +import { processImageCache } from '../../src/token-processor/images/image-cache.js'; +import { closeTestServer, startTestResponseServer, startTimeoutServer } from '../helpers.js'; import { ImageHttpError, ImageTimeoutError, TooManyRequestsHttpError, -} from '../../src/token-processor/util/errors'; +} from '../../src/token-processor/util/errors.js'; import { before, describe, test } from 'node:test'; describe('Image cache', () => { diff --git a/tests/token-queue/job-queue.test.ts b/tests/token-queue/job-queue.test.ts index 7e4b35c..205115c 100644 --- a/tests/token-queue/job-queue.test.ts +++ b/tests/token-queue/job-queue.test.ts @@ -1,9 +1,9 @@ import { strict as assert } from 'node:assert'; -import { ENV } from '../../src/env'; -import { MIGRATIONS_DIR, PgStore } from '../../src/pg/pg-store'; -import { DbJob, DbJobStatus, DbSipNumber } from '../../src/pg/types'; -import { JobQueue } from '../../src/token-processor/queue/job-queue'; -import { insertAndEnqueueTestContract } from '../helpers'; +import { ENV } from '../../src/env.js'; +import { MIGRATIONS_DIR, PgStore } from '../../src/pg/pg-store.js'; +import { DbJob, DbJobStatus, DbSipNumber } from '../../src/pg/types.js'; +import { JobQueue } from '../../src/token-processor/queue/job-queue.js'; +import { insertAndEnqueueTestContract } from '../helpers.js'; import { cycleMigrations, timeout } from '@stacks/api-toolkit'; import { StacksNetworkName } from '@stacks/network'; import { afterEach, beforeEach, describe, test } from 'node:test'; diff --git a/tests/token-queue/job.test.ts b/tests/token-queue/job.test.ts index 1fada7b..96ee501 100644 --- a/tests/token-queue/job.test.ts +++ b/tests/token-queue/job.test.ts @@ -1,12 +1,12 @@ import { strict as assert } from 'node:assert'; import { cycleMigrations, timeout } from '@stacks/api-toolkit'; -import { ENV } from '../../src/env'; -import { MIGRATIONS_DIR, PgStore } from '../../src/pg/pg-store'; -import { DbJob, DbSipNumber } from '../../src/pg/types'; -import { RetryableJobError } from '../../src/token-processor/queue/errors'; -import { Job } from '../../src/token-processor/queue/job/job'; -import { UserError } from '../../src/token-processor/util/errors'; -import { insertAndEnqueueTestContract } from '../helpers'; +import { ENV } from '../../src/env.js'; +import { MIGRATIONS_DIR, PgStore } from '../../src/pg/pg-store.js'; +import { DbJob, DbSipNumber } from '../../src/pg/types.js'; +import { RetryableJobError } from '../../src/token-processor/queue/errors.js'; +import { Job } from '../../src/token-processor/queue/job/job.js'; +import { UserError } from '../../src/token-processor/util/errors.js'; +import { insertAndEnqueueTestContract } from '../helpers.js'; import { afterEach, beforeEach, describe, test } from 'node:test'; class TestRetryableJob extends Job { diff --git a/tests/token-queue/metadata-helpers.test.ts b/tests/token-queue/metadata-helpers.test.ts index 0fcecb0..36624d2 100644 --- a/tests/token-queue/metadata-helpers.test.ts +++ b/tests/token-queue/metadata-helpers.test.ts @@ -1,13 +1,13 @@ import { strict as assert } from 'node:assert'; import { MockAgent, setGlobalDispatcher } from 'undici'; -import { ENV } from '../../src/env'; -import { MetadataHttpError, MetadataParseError } from '../../src/token-processor/util/errors'; +import { ENV } from '../../src/env.js'; +import { MetadataHttpError, MetadataParseError } from '../../src/token-processor/util/errors.js'; import { getFetchableMetadataUrl, getMetadataFromUri, getTokenSpecificUri, fetchMetadata, -} from '../../src/token-processor/util/metadata-helpers'; +} from '../../src/token-processor/util/metadata-helpers.js'; import { describe, test } from 'node:test'; describe('Metadata Helpers', () => { diff --git a/tests/token-queue/process-smart-contract-job.test.ts b/tests/token-queue/process-smart-contract-job.test.ts index 66b0f84..b1d9c64 100644 --- a/tests/token-queue/process-smart-contract-job.test.ts +++ b/tests/token-queue/process-smart-contract-job.test.ts @@ -1,12 +1,12 @@ import { strict as assert } from 'node:assert'; import { cvToHex, uintCV } from '@stacks/transactions'; import { MockAgent, setGlobalDispatcher } from 'undici'; -import { MIGRATIONS_DIR, PgStore } from '../../src/pg/pg-store'; -import { DbSipNumber, DbToken, DbTokenType } from '../../src/pg/types'; -import { ProcessSmartContractJob } from '../../src/token-processor/queue/job/process-smart-contract-job'; -import { ENV } from '../../src/env'; +import { MIGRATIONS_DIR, PgStore } from '../../src/pg/pg-store.js'; +import { DbSipNumber, DbToken, DbTokenType } from '../../src/pg/types.js'; +import { ProcessSmartContractJob } from '../../src/token-processor/queue/job/process-smart-contract-job.js'; +import { ENV } from '../../src/env.js'; import { cycleMigrations } from '@stacks/api-toolkit'; -import { insertAndEnqueueTestContract } from '../helpers'; +import { insertAndEnqueueTestContract } from '../helpers.js'; import { afterEach, beforeEach, describe, test } from 'node:test'; describe('ProcessSmartContractJob', () => { diff --git a/tests/token-queue/process-token-job.test.ts b/tests/token-queue/process-token-job.test.ts index 6fe4c70..f75d17a 100644 --- a/tests/token-queue/process-token-job.test.ts +++ b/tests/token-queue/process-token-job.test.ts @@ -2,21 +2,21 @@ import { strict as assert } from 'node:assert'; import { mock } from 'node:test'; import { cvToHex, noneCV, stringUtf8CV, uintCV } from '@stacks/transactions'; import { errors, MockAgent, setGlobalDispatcher } from 'undici'; -import { MIGRATIONS_DIR, PgStore } from '../../src/pg/pg-store'; +import { MIGRATIONS_DIR, PgStore } from '../../src/pg/pg-store.js'; import { DbJob, DbJobStatus, DbMetadataAttribute, DbMetadataProperty, DbSipNumber, -} from '../../src/pg/types'; -import { ENV } from '../../src/env'; -import { ProcessTokenJob } from '../../src/token-processor/queue/job/process-token-job'; -import { parseRetryAfterResponseHeader } from '../../src/token-processor/util/helpers'; -import { RetryableJobError } from '../../src/token-processor/queue/errors'; +} from '../../src/pg/types.js'; +import { ENV } from '../../src/env.js'; +import { ProcessTokenJob } from '../../src/token-processor/queue/job/process-token-job.js'; +import { parseRetryAfterResponseHeader } from '../../src/token-processor/util/helpers.js'; +import { RetryableJobError } from '../../src/token-processor/queue/errors.js'; import { cycleMigrations } from '@stacks/api-toolkit'; -import { insertAndEnqueueTestContractWithTokens } from '../helpers'; -import { InvalidTokenError } from '../../src/pg/errors'; +import { insertAndEnqueueTestContractWithTokens } from '../helpers.js'; +import { InvalidTokenError } from '../../src/pg/errors.js'; import { afterEach, beforeEach, describe, test } from 'node:test'; describe('ProcessTokenJob', () => { diff --git a/tests/token-queue/sip-validation.test.ts b/tests/token-queue/sip-validation.test.ts index 55107b6..6d72c51 100644 --- a/tests/token-queue/sip-validation.test.ts +++ b/tests/token-queue/sip-validation.test.ts @@ -9,8 +9,8 @@ import { tupleCV, uintCV, } from '@stacks/transactions'; -import { getContractLogMetadataUpdateNotification } from '../../src/token-processor/util/sip-validation'; -import { TestTransactionBuilder } from '../helpers'; +import { getContractLogMetadataUpdateNotification } from '../../src/token-processor/util/sip-validation.js'; +import { TestTransactionBuilder } from '../helpers.js'; import { NewBlockContractEvent, NewBlockEventType } from '@stacks/node-publisher-client'; import { describe, test } from 'node:test'; diff --git a/tests/token-queue/stacks-node-rpc-client.test.ts b/tests/token-queue/stacks-node-rpc-client.test.ts index 030a4fd..995fb55 100644 --- a/tests/token-queue/stacks-node-rpc-client.test.ts +++ b/tests/token-queue/stacks-node-rpc-client.test.ts @@ -7,13 +7,13 @@ import { noneCV, } from '@stacks/transactions'; import { MockAgent, setGlobalDispatcher } from 'undici'; -import { ENV } from '../../src/env'; -import { RetryableJobError } from '../../src/token-processor/queue/errors'; -import { StacksNodeRpcClient } from '../../src/token-processor/stacks-node/stacks-node-rpc-client'; +import { ENV } from '../../src/env.js'; +import { RetryableJobError } from '../../src/token-processor/queue/errors.js'; +import { StacksNodeRpcClient } from '../../src/token-processor/stacks-node/stacks-node-rpc-client.js'; import { StacksNodeJsonParseError, StacksNodeHttpError, -} from '../../src/token-processor/util/errors'; +} from '../../src/token-processor/util/errors.js'; import { beforeEach, describe, test } from 'node:test'; describe('StacksNodeRpcClient', () => { diff --git a/tests/token-queue/update-token-supply-job.test.ts b/tests/token-queue/update-token-supply-job.test.ts index ec03f1a..c7018f4 100644 --- a/tests/token-queue/update-token-supply-job.test.ts +++ b/tests/token-queue/update-token-supply-job.test.ts @@ -1,12 +1,12 @@ import { strict as assert } from 'node:assert'; import { cvToHex, uintCV } from '@stacks/transactions'; import { MockAgent, setGlobalDispatcher } from 'undici'; -import { MIGRATIONS_DIR, PgStore } from '../../src/pg/pg-store'; -import { DbJob, DbSipNumber } from '../../src/pg/types'; -import { ENV } from '../../src/env'; +import { MIGRATIONS_DIR, PgStore } from '../../src/pg/pg-store.js'; +import { DbJob, DbSipNumber } from '../../src/pg/types.js'; +import { ENV } from '../../src/env.js'; import { cycleMigrations } from '@stacks/api-toolkit'; -import { insertAndEnqueueTestContractWithTokens, markAllJobsAsDone } from '../helpers'; -import { UpdateTokenSupplyJob } from '../../src/token-processor/queue/job/update-token-supply-job'; +import { insertAndEnqueueTestContractWithTokens, markAllJobsAsDone } from '../helpers.js'; +import { UpdateTokenSupplyJob } from '../../src/token-processor/queue/job/update-token-supply-job.js'; import { afterEach, beforeEach, describe, test } from 'node:test'; describe('UpdateTokenSupplyJob', () => { diff --git a/tsconfig.json b/tsconfig.json index ae31700..98b7b91 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,9 +11,9 @@ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ /* Language and Environment */ - "target": "es2021" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, + "target": "es2022" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, "lib": [ - "es2021" + "es2022" ] /* Specify a set of bundled library declaration files that describe the target runtime environment. */, // "jsx": "preserve", /* Specify what JSX code is generated. */ // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ @@ -27,9 +27,9 @@ // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ /* Modules */ - "module": "commonjs" /* Specify what module code is generated. */, + "module": "nodenext" /* Specify what module code is generated. */, // "rootDir": "./", /* Specify the root folder within your source files. */ - "moduleResolution": "node" /* Specify how TypeScript looks up a file from a given module specifier. */, + "moduleResolution": "nodenext" /* Specify how TypeScript looks up a file from a given module specifier. */, // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ diff --git a/util/openapi-generator.ts b/util/openapi-generator.ts index 65bb22b..154d6c5 100644 --- a/util/openapi-generator.ts +++ b/util/openapi-generator.ts @@ -1,9 +1,9 @@ import Fastify from 'fastify'; import { TypeBoxTypeProvider } from '@fastify/type-provider-typebox'; -import { Api } from '../src/api/init'; +import { Api } from '../src/api/init.js'; import FastifySwagger from '@fastify/swagger'; import { writeFileSync } from 'fs'; -import { OpenApiSchemaOptions } from '../src/api/schemas'; +import { OpenApiSchemaOptions } from '../src/api/schemas.js'; /** * Generates `openapi.yaml` based on current Swagger definitions. From 5d722dbf62e9fac254a0cfbfe2528daea4d60b9b Mon Sep 17 00:00:00 2001 From: Rafa Cardenas <253999660+rafa-stacks@users.noreply.github.com> Date: Thu, 26 Mar 2026 13:45:30 -0600 Subject: [PATCH 06/12] remove husky, update lint config --- .husky/commit-msg | 4 - CHANGELOG.md | 565 ---------------------------------------------- eslint.config.cjs | 52 ----- eslint.config.js | 52 +++++ package-lock.json | 21 +- package.json | 1 - 6 files changed, 54 insertions(+), 641 deletions(-) delete mode 100755 .husky/commit-msg delete mode 100644 CHANGELOG.md delete mode 100644 eslint.config.cjs create mode 100644 eslint.config.js diff --git a/.husky/commit-msg b/.husky/commit-msg deleted file mode 100755 index ff33e02..0000000 --- a/.husky/commit-msg +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env sh -. "$(dirname -- "$0")/_/husky.sh" - -npx commitlint --edit diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 140b218..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,565 +0,0 @@ -## [2.0.0-next.3](https://github.com/hirosystems/token-metadata-api/compare/v2.0.0-next.2...v2.0.0-next.3) (2026-02-10) - -### ⚠ BREAKING CHANGES - -* ingest stacks core events from SNP instead of chainhooks (#334) - -### Features - -* ingest stacks core events from SNP instead of chainhooks ([#334](https://github.com/hirosystems/token-metadata-api/issues/334)) ([645c8ad](https://github.com/hirosystems/token-metadata-api/commit/645c8adea937b53037ce571b1c2c49c8fcfcf1cd)) - -## [2.0.0-next.2](https://github.com/hirosystems/token-metadata-api/compare/v2.0.0-next.1...v2.0.0-next.2) (2026-01-06) - -### Bug Fixes - -* add repo urls to package json ([#333](https://github.com/hirosystems/token-metadata-api/issues/333)) ([a37776e](https://github.com/hirosystems/token-metadata-api/commit/a37776ec1b5ffdefa41106d6f8e71009262a8993)) - -## [2.0.0-next.1](https://github.com/hirosystems/token-metadata-api/compare/v1.3.2...v2.0.0-next.1) (2026-01-06) - -### ⚠ BREAKING CHANGES - -* consolidate migration files (#332) - -### Miscellaneous Chores - -* consolidate migration files ([#332](https://github.com/hirosystems/token-metadata-api/issues/332)) ([5a6a3c8](https://github.com/hirosystems/token-metadata-api/commit/5a6a3c8cbf6f41a0cddf15905166d5c4cd6a94a4)) - -## [1.3.2](https://github.com/hirosystems/token-metadata-api/compare/v1.3.1...v1.3.2) (2025-10-02) - - -### Bug Fixes - -* force close db connection after a configurable timeout ([#321](https://github.com/hirosystems/token-metadata-api/issues/321)) ([2b02e81](https://github.com/hirosystems/token-metadata-api/commit/2b02e81095e10584be0649b749af4d15dd43337e)) - -## [1.3.1](https://github.com/hirosystems/token-metadata-api/compare/v1.3.0...v1.3.1) (2025-10-02) - - -### Bug Fixes - -* replace hard coded IPFS gateways with configurable gateway ([#319](https://github.com/hirosystems/token-metadata-api/issues/319)) ([d04012f](https://github.com/hirosystems/token-metadata-api/commit/d04012f9187a8885bab5046bb626010f681f57fb)) - -## [1.3.0](https://github.com/hirosystems/token-metadata-api/compare/v1.2.0...v1.3.0) (2025-06-16) - - -### Features - -* add `/import-contract` admin rpc endpoint ([#309](https://github.com/hirosystems/token-metadata-api/issues/309)) ([3aef505](https://github.com/hirosystems/token-metadata-api/commit/3aef5055cdb0afa3b682a23aff124a8ae91960ec)) - - -### Bug Fixes - -* update chainhook predicate start_block upon re-registration ([#308](https://github.com/hirosystems/token-metadata-api/issues/308)) ([929f08e](https://github.com/hirosystems/token-metadata-api/commit/929f08e33dedd4b7499799c468483692312d839f)) - -## [1.3.0-beta.1](https://github.com/hirosystems/token-metadata-api/compare/v1.2.1-beta.1...v1.3.0-beta.1) (2025-06-10) - - -### Features - -* add `/import-contract` admin rpc endpoint ([#309](https://github.com/hirosystems/token-metadata-api/issues/309)) ([3aef505](https://github.com/hirosystems/token-metadata-api/commit/3aef5055cdb0afa3b682a23aff124a8ae91960ec)) - -## [1.2.1-beta.1](https://github.com/hirosystems/token-metadata-api/compare/v1.2.0...v1.2.1-beta.1) (2025-06-04) - - -### Bug Fixes - -* update chainhook predicate start_block upon re-registration ([#308](https://github.com/hirosystems/token-metadata-api/issues/308)) ([929f08e](https://github.com/hirosystems/token-metadata-api/commit/929f08e33dedd4b7499799c468483692312d839f)) - -## [1.2.0](https://github.com/hirosystems/token-metadata-api/compare/v1.1.7...v1.2.0) (2025-04-18) - - -### Features - -* show asset_identifier in ft list response, add filter by valid metadata ([#298](https://github.com/hirosystems/token-metadata-api/issues/298)) ([aae897a](https://github.com/hirosystems/token-metadata-api/commit/aae897ad862ed8489f7f36c8083240c1e1677214)) - - -### Bug Fixes - -* add db indexes to optimize endpoint queries ([#296](https://github.com/hirosystems/token-metadata-api/issues/296)) ([50c75e6](https://github.com/hirosystems/token-metadata-api/commit/50c75e639c5527d6127692f21d3e72f1c56461c2)) - -## [1.1.7](https://github.com/hirosystems/token-metadata-api/compare/v1.1.6...v1.1.7) (2025-04-04) - - -### Bug Fixes - -* return fts without sip16 metadata in search results ([#293](https://github.com/hirosystems/token-metadata-api/issues/293)) ([24028ae](https://github.com/hirosystems/token-metadata-api/commit/24028aeba6e7676456351e1e04e6b72668ecc44b)) - -## [1.1.6](https://github.com/hirosystems/token-metadata-api/compare/v1.1.5...v1.1.6) (2024-12-17) - - -### Bug Fixes - -* display token supply with correct decimals ([#287](https://github.com/hirosystems/token-metadata-api/issues/287)) ([94c7b4a](https://github.com/hirosystems/token-metadata-api/commit/94c7b4a2ae68697e35e87c73d7f7e132bf1afad6)) -* roll back FT supply display, update docs instead ([#288](https://github.com/hirosystems/token-metadata-api/issues/288)) ([080176e](https://github.com/hirosystems/token-metadata-api/commit/080176e036bbb85bba82c1d619a69a60d7df21c3)), closes [#287](https://github.com/hirosystems/token-metadata-api/issues/287) -* update ft date on supply change ([#289](https://github.com/hirosystems/token-metadata-api/issues/289)) ([94b9486](https://github.com/hirosystems/token-metadata-api/commit/94b94868a3808324a0f6c23d0e423886dd143fa4)) - -## [1.1.5](https://github.com/hirosystems/token-metadata-api/compare/v1.1.4...v1.1.5) (2024-12-16) - - -### Bug Fixes - -* allow multiple sft mints for the same token per transaction ([#279](https://github.com/hirosystems/token-metadata-api/issues/279)) ([9b28880](https://github.com/hirosystems/token-metadata-api/commit/9b28880815a75f93f218fae69dc6e7147c908514)) -* process nft and sft mints in batches ([#271](https://github.com/hirosystems/token-metadata-api/issues/271)) ([c98f0cd](https://github.com/hirosystems/token-metadata-api/commit/c98f0cd6a1001933764ab2fbb4026f8824127f35)) -* upgrade to new chainhook ts client ([#280](https://github.com/hirosystems/token-metadata-api/issues/280)) ([b67dc8c](https://github.com/hirosystems/token-metadata-api/commit/b67dc8cd4e21f91a50a1c0c85880d2f265ab1d51)) - -## [1.1.5-beta.3](https://github.com/hirosystems/token-metadata-api/compare/v1.1.5-beta.2...v1.1.5-beta.3) (2024-10-22) - - -### Bug Fixes - -* upgrade to new chainhook ts client ([#280](https://github.com/hirosystems/token-metadata-api/issues/280)) ([b67dc8c](https://github.com/hirosystems/token-metadata-api/commit/b67dc8cd4e21f91a50a1c0c85880d2f265ab1d51)) - -## [1.1.5-beta.2](https://github.com/hirosystems/token-metadata-api/compare/v1.1.5-beta.1...v1.1.5-beta.2) (2024-10-21) - - -### Bug Fixes - -* allow multiple sft mints for the same token per transaction ([#279](https://github.com/hirosystems/token-metadata-api/issues/279)) ([9b28880](https://github.com/hirosystems/token-metadata-api/commit/9b28880815a75f93f218fae69dc6e7147c908514)) - -## [1.1.5-beta.1](https://github.com/hirosystems/token-metadata-api/compare/v1.1.4...v1.1.5-beta.1) (2024-10-07) - - -### Bug Fixes - -* process nft and sft mints in batches ([#271](https://github.com/hirosystems/token-metadata-api/issues/271)) ([c98f0cd](https://github.com/hirosystems/token-metadata-api/commit/c98f0cd6a1001933764ab2fbb4026f8824127f35)) - -## [1.1.4](https://github.com/hirosystems/token-metadata-api/compare/v1.1.3...v1.1.4) (2024-09-23) - - -### Bug Fixes - -* treat non-compliant SIP-016 metadata as invalid ([#266](https://github.com/hirosystems/token-metadata-api/issues/266)) ([288723d](https://github.com/hirosystems/token-metadata-api/commit/288723d577d35ecd38c75c26d572a28f548388fc)) - -## [1.1.3](https://github.com/hirosystems/token-metadata-api/compare/v1.1.2...v1.1.3) (2024-09-23) - - -### Bug Fixes - -* ignore events from failed transactions ([#264](https://github.com/hirosystems/token-metadata-api/issues/264)) ([84252a7](https://github.com/hirosystems/token-metadata-api/commit/84252a7d218de39f5c9379f933af99d49186c9fe)) - -## [1.1.2](https://github.com/hirosystems/token-metadata-api/compare/v1.1.1...v1.1.2) (2024-08-30) - - -### Bug Fixes - -* handle updated chain tip on rollbacks correctly ([#261](https://github.com/hirosystems/token-metadata-api/issues/261)) ([b85b1d3](https://github.com/hirosystems/token-metadata-api/commit/b85b1d3903a336d5691e05387140fcc1e8a41f16)) - -## [1.1.1](https://github.com/hirosystems/token-metadata-api/compare/v1.1.0...v1.1.1) (2024-08-30) - - -### Bug Fixes - -* allow boolean metadata properties ([#260](https://github.com/hirosystems/token-metadata-api/issues/260)) ([d52861a](https://github.com/hirosystems/token-metadata-api/commit/d52861a1434d51ffd340063ca2cc5ccc4bb03676)) - -## [1.1.0](https://github.com/hirosystems/token-metadata-api/compare/v1.0.3...v1.1.0) (2024-08-30) - - -### Features - -* add configurable delay for retrying jobs ([#257](https://github.com/hirosystems/token-metadata-api/issues/257)) ([20d753a](https://github.com/hirosystems/token-metadata-api/commit/20d753a82a4e7f214cf9dc8cb2fee333ac5a4f4c)) - - -### Bug Fixes - -* add chain tip etag generator ([#255](https://github.com/hirosystems/token-metadata-api/issues/255)) ([2b993cd](https://github.com/hirosystems/token-metadata-api/commit/2b993cd34484e156db9e24be8571c0e0e5b4bde0)) -* retry when a contract is not yet found ([#256](https://github.com/hirosystems/token-metadata-api/issues/256)) ([46d8fc8](https://github.com/hirosystems/token-metadata-api/commit/46d8fc892790d64e2a2646efbc64d97be4a109e3)) - -## [1.0.3](https://github.com/hirosystems/token-metadata-api/compare/v1.0.2...v1.0.3) (2024-08-27) - - -### Bug Fixes - -* correctly classify image errors vs metadata errors ([#251](https://github.com/hirosystems/token-metadata-api/issues/251)) ([7369554](https://github.com/hirosystems/token-metadata-api/commit/736955451c651f7c5f9d4d985060bfa68dee7b27)) - -## [1.0.2](https://github.com/hirosystems/token-metadata-api/compare/v1.0.1...v1.0.2) (2024-08-27) - - -### Bug Fixes - -* add block_height to status and prometheus ([#250](https://github.com/hirosystems/token-metadata-api/issues/250)) ([4502c7d](https://github.com/hirosystems/token-metadata-api/commit/4502c7dd2ba8ad6ef3159e0abdad482e73437800)) - -## [1.0.1](https://github.com/hirosystems/token-metadata-api/compare/v1.0.0...v1.0.1) (2024-08-27) - - -### Bug Fixes - -* demote server connection errors and contract clarity errors to be non-retryable ([#249](https://github.com/hirosystems/token-metadata-api/issues/249)) ([87ad8af](https://github.com/hirosystems/token-metadata-api/commit/87ad8af6e36a139950286da1b37818dc32f30927)) - -## [1.0.0](https://github.com/hirosystems/token-metadata-api/compare/v0.7.0...v1.0.0) (2024-08-26) - - -### ⚠ BREAKING CHANGES - -* use chainhook to listen for chain events instead of a direct stacks api connection (#200) - -### Features - -* convert data: image uris into image files and upload to cdn ([#245](https://github.com/hirosystems/token-metadata-api/issues/245)) ([903b0aa](https://github.com/hirosystems/token-metadata-api/commit/903b0aa2a63acc3340fdde570201f5c424f4443c)) - - -### Bug Fixes - -* catch econnreset errors ([#247](https://github.com/hirosystems/token-metadata-api/issues/247)) ([51347d6](https://github.com/hirosystems/token-metadata-api/commit/51347d635d4e50f299af07fef8378ae279f14461)) -* set maximum job timeout ([#244](https://github.com/hirosystems/token-metadata-api/issues/244)) ([3444917](https://github.com/hirosystems/token-metadata-api/commit/344491770172a8f8a22f4f5d8c485fd98256997c)) -* take only first page of gif images ([#241](https://github.com/hirosystems/token-metadata-api/issues/241)) ([334f8c5](https://github.com/hirosystems/token-metadata-api/commit/334f8c524d976719f9d33ed611ddf6a1a8e7bb05)) -* use bignumber to handle FT supplies ([#239](https://github.com/hirosystems/token-metadata-api/issues/239)) ([053d622](https://github.com/hirosystems/token-metadata-api/commit/053d622d33bc46401acbe80980010e2407383c1a)) -* use google cloud library for image uploads ([#238](https://github.com/hirosystems/token-metadata-api/issues/238)) ([c7f1b43](https://github.com/hirosystems/token-metadata-api/commit/c7f1b4368dbec0e028a4e7676c82c25f0ebaeb09)) -* use prometheus port configured in ENV ([c769d29](https://github.com/hirosystems/token-metadata-api/commit/c769d2950d65448265caf2bf6bd78fce437358c0)) - - -### Code Refactoring - -* use chainhook to listen for chain events instead of a direct stacks api connection ([#200](https://github.com/hirosystems/token-metadata-api/issues/200)) ([2ddb2c7](https://github.com/hirosystems/token-metadata-api/commit/2ddb2c7db37419538bd4267c863aaf1f8a2ec5c1)), closes [#229](https://github.com/hirosystems/token-metadata-api/issues/229) [#232](https://github.com/hirosystems/token-metadata-api/issues/232) [#233](https://github.com/hirosystems/token-metadata-api/issues/233) [#234](https://github.com/hirosystems/token-metadata-api/issues/234) [#235](https://github.com/hirosystems/token-metadata-api/issues/235) [#236](https://github.com/hirosystems/token-metadata-api/issues/236) - -## [1.0.0-beta.7](https://github.com/hirosystems/token-metadata-api/compare/v1.0.0-beta.6...v1.0.0-beta.7) (2024-08-26) - - -### Bug Fixes - -* catch econnreset errors ([#247](https://github.com/hirosystems/token-metadata-api/issues/247)) ([51347d6](https://github.com/hirosystems/token-metadata-api/commit/51347d635d4e50f299af07fef8378ae279f14461)) - -## [1.0.0-beta.6](https://github.com/hirosystems/token-metadata-api/compare/v1.0.0-beta.5...v1.0.0-beta.6) (2024-08-26) - - -### Features - -* convert data: image uris into image files and upload to cdn ([#245](https://github.com/hirosystems/token-metadata-api/issues/245)) ([903b0aa](https://github.com/hirosystems/token-metadata-api/commit/903b0aa2a63acc3340fdde570201f5c424f4443c)) - -## [1.0.0-beta.5](https://github.com/hirosystems/token-metadata-api/compare/v1.0.0-beta.4...v1.0.0-beta.5) (2024-08-26) - - -### Bug Fixes - -* set maximum job timeout ([#244](https://github.com/hirosystems/token-metadata-api/issues/244)) ([3444917](https://github.com/hirosystems/token-metadata-api/commit/344491770172a8f8a22f4f5d8c485fd98256997c)) - -## [1.0.0-beta.4](https://github.com/hirosystems/token-metadata-api/compare/v1.0.0-beta.3...v1.0.0-beta.4) (2024-08-24) - - -### Bug Fixes - -* take only first page of gif images ([#241](https://github.com/hirosystems/token-metadata-api/issues/241)) ([334f8c5](https://github.com/hirosystems/token-metadata-api/commit/334f8c524d976719f9d33ed611ddf6a1a8e7bb05)) - -## [1.0.0-beta.3](https://github.com/hirosystems/token-metadata-api/compare/v1.0.0-beta.2...v1.0.0-beta.3) (2024-08-22) - - -### Bug Fixes - -* use bignumber to handle FT supplies ([#239](https://github.com/hirosystems/token-metadata-api/issues/239)) ([053d622](https://github.com/hirosystems/token-metadata-api/commit/053d622d33bc46401acbe80980010e2407383c1a)) - -## [1.0.0-beta.2](https://github.com/hirosystems/token-metadata-api/compare/v1.0.0-beta.1...v1.0.0-beta.2) (2024-08-22) - - -### Bug Fixes - -* use google cloud library for image uploads ([#238](https://github.com/hirosystems/token-metadata-api/issues/238)) ([c7f1b43](https://github.com/hirosystems/token-metadata-api/commit/c7f1b4368dbec0e028a4e7676c82c25f0ebaeb09)) - -## [1.0.0-beta.1](https://github.com/hirosystems/token-metadata-api/compare/v0.7.0...v1.0.0-beta.1) (2024-08-21) - - -### ⚠ BREAKING CHANGES - -* use chainhook to listen for chain events instead of a direct stacks api connection (#200) - -### Bug Fixes - -* use prometheus port configured in ENV ([c769d29](https://github.com/hirosystems/token-metadata-api/commit/c769d2950d65448265caf2bf6bd78fce437358c0)) - - -### Code Refactoring - -* use chainhook to listen for chain events instead of a direct stacks api connection ([#200](https://github.com/hirosystems/token-metadata-api/issues/200)) ([2ddb2c7](https://github.com/hirosystems/token-metadata-api/commit/2ddb2c7db37419538bd4267c863aaf1f8a2ec5c1)), closes [#229](https://github.com/hirosystems/token-metadata-api/issues/229) [#232](https://github.com/hirosystems/token-metadata-api/issues/232) [#233](https://github.com/hirosystems/token-metadata-api/issues/233) [#234](https://github.com/hirosystems/token-metadata-api/issues/234) [#235](https://github.com/hirosystems/token-metadata-api/issues/235) [#236](https://github.com/hirosystems/token-metadata-api/issues/236) - -## [0.7.0](https://github.com/hirosystems/token-metadata-api/compare/v0.6.3...v0.7.0) (2024-05-13) - - -### Features - -* add admin rpc to reprocess token image cache ([#205](https://github.com/hirosystems/token-metadata-api/issues/205)) ([2fdcb33](https://github.com/hirosystems/token-metadata-api/commit/2fdcb33908062770da4e334810fd04bb378db66a)) -* update ts client with image thumbnails ([#206](https://github.com/hirosystems/token-metadata-api/issues/206)) ([c24cb56](https://github.com/hirosystems/token-metadata-api/commit/c24cb56b854123b252eb2e2616bb8589c5b36f0f)) -* upload token images to gcs ([#204](https://github.com/hirosystems/token-metadata-api/issues/204)) ([1cec219](https://github.com/hirosystems/token-metadata-api/commit/1cec2195a2b3df9e9c85f0152732594caa8c8c51)) - - -### Bug Fixes - -* get access token properly ([a6b98c5](https://github.com/hirosystems/token-metadata-api/commit/a6b98c5099a9de1d88e74eed66dece1c4c157422)) -* get gcs auth token dynamically for image cache ([#210](https://github.com/hirosystems/token-metadata-api/issues/210)) ([8434b22](https://github.com/hirosystems/token-metadata-api/commit/8434b229f6d38e6799bf84bd6f1eb4de106996bb)) -* image cache agent arg types ([5826628](https://github.com/hirosystems/token-metadata-api/commit/5826628a329225fbf697a092dc201fc74fb96d43)) -* improve image cache error handling ([#214](https://github.com/hirosystems/token-metadata-api/issues/214)) ([115a745](https://github.com/hirosystems/token-metadata-api/commit/115a745c268e7bb8115a488ca111e8b46cefed62)) -* reuse gcs token and validate image cache script errors ([#213](https://github.com/hirosystems/token-metadata-api/issues/213)) ([5e1af5c](https://github.com/hirosystems/token-metadata-api/commit/5e1af5c28cd0b1313f78a59b015669ceb07e5738)) - -## [0.7.0-beta.5](https://github.com/hirosystems/token-metadata-api/compare/v0.7.0-beta.4...v0.7.0-beta.5) (2024-05-13) - - -### Bug Fixes - -* improve image cache error handling ([#214](https://github.com/hirosystems/token-metadata-api/issues/214)) ([115a745](https://github.com/hirosystems/token-metadata-api/commit/115a745c268e7bb8115a488ca111e8b46cefed62)) - -## [0.7.0-beta.4](https://github.com/hirosystems/token-metadata-api/compare/v0.7.0-beta.3...v0.7.0-beta.4) (2024-05-08) - - -### Bug Fixes - -* get access token properly ([a6b98c5](https://github.com/hirosystems/token-metadata-api/commit/a6b98c5099a9de1d88e74eed66dece1c4c157422)) - -## [0.7.0-beta.3](https://github.com/hirosystems/token-metadata-api/compare/v0.7.0-beta.2...v0.7.0-beta.3) (2024-05-07) - - -### Bug Fixes - -* image cache agent arg types ([5826628](https://github.com/hirosystems/token-metadata-api/commit/5826628a329225fbf697a092dc201fc74fb96d43)) - -## [0.7.0-beta.2](https://github.com/hirosystems/token-metadata-api/compare/v0.7.0-beta.1...v0.7.0-beta.2) (2024-05-07) - - -### Bug Fixes - -* reuse gcs token and validate image cache script errors ([#213](https://github.com/hirosystems/token-metadata-api/issues/213)) ([5e1af5c](https://github.com/hirosystems/token-metadata-api/commit/5e1af5c28cd0b1313f78a59b015669ceb07e5738)) - -## [0.7.0-beta.1](https://github.com/hirosystems/token-metadata-api/compare/v0.6.3...v0.7.0-beta.1) (2024-05-07) - - -### Features - -* add admin rpc to reprocess token image cache ([#205](https://github.com/hirosystems/token-metadata-api/issues/205)) ([2fdcb33](https://github.com/hirosystems/token-metadata-api/commit/2fdcb33908062770da4e334810fd04bb378db66a)) -* update ts client with image thumbnails ([#206](https://github.com/hirosystems/token-metadata-api/issues/206)) ([c24cb56](https://github.com/hirosystems/token-metadata-api/commit/c24cb56b854123b252eb2e2616bb8589c5b36f0f)) -* upload token images to gcs ([#204](https://github.com/hirosystems/token-metadata-api/issues/204)) ([1cec219](https://github.com/hirosystems/token-metadata-api/commit/1cec2195a2b3df9e9c85f0152732594caa8c8c51)) - - -### Bug Fixes - -* get gcs auth token dynamically for image cache ([#210](https://github.com/hirosystems/token-metadata-api/issues/210)) ([8434b22](https://github.com/hirosystems/token-metadata-api/commit/8434b229f6d38e6799bf84bd6f1eb4de106996bb)) - -## [0.6.3](https://github.com/hirosystems/token-metadata-api/compare/v0.6.2...v0.6.3) (2024-05-07) - - -### Bug Fixes - -* retry `NoSuchContract` clarity errors ([#209](https://github.com/hirosystems/token-metadata-api/issues/209)) ([b7b6e84](https://github.com/hirosystems/token-metadata-api/commit/b7b6e84c5849fdfa0ce4d9520d0f8ae84f692910)) - -## [0.6.2](https://github.com/hirosystems/token-metadata-api/compare/v0.6.1...v0.6.2) (2024-05-07) - - -### Bug Fixes - -* handle missing image uris ([#207](https://github.com/hirosystems/token-metadata-api/issues/207)) ([a540ae0](https://github.com/hirosystems/token-metadata-api/commit/a540ae033c52161c5a5040304b8b992d31a4077c)) - -## [0.6.1](https://github.com/hirosystems/token-metadata-api/compare/v0.6.0...v0.6.1) (2024-02-27) - - -### Bug Fixes - -* accept FTs with incorrect return type for get-token-supply ([#197](https://github.com/hirosystems/token-metadata-api/issues/197)) ([116248c](https://github.com/hirosystems/token-metadata-api/commit/116248c7af09a6658b5542a4c900159a10c38b47)) - -## [0.6.0](https://github.com/hirosystems/token-metadata-api/compare/v0.5.0...v0.6.0) (2023-12-20) - - -### Features - -* make FT search on name and symbol case insensitive ([#187](https://github.com/hirosystems/token-metadata-api/issues/187)) ([5187e59](https://github.com/hirosystems/token-metadata-api/commit/5187e598e40a3b53400e9c1f63942257192222d5)) - - -### Bug Fixes - -* run tests in band ([#190](https://github.com/hirosystems/token-metadata-api/issues/190)) ([989575e](https://github.com/hirosystems/token-metadata-api/commit/989575ef8b53a513b77f5b0f509ed538591104f7)) -* semantic release ([#191](https://github.com/hirosystems/token-metadata-api/issues/191)) ([0a81fdb](https://github.com/hirosystems/token-metadata-api/commit/0a81fdb080d962d7390de374327aa2b3d59b28c8)) -* skip migrations during readonly mode ([#183](https://github.com/hirosystems/token-metadata-api/issues/183)) ([f658e0d](https://github.com/hirosystems/token-metadata-api/commit/f658e0d7e9fb4d52a63f936d5e2f55c3e11a3c8a)) - -## [0.5.0](https://github.com/hirosystems/token-metadata-api/compare/v0.4.0...v0.5.0) (2023-08-02) - - -### Features - -* add contract principal to ft index responses ([#180](https://github.com/hirosystems/token-metadata-api/issues/180)) ([57d0468](https://github.com/hirosystems/token-metadata-api/commit/57d04683ce7d72d15484d8cbf8ab36253261bf30)) - -## [0.4.0](https://github.com/hirosystems/token-metadata-api/compare/v0.3.1...v0.4.0) (2023-06-30) - - -### Features - -* add endpoint to list all FTs ([#167](https://github.com/hirosystems/token-metadata-api/issues/167)) ([af1e886](https://github.com/hirosystems/token-metadata-api/commit/af1e88661e344d407fcc96451ceb64cb224d2939)) - -## [0.3.1](https://github.com/hirosystems/token-metadata-api/compare/v0.3.0...v0.3.1) (2023-06-15) - - -### Bug Fixes - -* only warn when sip-019 contract is not found ([#162](https://github.com/hirosystems/token-metadata-api/issues/162)) ([55dcde1](https://github.com/hirosystems/token-metadata-api/commit/55dcde1a472f068cc2928125cd1e122d2d6d9c84)) -* run prometheus on port 9153 ([#165](https://github.com/hirosystems/token-metadata-api/issues/165)) ([2fa0d93](https://github.com/hirosystems/token-metadata-api/commit/2fa0d93c11764da7dff2a39b94606938ecafbcd7)) - -## [0.3.0](https://github.com/hirosystems/token-metadata-api/compare/v0.2.1...v0.3.0) (2023-04-03) - - -### Features - -* add `invalid` job status to mark invalid contracts or tokens ([#148](https://github.com/hirosystems/token-metadata-api/issues/148)) ([5d6ef41](https://github.com/hirosystems/token-metadata-api/commit/5d6ef419a594bbe01c54d2905707a4bc6a2a8e2f)) - - -### Bug Fixes - -* support FTs with missing metadata but correct token data ([#150](https://github.com/hirosystems/token-metadata-api/issues/150)) ([0a5558e](https://github.com/hirosystems/token-metadata-api/commit/0a5558e4c184aa6989b48361ae3ed3fc1b363ee7)) - -## [0.2.1](https://github.com/hirosystems/token-metadata-api/compare/v0.2.0...v0.2.1) (2023-03-17) - - -### Bug Fixes - -* do not retry incorrect clarity values ([#143](https://github.com/hirosystems/token-metadata-api/issues/143)) ([272064a](https://github.com/hirosystems/token-metadata-api/commit/272064aaf39b80cefe16418ac80d8d1c0ca08674)) - -## [0.2.0](https://github.com/hirosystems/token-metadata-api/compare/v0.1.1...v0.2.0) (2023-03-17) - - -### Features - -* add admin RPC interface ([#136](https://github.com/hirosystems/token-metadata-api/issues/136)) ([1f4b4aa](https://github.com/hirosystems/token-metadata-api/commit/1f4b4aabb37fe8c4805314f7e8eb268c6de749b6)) - -## [0.1.1](https://github.com/hirosystems/token-metadata-api/compare/v0.1.0...v0.1.1) (2023-03-14) - - -### Bug Fixes - -* return FT metadata in a backwards compatible way ([#130](https://github.com/hirosystems/token-metadata-api/issues/130)) ([3ca57a0](https://github.com/hirosystems/token-metadata-api/commit/3ca57a06bb14423a374cd7ceac368c1a6fbf0f57)) - -## [0.1.0](https://github.com/hirosystems/token-metadata-service/compare/v0.0.1...v0.1.0) (2023-02-22) - - -### Features - -* add server version to status endpoint and rendered docs ([#76](https://github.com/hirosystems/token-metadata-service/issues/76)) ([ba2f7de](https://github.com/hirosystems/token-metadata-service/commit/ba2f7de52996fe57c89298b98a7fd33e3db186f1)) -* enable run modes ([#116](https://github.com/hirosystems/token-metadata-service/issues/116)) ([c7a9c55](https://github.com/hirosystems/token-metadata-service/commit/c7a9c553217f5dcc9c1f30db3d8d29200504e930)) -* import sip-019 notifications during boot ([#81](https://github.com/hirosystems/token-metadata-service/issues/81)) ([6c28037](https://github.com/hirosystems/token-metadata-service/commit/6c2803703560fa42d5b15b25a83e877ad879f20b)) -* refresh dynamic metadata tokens periodically ([#64](https://github.com/hirosystems/token-metadata-service/issues/64)) ([e1c0882](https://github.com/hirosystems/token-metadata-service/commit/e1c08825e5148ee0c99a9d0e240bf386934a9c4b)) -* throttle requests to rate limited domains ([#97](https://github.com/hirosystems/token-metadata-service/issues/97)) ([5b75060](https://github.com/hirosystems/token-metadata-service/commit/5b75060157f9e8ec170176a8ba76c73eb7423cd3)) - - -### Bug Fixes - -* add `/metadata/v1` prefix to all routes ([#100](https://github.com/hirosystems/token-metadata-service/issues/100)) ([a11d4be](https://github.com/hirosystems/token-metadata-service/commit/a11d4be8abeb08ce192ea4e3f01d1da6db960733)) -* add cache-control, remove cache for error responses ([#114](https://github.com/hirosystems/token-metadata-service/issues/114)) ([e03caf8](https://github.com/hirosystems/token-metadata-service/commit/e03caf8e488bb0ad5911a40d68319391ef1cdca6)) -* contract log queries ([4bd2812](https://github.com/hirosystems/token-metadata-service/commit/4bd2812e135ea1ccb242b0b26f7a0ab62ea65048)) -* display cached image in metadata responses ([#104](https://github.com/hirosystems/token-metadata-service/issues/104)) ([156e9e2](https://github.com/hirosystems/token-metadata-service/commit/156e9e2e5b886cf1bd8fe7065cbf0f073e98b832)) -* dockerfile CMD path ([#91](https://github.com/hirosystems/token-metadata-service/issues/91)) ([de60556](https://github.com/hirosystems/token-metadata-service/commit/de605568415582f2b8c8451b02864827099d5b66)) -* enclose response etag in double quotes ([#113](https://github.com/hirosystems/token-metadata-service/issues/113)) ([2b77cfe](https://github.com/hirosystems/token-metadata-service/commit/2b77cfec24c1d1cba6857525fd9321628c7f3b9a)) -* etag cache calculation with url prefix ([#111](https://github.com/hirosystems/token-metadata-service/issues/111)) ([f872f93](https://github.com/hirosystems/token-metadata-service/commit/f872f9365e2d95ec051cfb4838881eb01e5c3df6)) -* follow redirects when fetching metadata ([#109](https://github.com/hirosystems/token-metadata-service/issues/109)) ([0ab2fbb](https://github.com/hirosystems/token-metadata-service/commit/0ab2fbb8eabf59b5ccaa4eef7d6c4b65d979f40e)) -* generate git info on docker build ([#93](https://github.com/hirosystems/token-metadata-service/issues/93)) ([9808b47](https://github.com/hirosystems/token-metadata-service/commit/9808b47d37d8a7ce2c720a96ddcd5e0db2e7ff5a)) -* handle pg disconnections and transaction management ([#92](https://github.com/hirosystems/token-metadata-service/issues/92)) ([201d813](https://github.com/hirosystems/token-metadata-service/commit/201d813241731bb634951e9534ad40f84842c6f9)) -* ignore invalid ssl certs for metadata fetch ([#107](https://github.com/hirosystems/token-metadata-service/issues/107)) ([46e184c](https://github.com/hirosystems/token-metadata-service/commit/46e184c9d773fc520ae95a9f93c2c35893b0e53b)) -* ignore ts type maps when migrating ([#95](https://github.com/hirosystems/token-metadata-service/issues/95)) ([b92b9d8](https://github.com/hirosystems/token-metadata-service/commit/b92b9d80f8ebe5b7e0d15b22a55900d389ee20b1)) -* improve SIGINT handling for queued jobs ([e16fcd5](https://github.com/hirosystems/token-metadata-service/commit/e16fcd5a5aba053620961538c6b3757cdc5523c5)) -* jsonb type interpretation on endpoints ([5985c80](https://github.com/hirosystems/token-metadata-service/commit/5985c8075c244c4414e5b73460a7267dc535a13f)) -* jsonb value insertions ([8dff8a6](https://github.com/hirosystems/token-metadata-service/commit/8dff8a601e78652961ab9f1a1c7b36e65a658c8c)) -* make importer wait for API height to catch up if it's behind ([#101](https://github.com/hirosystems/token-metadata-service/issues/101)) ([930cce3](https://github.com/hirosystems/token-metadata-service/commit/930cce3c6660bdc98181d5c5bced94c0bd46699c)) -* manage additional timeout errors on metadata fetch ([e658e1d](https://github.com/hirosystems/token-metadata-service/commit/e658e1ddd7d8580180e8baed8045b09be274e67c)) -* move from fetch to request to fix ENOBUFS ([9b26439](https://github.com/hirosystems/token-metadata-service/commit/9b2643948e9ec7b8d8fe102e47a062c26ff147db)) -* persist http agent for metadata fetches ([a30641a](https://github.com/hirosystems/token-metadata-service/commit/a30641ab14839978caef0feb78345fb92a39ece2)) -* retry 429 and gateway timeouts ([08cdce6](https://github.com/hirosystems/token-metadata-service/commit/08cdce64157800d28635ffc67c27ca3e08eaae2a)) -* sft_mint detection ([53673b2](https://github.com/hirosystems/token-metadata-service/commit/53673b22f6238b062ec17f34ba9faa4fcaa76e01)) -* shut down queue at the end of sequence ([e268c79](https://github.com/hirosystems/token-metadata-service/commit/e268c79177e6f0a52556a14174f1b57a828af3ee)) -* support JSON5 metadata strings ([#106](https://github.com/hirosystems/token-metadata-service/issues/106)) ([d19634f](https://github.com/hirosystems/token-metadata-service/commit/d19634f5dae83f769e14956edc842b382f08c763)) -* uintcv creation ([780b160](https://github.com/hirosystems/token-metadata-service/commit/780b1607497d089e454389c6180abb7a3cdb733d)) -* update_at jobs on status or retry change ([c16025f](https://github.com/hirosystems/token-metadata-service/commit/c16025fa1e86fa7d74c5ac24ab439b1d3a56084b)) - -## [0.1.0-beta.12](https://github.com/hirosystems/token-metadata-service/compare/v0.1.0-beta.11...v0.1.0-beta.12) (2023-02-21) - - -### Features - -* enable run modes ([#116](https://github.com/hirosystems/token-metadata-service/issues/116)) ([c7a9c55](https://github.com/hirosystems/token-metadata-service/commit/c7a9c553217f5dcc9c1f30db3d8d29200504e930)) - -## [0.1.0-beta.11](https://github.com/hirosystems/token-metadata-service/compare/v0.1.0-beta.10...v0.1.0-beta.11) (2023-02-09) - - -### Bug Fixes - -* add cache-control, remove cache for error responses ([#114](https://github.com/hirosystems/token-metadata-service/issues/114)) ([e03caf8](https://github.com/hirosystems/token-metadata-service/commit/e03caf8e488bb0ad5911a40d68319391ef1cdca6)) - -## [0.1.0-beta.10](https://github.com/hirosystems/token-metadata-service/compare/v0.1.0-beta.9...v0.1.0-beta.10) (2023-02-09) - - -### Bug Fixes - -* enclose response etag in double quotes ([#113](https://github.com/hirosystems/token-metadata-service/issues/113)) ([2b77cfe](https://github.com/hirosystems/token-metadata-service/commit/2b77cfec24c1d1cba6857525fd9321628c7f3b9a)) - -## [0.1.0-beta.9](https://github.com/hirosystems/token-metadata-service/compare/v0.1.0-beta.8...v0.1.0-beta.9) (2023-02-09) - - -### Bug Fixes - -* etag cache calculation with url prefix ([#111](https://github.com/hirosystems/token-metadata-service/issues/111)) ([f872f93](https://github.com/hirosystems/token-metadata-service/commit/f872f9365e2d95ec051cfb4838881eb01e5c3df6)) - -## [0.1.0-beta.8](https://github.com/hirosystems/token-metadata-service/compare/v0.1.0-beta.7...v0.1.0-beta.8) (2023-02-09) - - -### Bug Fixes - -* display cached image in metadata responses ([#104](https://github.com/hirosystems/token-metadata-service/issues/104)) ([156e9e2](https://github.com/hirosystems/token-metadata-service/commit/156e9e2e5b886cf1bd8fe7065cbf0f073e98b832)) -* follow redirects when fetching metadata ([#109](https://github.com/hirosystems/token-metadata-service/issues/109)) ([0ab2fbb](https://github.com/hirosystems/token-metadata-service/commit/0ab2fbb8eabf59b5ccaa4eef7d6c4b65d979f40e)) -* ignore invalid ssl certs for metadata fetch ([#107](https://github.com/hirosystems/token-metadata-service/issues/107)) ([46e184c](https://github.com/hirosystems/token-metadata-service/commit/46e184c9d773fc520ae95a9f93c2c35893b0e53b)) -* make importer wait for API height to catch up if it's behind ([#101](https://github.com/hirosystems/token-metadata-service/issues/101)) ([930cce3](https://github.com/hirosystems/token-metadata-service/commit/930cce3c6660bdc98181d5c5bced94c0bd46699c)) -* support JSON5 metadata strings ([#106](https://github.com/hirosystems/token-metadata-service/issues/106)) ([d19634f](https://github.com/hirosystems/token-metadata-service/commit/d19634f5dae83f769e14956edc842b382f08c763)) - -## [0.1.0-beta.7](https://github.com/hirosystems/token-metadata-service/compare/v0.1.0-beta.6...v0.1.0-beta.7) (2023-02-07) - - -### Bug Fixes - -* add `/metadata/v1` prefix to all routes ([#100](https://github.com/hirosystems/token-metadata-service/issues/100)) ([a11d4be](https://github.com/hirosystems/token-metadata-service/commit/a11d4be8abeb08ce192ea4e3f01d1da6db960733)) - -## [0.1.0-beta.6](https://github.com/hirosystems/token-metadata-service/compare/v0.1.0-beta.5...v0.1.0-beta.6) (2023-02-06) - - -### Features - -* throttle requests to rate limited domains ([#97](https://github.com/hirosystems/token-metadata-service/issues/97)) ([5b75060](https://github.com/hirosystems/token-metadata-service/commit/5b75060157f9e8ec170176a8ba76c73eb7423cd3)) - -## [0.1.0-beta.5](https://github.com/hirosystems/token-metadata-service/compare/v0.1.0-beta.4...v0.1.0-beta.5) (2023-02-02) - - -### Bug Fixes - -* handle pg disconnections and transaction management ([#92](https://github.com/hirosystems/token-metadata-service/issues/92)) ([201d813](https://github.com/hirosystems/token-metadata-service/commit/201d813241731bb634951e9534ad40f84842c6f9)) - -## [0.1.0-beta.4](https://github.com/hirosystems/token-metadata-service/compare/v0.1.0-beta.3...v0.1.0-beta.4) (2023-02-01) - - -### Bug Fixes - -* ignore ts type maps when migrating ([#95](https://github.com/hirosystems/token-metadata-service/issues/95)) ([b92b9d8](https://github.com/hirosystems/token-metadata-service/commit/b92b9d80f8ebe5b7e0d15b22a55900d389ee20b1)) - -## [0.1.0-beta.3](https://github.com/hirosystems/token-metadata-service/compare/v0.1.0-beta.2...v0.1.0-beta.3) (2023-02-01) - - -### Bug Fixes - -* generate git info on docker build ([#93](https://github.com/hirosystems/token-metadata-service/issues/93)) ([9808b47](https://github.com/hirosystems/token-metadata-service/commit/9808b47d37d8a7ce2c720a96ddcd5e0db2e7ff5a)) - -## [0.1.0-beta.2](https://github.com/hirosystems/token-metadata-service/compare/v0.1.0-beta.1...v0.1.0-beta.2) (2023-02-01) - - -### Bug Fixes - -* dockerfile CMD path ([#91](https://github.com/hirosystems/token-metadata-service/issues/91)) ([de60556](https://github.com/hirosystems/token-metadata-service/commit/de605568415582f2b8c8451b02864827099d5b66)) - -## [0.1.0-beta.1](https://github.com/hirosystems/token-metadata-service/compare/v0.0.1...v0.1.0-beta.1) (2023-01-26) - - -### Features - -* add server version to status endpoint and rendered docs ([#76](https://github.com/hirosystems/token-metadata-service/issues/76)) ([ba2f7de](https://github.com/hirosystems/token-metadata-service/commit/ba2f7de52996fe57c89298b98a7fd33e3db186f1)) -* import sip-019 notifications during boot ([#81](https://github.com/hirosystems/token-metadata-service/issues/81)) ([6c28037](https://github.com/hirosystems/token-metadata-service/commit/6c2803703560fa42d5b15b25a83e877ad879f20b)) -* refresh dynamic metadata tokens periodically ([#64](https://github.com/hirosystems/token-metadata-service/issues/64)) ([e1c0882](https://github.com/hirosystems/token-metadata-service/commit/e1c08825e5148ee0c99a9d0e240bf386934a9c4b)) - - -### Bug Fixes - -* contract log queries ([4bd2812](https://github.com/hirosystems/token-metadata-service/commit/4bd2812e135ea1ccb242b0b26f7a0ab62ea65048)) -* improve SIGINT handling for queued jobs ([e16fcd5](https://github.com/hirosystems/token-metadata-service/commit/e16fcd5a5aba053620961538c6b3757cdc5523c5)) -* jsonb type interpretation on endpoints ([5985c80](https://github.com/hirosystems/token-metadata-service/commit/5985c8075c244c4414e5b73460a7267dc535a13f)) -* jsonb value insertions ([8dff8a6](https://github.com/hirosystems/token-metadata-service/commit/8dff8a601e78652961ab9f1a1c7b36e65a658c8c)) -* manage additional timeout errors on metadata fetch ([e658e1d](https://github.com/hirosystems/token-metadata-service/commit/e658e1ddd7d8580180e8baed8045b09be274e67c)) -* move from fetch to request to fix ENOBUFS ([9b26439](https://github.com/hirosystems/token-metadata-service/commit/9b2643948e9ec7b8d8fe102e47a062c26ff147db)) -* persist http agent for metadata fetches ([a30641a](https://github.com/hirosystems/token-metadata-service/commit/a30641ab14839978caef0feb78345fb92a39ece2)) -* retry 429 and gateway timeouts ([08cdce6](https://github.com/hirosystems/token-metadata-service/commit/08cdce64157800d28635ffc67c27ca3e08eaae2a)) -* sft_mint detection ([53673b2](https://github.com/hirosystems/token-metadata-service/commit/53673b22f6238b062ec17f34ba9faa4fcaa76e01)) -* shut down queue at the end of sequence ([e268c79](https://github.com/hirosystems/token-metadata-service/commit/e268c79177e6f0a52556a14174f1b57a828af3ee)) -* uintcv creation ([780b160](https://github.com/hirosystems/token-metadata-service/commit/780b1607497d089e454389c6180abb7a3cdb733d)) -* update_at jobs on status or retry change ([c16025f](https://github.com/hirosystems/token-metadata-service/commit/c16025fa1e86fa7d74c5ac24ab439b1d3a56084b)) diff --git a/eslint.config.cjs b/eslint.config.cjs deleted file mode 100644 index b09bb89..0000000 --- a/eslint.config.cjs +++ /dev/null @@ -1,52 +0,0 @@ -const { FlatCompat } = require('@eslint/eslintrc'); - -const compat = new FlatCompat({ - baseDirectory: __dirname, -}); - -module.exports = [ - ...compat.config({ - extends: ['@stacks/eslint-config', 'prettier'], - parser: '@typescript-eslint/parser', - parserOptions: { - tsconfigRootDir: __dirname, - project: './tsconfig.json', - ecmaVersion: 2020, - sourceType: 'module', - }, - ignorePatterns: [ - '*.config.js', - 'config/*', - '*.mjs', - 'tests/**/*.js', - 'client/*', - 'coverage/*', - 'dist/*', - 'node_modules/', - ], - plugins: ['@typescript-eslint', 'eslint-plugin-tsdoc', 'prettier'], - rules: { - 'prettier/prettier': 'error', - '@typescript-eslint/no-inferrable-types': 'off', - '@typescript-eslint/camelcase': 'off', - '@typescript-eslint/no-empty-function': 'off', - '@typescript-eslint/no-use-before-define': ['error', 'nofunc'], - '@typescript-eslint/no-floating-promises': ['error', { ignoreVoid: true }], - 'no-warning-comments': 'warn', - 'tsdoc/syntax': 'error', - // TODO: Remove this when `any` abi type is fixed. - '@typescript-eslint/no-unsafe-assignment': 'off', - '@typescript-eslint/no-unsafe-member-access': 'off', - '@typescript-eslint/no-unsafe-call': 'off', - '@typescript-eslint/restrict-template-expressions': 'off', - }, - }), - { - files: ['tests/**/*.ts'], - rules: { - '@typescript-eslint/no-floating-promises': 'off', - '@typescript-eslint/no-unsafe-argument': 'off', - '@typescript-eslint/no-unnecessary-type-assertion': 'off', - }, - }, -]; diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..699a43f --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,52 @@ +import stacksConfig from '@stacks/eslint-config'; +import tsdoc from 'eslint-plugin-tsdoc'; + +export default [ + { + ignores: [ + 'lib/**', + 'client/**', + 'utils/**', + 'migrations/**', + 'tests/**', + 'stacks-blockchain/**', + ], + }, + ...stacksConfig, + { + files: ['**/*.ts', '**/*.tsx'], + languageOptions: { + parserOptions: { + tsconfigRootDir: import.meta.dirname, + project: './tsconfig.json', + }, + }, + plugins: { tsdoc }, + rules: { + '@typescript-eslint/no-inferrable-types': 'off', + '@typescript-eslint/no-empty-function': 'off', + '@typescript-eslint/no-use-before-define': ['error', 'nofunc'], + '@typescript-eslint/no-floating-promises': ['error', { ignoreVoid: true }], + 'no-warning-comments': 'warn', + 'tsdoc/syntax': 'error', + '@typescript-eslint/no-unsafe-assignment': 'off', + '@typescript-eslint/no-unsafe-member-access': 'off', + '@typescript-eslint/no-unsafe-call': 'off', + '@typescript-eslint/restrict-template-expressions': 'off', + '@typescript-eslint/explicit-module-boundary-types': 'off', + '@typescript-eslint/restrict-plus-operands': 'off', + '@typescript-eslint/no-misused-promises': 'off', + '@typescript-eslint/no-unsafe-argument': 'off', + '@typescript-eslint/no-unused-vars': [ + 'error', + { + args: 'all', + argsIgnorePattern: '^_', + varsIgnorePattern: '^_', + caughtErrorsIgnorePattern: '^_', + destructuredArrayIgnorePattern: '^_', + }, + ], + }, + }, +]; diff --git a/package-lock.json b/package-lock.json index b6f712d..07a233e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { - "name": "@hirosystems/token-metadata-api", + "name": "@stx-labs/token-metadata-api", "version": "2.2.1", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "@hirosystems/token-metadata-api", + "name": "@stx-labs/token-metadata-api", "version": "2.2.1", "license": "GPL-3.0", "dependencies": { @@ -43,7 +43,6 @@ "eslint-plugin-import": "^2.32.0", "eslint-plugin-prettier": "^5.5.5", "eslint-plugin-tsdoc": "^0.5.2", - "husky": "^9.1.7", "nock": "^14.0.11", "openapi-typescript": "^7.13.0", "prettier": "^3.8.1", @@ -6889,22 +6888,6 @@ "node": ">= 14" } }, - "node_modules/husky": { - "version": "9.1.7", - "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", - "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", - "dev": true, - "license": "MIT", - "bin": { - "husky": "bin.js" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/typicode" - } - }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", diff --git a/package.json b/package.json index 3111d55..fe3efef 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,6 @@ "eslint-plugin-import": "^2.32.0", "eslint-plugin-prettier": "^5.5.5", "eslint-plugin-tsdoc": "^0.5.2", - "husky": "^9.1.7", "nock": "^14.0.11", "openapi-typescript": "^7.13.0", "prettier": "^3.8.1", From e177349a8b47367b9f9bd853e1ba0dc0fdfb647c Mon Sep 17 00:00:00 2001 From: Rafa Cardenas <253999660+rafa-stacks@users.noreply.github.com> Date: Thu, 26 Mar 2026 15:56:04 -0600 Subject: [PATCH 07/12] tests run --- .vscode/launch.json | 5 +- package.json | 11 +- .../stacks-core-block-processor.ts | 15 +- .../queue/job/process-token-job.ts | 8 +- .../queue/job/update-token-supply-job.ts | 10 +- .../stacks-node/stacks-node-rpc-client.ts | 34 +-- src/token-processor/util/sip-validation.ts | 42 ++- tests/admin/admin-rpc.test.ts | 3 +- tests/api/cache.test.ts | 4 +- tests/api/ft.test.ts | 4 +- tests/api/nft.test.ts | 4 +- tests/api/search.test.ts | 4 +- tests/api/sft.test.ts | 4 +- tests/api/status.test.ts | 5 +- tests/docker-container.ts | 259 ++++++++++++++++++ tests/helpers.ts | 21 +- tests/setup-env.ts | 10 - tests/setup.ts | 231 ++-------------- tests/stacks-core/block-processor.test.ts | 3 +- tests/stacks-core/ft-events.test.ts | 4 +- tests/stacks-core/nft-events.test.ts | 4 +- tests/stacks-core/notifications.test.ts | 4 +- tests/stacks-core/reorg.test.ts | 4 +- tests/stacks-core/sft-events.test.ts | 4 +- tests/stacks-core/smart-contracts.test.ts | 5 +- tests/token-queue/job-queue.test.ts | 4 +- tests/token-queue/job.test.ts | 4 +- .../process-smart-contract-job.test.ts | 4 +- tests/token-queue/process-token-job.test.ts | 4 +- .../update-token-supply-job.test.ts | 4 +- tests/tsconfig.json | 7 + tsconfig.json | 126 +-------- 32 files changed, 418 insertions(+), 437 deletions(-) create mode 100644 tests/docker-container.ts delete mode 100644 tests/setup-env.ts create mode 100644 tests/tsconfig.json diff --git a/.vscode/launch.json b/.vscode/launch.json index 9c8c682..89c3a0c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -89,16 +89,13 @@ "args": [ "--import", "tsx", - "--import", - "${workspaceFolder}/tests/setup-env.ts", "--test", + "--test-global-setup=./tests/setup.ts", "--test-concurrency=1", "${workspaceFolder}/tests/admin/*.test.ts" ], "outputCapture": "std", "console": "integratedTerminal", - "preLaunchTask": "npm: testenv:run", - "postDebugTask": "npm: testenv:stop", "env": { "NODE_ENV": "test" }, diff --git a/package.json b/package.json index fe3efef..9df1460 100644 --- a/package.json +++ b/package.json @@ -18,13 +18,10 @@ "build:client": "npm run generate:git-info && npm run generate:openapi && npm run generate:client", "start": "node ./dist/src/index.js", "start-ts": "node --import tsx ./src/index.ts", - "test": "npm run testenv:run && NODE_ENV=test node --import tsx --import ./tests/setup-env.ts --test --test-concurrency=1; EXIT=$?; npm run testenv:stop; exit $EXIT", - "test:admin": "npm run test -- ./tests/admin/*.test.ts", - "test:api": "npm run test -- ./tests/api/*.test.ts", - "test:stacks-core": "npm run test -- ./tests/stacks-core/*.test.ts", - "test:token-queue": "npm run test -- ./tests/token-queue/*.test.ts", - "testenv:run": "node --import tsx ./tests/setup.ts up", - "testenv:stop": "node --import tsx ./tests/setup.ts down", + "test:admin": "NODE_ENV=test node --import tsx --test --test-global-setup=./tests/setup.ts --test-concurrency=1 ./tests/admin/*.test.ts", + "test:api": "NODE_ENV=test node --import tsx --test --test-global-setup=./tests/setup.ts --test-concurrency=1 ./tests/api/*.test.ts", + "test:stacks-core": "NODE_ENV=test node --import tsx --test --test-global-setup=./tests/setup.ts --test-concurrency=1 ./tests/stacks-core/*.test.ts", + "test:token-queue": "NODE_ENV=test node --import tsx --test --test-global-setup=./tests/setup.ts --test-concurrency=1 ./tests/token-queue/*.test.ts", "migrate": "node --import tsx node_modules/.bin/node-pg-migrate -j ts", "lint:eslint": "eslint . --ext .js,.jsx,.ts,.tsx -f unix", "lint:prettier": "prettier --check src/**/*.ts tests/**/*.ts migrations/**/*.ts", diff --git a/src/stacks-core/stacks-core-block-processor.ts b/src/stacks-core/stacks-core-block-processor.ts index 6e6dd99..66beeca 100644 --- a/src/stacks-core/stacks-core-block-processor.ts +++ b/src/stacks-core/stacks-core-block-processor.ts @@ -8,12 +8,7 @@ import { SmartContractDeployment, TokenMetadataUpdateNotification, } from '../token-processor/util/sip-validation.js'; -import { - ClarityTypeID, - decodeClarityValue, - DecodedTxResult, - decodeTransaction, -} from '@stacks/codec'; +import codec from '@stacks/codec'; import { StacksCorePgStore } from '../pg/stacks-core-pg-store.js'; import { logger, stopwatch } from '@stacks/api-toolkit'; import { @@ -29,7 +24,7 @@ import { export type DecodedStacksTransaction = { tx: NewBlockTransaction; - decoded: DecodedTxResult; + decoded: codec.DecodedTxResult; events: NewBlockEvent[]; }; @@ -58,7 +53,7 @@ export function decodeStacksCoreBlock(block: NewBlockMessage): DecodedStacksBloc if (tx.burnchain_op) continue; transactions.push({ tx, - decoded: decodeTransaction(tx.raw_tx.substring(2)), + decoded: codec.decodeTransaction(tx.raw_tx.substring(2)), events: (events.get(tx.txid) || []).sort((a, b) => a.event_index - b.event_index), }); } @@ -233,8 +228,8 @@ export class StacksCoreBlockProcessor { event: NewBlockNftMintEvent, nftMints: NftMintEvent[] ) { - const value = decodeClarityValue(event.nft_mint_event.raw_value); - if (value.type_id === ClarityTypeID.UInt) { + const value = codec.decodeClarityValue(event.nft_mint_event.raw_value); + if (value.type_id === codec.ClarityTypeID.UInt) { const principal = event.nft_mint_event.asset_identifier.split('::')[0]; const tokenId = BigInt(value.value); nftMints.push({ diff --git a/src/token-processor/queue/job/process-token-job.ts b/src/token-processor/queue/job/process-token-job.ts index b851fb6..533119c 100644 --- a/src/token-processor/queue/job/process-token-job.ts +++ b/src/token-processor/queue/job/process-token-job.ts @@ -1,5 +1,5 @@ import { cvToHex, uintCV } from '@stacks/transactions'; -import { ClarityValueUInt, decodeClarityValueToRepr } from '@stacks/codec'; +import codec from '@stacks/codec'; import { DbMetadataLocaleInsertBundle, DbProcessedTokenUpdateBundle, @@ -216,13 +216,13 @@ export class ProcessTokenJob extends Job { } } - private uIntCv(n: bigint): ClarityValueUInt { + private uIntCv(n: bigint): codec.ClarityValueUInt { const cv = uintCV(n); const hex = cvToHex(cv); return { value: n.toString(), hex: hex, - repr: decodeClarityValueToRepr(hex), - } as ClarityValueUInt; + repr: codec.decodeClarityValueToRepr(hex), + } as codec.ClarityValueUInt; } } diff --git a/src/token-processor/queue/job/update-token-supply-job.ts b/src/token-processor/queue/job/update-token-supply-job.ts index 7e8a512..2b1bb38 100644 --- a/src/token-processor/queue/job/update-token-supply-job.ts +++ b/src/token-processor/queue/job/update-token-supply-job.ts @@ -1,5 +1,5 @@ import { cvToHex, uintCV } from '@stacks/transactions'; -import { ClarityValueUInt, decodeClarityValueToRepr } from '@stacks/codec'; +import codec from '@stacks/codec'; import { DbSmartContract, DbToken, DbTokenType } from '../../../pg/types.js'; import { StacksNodeRpcClient } from '../../stacks-node/stacks-node-rpc-client.js'; import { SmartContractClarityError } from '../../util/errors.js'; @@ -80,7 +80,7 @@ export class UpdateTokenSupplyJob extends Job { private async updateTokenSupply( client: StacksNodeRpcClient, token: DbToken, - arg: ClarityValueUInt[] = [] + arg: codec.ClarityValueUInt[] = [] ) { let fTotalSupply: PgNumeric | undefined; try { @@ -100,13 +100,13 @@ export class UpdateTokenSupplyJob extends Job { await this.db.core.updateTokenSupply({ id: token.id, total_supply: fTotalSupply }); } - private uIntCv(n: bigint): ClarityValueUInt { + private uIntCv(n: bigint): codec.ClarityValueUInt { const cv = uintCV(n); const hex = cvToHex(cv); return { value: n.toString(), hex: hex, - repr: decodeClarityValueToRepr(hex), - } as ClarityValueUInt; + repr: codec.decodeClarityValueToRepr(hex), + } as codec.ClarityValueUInt; } } diff --git a/src/token-processor/stacks-node/stacks-node-rpc-client.ts b/src/token-processor/stacks-node/stacks-node-rpc-client.ts index 5c45b81..939df5d 100644 --- a/src/token-processor/stacks-node/stacks-node-rpc-client.ts +++ b/src/token-processor/stacks-node/stacks-node-rpc-client.ts @@ -1,4 +1,4 @@ -import { ClarityTypeID, ClarityValue, ClarityValueUInt, decodeClarityValue } from '@stacks/codec'; +import codec from '@stacks/codec'; import { request, errors } from 'undici'; import { ENV } from '../../env.js'; import { RetryableJobError } from '../queue/errors.js'; @@ -55,7 +55,7 @@ export class StacksNodeRpcClient { async readStringFromContract( functionName: string, - functionArgs: ClarityValue[] = [] + functionArgs: codec.ClarityValue[] = [] ): Promise { const clarityValue = await this.makeReadOnlyContractCall(functionName, functionArgs); return this.checkAndParseString(clarityValue); @@ -63,7 +63,7 @@ export class StacksNodeRpcClient { async readUIntFromContract( functionName: string, - functionArgs: ClarityValue[] = [] + functionArgs: codec.ClarityValue[] = [] ): Promise { const clarityValue = await this.makeReadOnlyContractCall(functionName, functionArgs); const uintVal = this.checkAndParseUintCV(clarityValue); @@ -101,7 +101,7 @@ export class StacksNodeRpcClient { private async sendReadOnlyContractCall( functionName: string, - functionArgs: ClarityValue[] + functionArgs: codec.ClarityValue[] ): Promise { const body = { sender: this.senderAddress, @@ -135,8 +135,8 @@ export class StacksNodeRpcClient { private async makeReadOnlyContractCall( functionName: string, - functionArgs: ClarityValue[] - ): Promise { + functionArgs: codec.ClarityValue[] + ): Promise { const result = await this.sendReadOnlyContractCall(functionName, functionArgs); if (!result.okay) { if (result.cause.startsWith('Runtime')) { @@ -150,23 +150,23 @@ export class StacksNodeRpcClient { } throw new SmartContractClarityError(`Read-only error ${functionName}: ${result.cause}`); } - return decodeClarityValue(result.result); + return codec.decodeClarityValue(result.result); } - private unwrapClarityType(clarityValue: ClarityValue): ClarityValue { - let unwrappedClarityValue: ClarityValue = clarityValue; + private unwrapClarityType(clarityValue: codec.ClarityValue): codec.ClarityValue { + let unwrappedClarityValue: codec.ClarityValue = clarityValue; while ( - unwrappedClarityValue.type_id === ClarityTypeID.ResponseOk || - unwrappedClarityValue.type_id === ClarityTypeID.OptionalSome + unwrappedClarityValue.type_id === codec.ClarityTypeID.ResponseOk || + unwrappedClarityValue.type_id === codec.ClarityTypeID.OptionalSome ) { unwrappedClarityValue = unwrappedClarityValue.value; } return unwrappedClarityValue; } - private checkAndParseUintCV(responseCV: ClarityValue): ClarityValueUInt { + private checkAndParseUintCV(responseCV: codec.ClarityValue): codec.ClarityValueUInt { const unwrappedClarityValue = this.unwrapClarityType(responseCV); - if (unwrappedClarityValue.type_id === ClarityTypeID.UInt) { + if (unwrappedClarityValue.type_id === codec.ClarityTypeID.UInt) { return unwrappedClarityValue; } throw new SmartContractClarityError( @@ -174,14 +174,14 @@ export class StacksNodeRpcClient { ); } - private checkAndParseString(responseCV: ClarityValue): string | undefined { + private checkAndParseString(responseCV: codec.ClarityValue): string | undefined { const unwrappedClarityValue = this.unwrapClarityType(responseCV); if ( - unwrappedClarityValue.type_id === ClarityTypeID.StringAscii || - unwrappedClarityValue.type_id === ClarityTypeID.StringUtf8 + unwrappedClarityValue.type_id === codec.ClarityTypeID.StringAscii || + unwrappedClarityValue.type_id === codec.ClarityTypeID.StringUtf8 ) { return unwrappedClarityValue.data; - } else if (unwrappedClarityValue.type_id === ClarityTypeID.OptionalNone) { + } else if (unwrappedClarityValue.type_id === codec.ClarityTypeID.OptionalNone) { return undefined; } throw new SmartContractClarityError( diff --git a/src/token-processor/util/sip-validation.ts b/src/token-processor/util/sip-validation.ts index 8b4edab..9032601 100644 --- a/src/token-processor/util/sip-validation.ts +++ b/src/token-processor/util/sip-validation.ts @@ -1,13 +1,5 @@ import { ClarityAbiFunction, ClarityAbi } from '@stacks/transactions'; -import { - ClarityTypeID, - ClarityValue, - ClarityValueTuple, - ClarityValueList, - ClarityValueUInt, - decodeClarityValue, - TxPayloadTypeID, -} from '@stacks/codec'; +import codec from '@stacks/codec'; import { DbSipNumber } from '../../pg/types.js'; import { DecodedStacksTransaction } from '../../stacks-core/stacks-core-block-processor.js'; import { NewBlockContractEvent } from '@stacks/node-publisher-client'; @@ -255,18 +247,18 @@ function findFunction(fun: ClarityAbiFunction, functionList: ClarityAbiFunction[ return found !== undefined; } -function stringFromValue(value: ClarityValue): string { +function stringFromValue(value: codec.ClarityValue): string { switch (value.type_id) { - case ClarityTypeID.Buffer: + case codec.ClarityTypeID.Buffer: const parts = value.buffer.substring(2).match(/.{1,2}/g) ?? []; const arr = Uint8Array.from(parts.map(byte => parseInt(byte, 16))); return Buffer.from(arr).toString('utf8'); - case ClarityTypeID.StringAscii: - case ClarityTypeID.StringUtf8: + case codec.ClarityTypeID.StringAscii: + case codec.ClarityTypeID.StringUtf8: return value.data; - case ClarityTypeID.PrincipalContract: + case codec.ClarityTypeID.PrincipalContract: return `${value.address}.${value.contract_name}`; - case ClarityTypeID.PrincipalStandard: + case codec.ClarityTypeID.PrincipalStandard: return value.address; default: throw new Error('Invalid clarity value'); @@ -331,12 +323,12 @@ export function getContractLogMetadataUpdateNotification( const sender = transaction.decoded.auth.origin_condition.signer.address; try { // Validate that we have the correct SIP-019 payload structure. - const value = decodeClarityValue(log.raw_value); + const value = codec.decodeClarityValue(log.raw_value); const notification = stringFromValue(value.data.notification); if (notification !== 'token-metadata-update') { return; } - const payload = value.data.payload as ClarityValueTuple; + const payload = value.data.payload as codec.ClarityValueTuple; const contractId = stringFromValue(payload.data['contract-id']); const tokenClass = stringFromValue(payload.data['token-class']); if (!['ft', 'nft'].includes(tokenClass)) { @@ -356,7 +348,9 @@ export function getContractLogMetadataUpdateNotification( // Only NFT notifications provide token ids. let tokenIds: bigint[] | undefined; if (tokenClass === 'nft') { - const tokenIdList = payload.data['token-ids'] as ClarityValueList; + const tokenIdList = payload.data[ + 'token-ids' + ] as codec.ClarityValueList; if (tokenIdList) { tokenIds = tokenIdList.list.map(i => BigInt(i.value)); } @@ -373,7 +367,7 @@ export function getContractLogMetadataUpdateNotification( let ttl: bigint | undefined; const ttlValue = payload.data['ttl']; - if (ttlValue && ttlValue.type_id === ClarityTypeID.UInt) { + if (ttlValue && ttlValue.type_id === codec.ClarityTypeID.UInt) { ttl = BigInt(ttlValue.value); } @@ -399,14 +393,14 @@ export function getContractLogSftMintEvent( const log = event.contract_event; try { // Validate that we have the correct SIP-013 `sft_mint` payload structure. - const value = decodeClarityValue(log.raw_value); + const value = codec.decodeClarityValue(log.raw_value); const type = stringFromValue(value.data.type); if (type !== 'sft_mint') { return; } const recipient = stringFromValue(value.data['recipient']); - const tokenId = (value.data['token-id'] as ClarityValueUInt).value; - const amount = (value.data['amount'] as ClarityValueUInt).value; + const tokenId = (value.data['token-id'] as codec.ClarityValueUInt).value; + const amount = (value.data['amount'] as codec.ClarityValueUInt).value; return { tx_id: transaction.tx.txid, @@ -435,8 +429,8 @@ export function getSmartContractDeployment( const sender = transaction.decoded.auth.origin_condition.signer.address; const payload = transaction.decoded.payload; if ( - payload.type_id === TxPayloadTypeID.SmartContract || - payload.type_id === TxPayloadTypeID.VersionedSmartContract + payload.type_id === codec.TxPayloadTypeID.SmartContract || + payload.type_id === codec.TxPayloadTypeID.VersionedSmartContract ) { const principal = `${sender}.${payload.contract_name}`; return { diff --git a/tests/admin/admin-rpc.test.ts b/tests/admin/admin-rpc.test.ts index 93461bb..466597a 100644 --- a/tests/admin/admin-rpc.test.ts +++ b/tests/admin/admin-rpc.test.ts @@ -8,6 +8,7 @@ import { DbJobStatus, DbSipNumber } from '../../src/pg/types.js'; import { insertAndEnqueueTestContractWithTokens, markAllJobsAsDone, + setupEnv, SIP_010_ABI, TestFastifyServer, } from '../helpers.js'; @@ -20,7 +21,7 @@ describe('Admin RPC', () => { let jobQueue: JobQueue; beforeEach(async () => { - ENV.PGDATABASE = 'postgres'; + setupEnv(); db = await PgStore.connect({ skipMigrations: true }); jobQueue = new JobQueue({ db, network: 'mainnet' }); fastify = await buildAdminRpcServer({ db, jobQueue }); diff --git a/tests/api/cache.test.ts b/tests/api/cache.test.ts index 945b933..f69aef8 100644 --- a/tests/api/cache.test.ts +++ b/tests/api/cache.test.ts @@ -1,11 +1,11 @@ import { strict as assert } from 'node:assert'; import { cycleMigrations } from '@stacks/api-toolkit'; -import { ENV } from '../../src/env.js'; import { MIGRATIONS_DIR, PgStore } from '../../src/pg/pg-store.js'; import { DbSipNumber } from '../../src/pg/types.js'; import { TestFastifyServer, insertAndEnqueueTestContractWithTokens, + setupEnv, startTestApiServer, } from '../helpers.js'; import { afterEach, beforeEach, describe, test } from 'node:test'; @@ -15,7 +15,7 @@ describe('ETag cache', () => { let fastify: TestFastifyServer; beforeEach(async () => { - ENV.PGDATABASE = 'postgres'; + setupEnv(); db = await PgStore.connect({ skipMigrations: true }); fastify = await startTestApiServer(db); await cycleMigrations(MIGRATIONS_DIR); diff --git a/tests/api/ft.test.ts b/tests/api/ft.test.ts index f537054..a759688 100644 --- a/tests/api/ft.test.ts +++ b/tests/api/ft.test.ts @@ -1,11 +1,11 @@ import { strict as assert } from 'node:assert'; import { cycleMigrations } from '@stacks/api-toolkit'; -import { ENV } from '../../src/env.js'; import { MIGRATIONS_DIR, PgStore } from '../../src/pg/pg-store.js'; import { DbFungibleTokenMetadataItem, DbSipNumber } from '../../src/pg/types.js'; import { insertAndEnqueueTestContract, insertAndEnqueueTestContractWithTokens, + setupEnv, startTestApiServer, TestFastifyServer, } from '../helpers.js'; @@ -16,7 +16,7 @@ describe('FT routes', () => { let fastify: TestFastifyServer; beforeEach(async () => { - ENV.PGDATABASE = 'postgres'; + setupEnv(); db = await PgStore.connect({ skipMigrations: true }); fastify = await startTestApiServer(db); await cycleMigrations(MIGRATIONS_DIR); diff --git a/tests/api/nft.test.ts b/tests/api/nft.test.ts index 7ccd7e9..2983cb8 100644 --- a/tests/api/nft.test.ts +++ b/tests/api/nft.test.ts @@ -1,10 +1,10 @@ import { strict as assert } from 'node:assert'; import { cycleMigrations } from '@stacks/api-toolkit'; -import { ENV } from '../../src/env.js'; import { MIGRATIONS_DIR, PgStore } from '../../src/pg/pg-store.js'; import { insertAndEnqueueTestContract, insertAndEnqueueTestContractWithTokens, + setupEnv, startTestApiServer, TestFastifyServer, } from '../helpers.js'; @@ -16,7 +16,7 @@ describe('NFT routes', () => { let fastify: TestFastifyServer; beforeEach(async () => { - ENV.PGDATABASE = 'postgres'; + setupEnv(); db = await PgStore.connect({ skipMigrations: true }); fastify = await startTestApiServer(db); await cycleMigrations(MIGRATIONS_DIR); diff --git a/tests/api/search.test.ts b/tests/api/search.test.ts index b877f5c..a54cd65 100644 --- a/tests/api/search.test.ts +++ b/tests/api/search.test.ts @@ -1,10 +1,10 @@ import { strict as assert } from 'node:assert'; import { cycleMigrations } from '@stacks/api-toolkit'; -import { ENV } from '../../src/env.js'; import { MIGRATIONS_DIR, PgStore } from '../../src/pg/pg-store.js'; import { DbSipNumber } from '../../src/pg/types.js'; import { insertAndEnqueueTestContractWithTokens, + setupEnv, startTestApiServer, TestFastifyServer, } from '../helpers.js'; @@ -15,7 +15,7 @@ describe('Search routes', () => { let fastify: TestFastifyServer; beforeEach(async () => { - ENV.PGDATABASE = 'postgres'; + setupEnv(); db = await PgStore.connect({ skipMigrations: true }); fastify = await startTestApiServer(db); await cycleMigrations(MIGRATIONS_DIR); diff --git a/tests/api/sft.test.ts b/tests/api/sft.test.ts index 6c7e281..3c62132 100644 --- a/tests/api/sft.test.ts +++ b/tests/api/sft.test.ts @@ -1,11 +1,11 @@ import { strict as assert } from 'node:assert'; import { cycleMigrations } from '@stacks/api-toolkit'; -import { ENV } from '../../src/env.js'; import { MIGRATIONS_DIR, PgStore } from '../../src/pg/pg-store.js'; import { DbSipNumber } from '../../src/pg/types.js'; import { insertAndEnqueueTestContract, insertAndEnqueueTestContractWithTokens, + setupEnv, startTestApiServer, TestFastifyServer, } from '../helpers.js'; @@ -16,7 +16,7 @@ describe('SFT routes', () => { let fastify: TestFastifyServer; beforeEach(async () => { - ENV.PGDATABASE = 'postgres'; + setupEnv(); db = await PgStore.connect({ skipMigrations: true }); fastify = await startTestApiServer(db); await cycleMigrations(MIGRATIONS_DIR); diff --git a/tests/api/status.test.ts b/tests/api/status.test.ts index 240b371..944c4b1 100644 --- a/tests/api/status.test.ts +++ b/tests/api/status.test.ts @@ -1,8 +1,7 @@ import { strict as assert } from 'node:assert'; import { cycleMigrations } from '@stacks/api-toolkit'; -import { ENV } from '../../src/env.js'; import { MIGRATIONS_DIR, PgStore } from '../../src/pg/pg-store.js'; -import { startTestApiServer, TestFastifyServer } from '../helpers.js'; +import { setupEnv, startTestApiServer, TestFastifyServer } from '../helpers.js'; import { afterEach, beforeEach, describe, test } from 'node:test'; describe('Status routes', () => { @@ -10,7 +9,7 @@ describe('Status routes', () => { let fastify: TestFastifyServer; beforeEach(async () => { - ENV.PGDATABASE = 'postgres'; + setupEnv(); db = await PgStore.connect({ skipMigrations: true }); fastify = await startTestApiServer(db); await cycleMigrations(MIGRATIONS_DIR); diff --git a/tests/docker-container.ts b/tests/docker-container.ts new file mode 100644 index 0000000..d68d548 --- /dev/null +++ b/tests/docker-container.ts @@ -0,0 +1,259 @@ +/* eslint-disable @typescript-eslint/no-unsafe-return */ +import { strict as assert } from 'node:assert'; +import * as net from 'node:net'; +import Docker from 'dockerode'; + +export interface PortMapping { + host: number; + container: number; +} + +export interface ContainerConfig { + /** Docker image (e.g. "postgres:17") */ + image: string; + /** Container name */ + name: string; + /** Host to bind to (default: "127.0.0.1") */ + host?: string; + /** Port mappings (host → container) */ + ports: PortMapping[]; + /** Port to wait on before declaring the container ready (default: first port's host side) */ + waitPort?: number; + /** Set to false to skip the port-readiness check (e.g. for one-shot sidecars) */ + waitForReady?: boolean; + /** Environment variables */ + env?: string[]; + /** Override the image entrypoint */ + entrypoint?: string[]; + /** Override the image command */ + command?: string[]; + /** Bind-mount volumes ("host:container") */ + volumes?: string[]; + /** Extra /etc/hosts entries ("hostname:ip") */ + extraHosts?: string[]; + /** Docker healthcheck command (passed after CMD-SHELL) */ + healthcheck?: string; + /** Restart policy (default: no) */ + restartPolicy?: 'no' | 'always' | 'on-failure' | 'unless-stopped'; + /** Labels to attach to the container */ + labels?: Record; + /** Startup timeout in ms (default: 120_000) */ + timeoutMs?: number; +} + +const DEFAULTS = { + host: '127.0.0.1', + timeoutMs: 120_000, +} as const; + +function createDockerClient(): Docker { + if (process.env.DOCKER_HOST) { + const dockerHost = new URL(process.env.DOCKER_HOST); + return new Docker({ + host: dockerHost.hostname, + port: Number(dockerHost.port), + protocol: dockerHost.protocol.replace(':', '') as 'http' | 'https' | 'ssh', + }); + } + return new Docker({ socketPath: process.env.DOCKER_SOCKET_PATH ?? '/var/run/docker.sock' }); +} + +function sleep(ms: number): Promise { + return new Promise(resolve => setTimeout(resolve, ms)); +} + +function streamToPromise(stream: NodeJS.ReadableStream): Promise { + return new Promise((resolve, reject) => { + stream.on('end', () => resolve()); + stream.on('error', reject); + }); +} + +async function pullImageIfMissing(docker: Docker, image: string): Promise { + const images = (await docker.listImages()) as { RepoTags?: string[] }[]; + const hasImage = images.some(img => img.RepoTags?.includes(image)); + if (hasImage) return; + + process.stdout.write(`[testenv] pulling image ${image}\n`); + const stream = await docker.pull(image); + await new Promise((resolve, reject) => { + docker.modem.followProgress(stream, err => { + if (err) { + reject(err instanceof Error ? err : new Error(String(err))); + return; + } + resolve(); + }); + }); +} + +async function getContainer(docker: Docker, name: string) { + const containers = await docker.listContainers({ + all: true, + filters: { name: [name] }, + }); + // Docker's name filter does substring matching, so we need an exact match. + // Container names are stored with a leading slash (e.g. "/my-container"). + const exact = containers.find(c => c.Names.some(n => n === `/${name}` || n === name)); + if (!exact) return undefined; + assert.ok(exact.Id); + return docker.getContainer(exact.Id); +} + +async function ensureContainerRunning(docker: Docker, config: ContainerConfig) { + const host = config.host ?? DEFAULTS.host; + const { + name, + image, + ports, + env, + entrypoint, + command, + volumes, + extraHosts, + healthcheck, + restartPolicy, + labels, + } = config; + + const existing = await getContainer(docker, name); + if (existing) { + const inspect = await existing.inspect(); + if (!inspect.State.Running) { + process.stdout.write(`[testenv] starting existing container ${name}\n`); + await existing.start(); + } else { + process.stdout.write(`[testenv] container ${name} already running\n`); + } + return existing; + } + + const exposedPorts: Record = {}; + const portBindings: Record = {}; + for (const { host: hostPort, container: containerPort } of ports) { + const key = `${containerPort}/tcp`; + exposedPorts[key] = {}; + portBindings[key] = [{ HostPort: String(hostPort), HostIp: host }]; + } + + const binds = volumes?.map(v => { + // Resolve relative paths from the project root + if (!v.startsWith('/')) { + const [hostPath, ...rest] = v.split(':'); + const resolved = `${process.cwd()}/${hostPath}`; + return [resolved, ...rest].join(':'); + } + return v; + }); + + process.stdout.write(`[testenv] creating container ${name}\n`); + const container = await docker.createContainer({ + name, + Image: image, + Env: env, + ...(entrypoint && { Entrypoint: entrypoint }), + ...(command && { Cmd: command }), + ExposedPorts: exposedPorts, + HostConfig: { + PortBindings: portBindings, + AutoRemove: false, + ...(binds && { Binds: binds }), + ...(extraHosts && { ExtraHosts: extraHosts }), + RestartPolicy: { Name: restartPolicy ?? 'no' }, + }, + Labels: labels, + ...(healthcheck && { + Healthcheck: { + Test: ['CMD-SHELL', healthcheck], + Interval: 2_000_000_000, + Timeout: 2_000_000_000, + Retries: 30, + StartPeriod: 2_000_000_000, + }, + }), + }); + await container.start(); + return container; +} + +async function waitForPort(host: string, port: number, timeoutMs: number): Promise { + const startedAt = Date.now(); + while (Date.now() - startedAt < timeoutMs) { + const ok = await new Promise(resolve => { + const socket = net.createConnection(port, host); + socket.setTimeout(1_000); + socket.on('connect', () => { + socket.end(); + resolve(true); + }); + socket.on('timeout', () => { + socket.destroy(); + resolve(false); + }); + socket.on('error', () => resolve(false)); + }); + if (ok) return; + await sleep(500); + } + throw new Error(`timed out waiting for ${host}:${port}`); +} + +export async function runUp(config: ContainerConfig): Promise { + const host = config.host ?? DEFAULTS.host; + const timeoutMs = config.timeoutMs ?? DEFAULTS.timeoutMs; + const docker = createDockerClient(); + await pullImageIfMissing(docker, config.image); + await ensureContainerRunning(docker, config); + if (config.waitForReady !== false && config.ports.length > 0) { + const port = config.waitPort ?? config.ports[0].host; + await waitForPort(host, port, timeoutMs); + process.stdout.write(`[testenv] ${config.name} ready on ${host}:${port}\n`); + } else { + process.stdout.write(`[testenv] ${config.name} started (no readiness check)\n`); + } +} + +export async function runDown(config: ContainerConfig): Promise { + const docker = createDockerClient(); + const container = await getContainer(docker, config.name); + if (!container) { + process.stdout.write(`[testenv] container ${config.name} is already absent\n`); + return; + } + const inspect = await container.inspect(); + if (inspect.State.Running) { + process.stdout.write(`[testenv] stopping ${config.name}\n`); + await container.stop({ t: 0 }); + } + process.stdout.write(`[testenv] removing ${config.name}\n`); + await container.remove({ force: true, v: true }); +} + +export async function runLogs(config: ContainerConfig, argv: string[]): Promise { + const follow = argv.includes('-f') || argv.includes('--follow') || !argv.includes('--once'); + const docker = createDockerClient(); + const container = await getContainer(docker, config.name); + if (!container) { + throw new Error(`container ${config.name} not found`); + } + if (follow) { + const logStream = await container.logs({ + stdout: true, + stderr: true, + follow: true, + timestamps: true, + tail: 200, + }); + container.modem.demuxStream(logStream, process.stdout, process.stderr); + await streamToPromise(logStream); + return; + } + const output = await container.logs({ + stdout: true, + stderr: true, + follow: false, + timestamps: true, + tail: 200, + }); + process.stdout.write(output.toString('utf8')); +} diff --git a/tests/helpers.ts b/tests/helpers.ts index 6d08728..f509488 100644 --- a/tests/helpers.ts +++ b/tests/helpers.ts @@ -2,7 +2,7 @@ import * as http from 'http'; import { PgStore } from '../src/pg/pg-store.js'; import { buildApiServer } from '../src/api/init.js'; import { FastifyBaseLogger, FastifyInstance } from 'fastify'; -import { IncomingMessage, Server, ServerResponse } from 'http'; +import { IncomingMessage, ServerResponse } from 'http'; import { TypeBoxTypeProvider } from '@fastify/type-provider-typebox'; import { SmartContractDeployment } from '../src/token-processor/util/sip-validation.js'; import { DbJob, DbSipNumber, DbSmartContract, DbUpdateNotification } from '../src/pg/types.js'; @@ -20,15 +20,32 @@ import { } from '@stacks/codec'; import { ClarityAbi } from '@stacks/transactions'; import { NewBlockEventType } from '@stacks/node-publisher-client'; +import { ENV } from '../src/env.js'; export type TestFastifyServer = FastifyInstance< - Server, + http.Server, IncomingMessage, ServerResponse, FastifyBaseLogger, TypeBoxTypeProvider >; +export function setupEnv() { + process.env.PGUSER = 'postgres'; + process.env.PGDATABASE = 'postgres'; + process.env.PGPASSWORD = 'postgres'; + ENV.STACKS_NODE_RPC_HOST = 'localhost'; + ENV.STACKS_NODE_RPC_PORT = 24000; + ENV.PGHOST = 'localhost'; + ENV.PGPORT = 5432; + ENV.PGUSER = 'postgres'; + ENV.PGDATABASE = 'postgres'; + ENV.PGPASSWORD = 'postgres'; + ENV.NETWORK = 'mainnet'; + ENV.SNP_REDIS_URL = 'redis://localhost:6379'; + ENV.SNP_REDIS_STREAM_KEY_PREFIX = 'test'; +} + export async function startTestApiServer(db: PgStore): Promise { return await buildApiServer({ db }); } diff --git a/tests/setup-env.ts b/tests/setup-env.ts deleted file mode 100644 index 97b57b2..0000000 --- a/tests/setup-env.ts +++ /dev/null @@ -1,10 +0,0 @@ -process.env.STACKS_NODE_RPC_HOST = process.env.STACKS_NODE_RPC_HOST ?? 'localhost'; -process.env.STACKS_NODE_RPC_PORT = process.env.STACKS_NODE_RPC_PORT ?? '24000'; -process.env.PGHOST = process.env.PGHOST ?? 'localhost'; -process.env.PGPORT = process.env.PGPORT ?? '5432'; -process.env.PGUSER = process.env.PGUSER ?? 'postgres'; -process.env.PGDATABASE = process.env.PGDATABASE ?? 'postgres'; -process.env.PGPASSWORD = process.env.PGPASSWORD ?? 'postgres'; -process.env.NETWORK = process.env.NETWORK ?? 'mainnet'; -process.env.SNP_REDIS_URL = process.env.SNP_REDIS_URL ?? 'redis://localhost:6379'; -process.env.SNP_REDIS_STREAM_KEY_PREFIX = process.env.SNP_REDIS_STREAM_KEY_PREFIX ?? 'test'; diff --git a/tests/setup.ts b/tests/setup.ts index cf7df2f..d9d64ff 100644 --- a/tests/setup.ts +++ b/tests/setup.ts @@ -1,213 +1,34 @@ -/* eslint-disable @typescript-eslint/no-unsafe-return */ -import { strict as assert } from 'node:assert'; -import * as net from 'node:net'; -import Docker from 'dockerode'; - -const IMAGE = 'postgres:17'; -const CONTAINER_NAME = 'token-metadata-api-test-postgres'; -const HOST = '127.0.0.1'; -const PORT = 5432; -const USER = 'postgres'; -const PASSWORD = 'postgres'; -const DATABASE = 'postgres'; -const STARTUP_TIMEOUT_MS = 120_000; - -function createDockerClient(): Docker { - if (process.env.DOCKER_HOST) { - const dockerHost = new URL(process.env.DOCKER_HOST); - return new Docker({ - host: dockerHost.hostname, - port: Number(dockerHost.port), - protocol: dockerHost.protocol.replace(':', '') as 'http' | 'https' | 'ssh', - }); - } - return new Docker({ socketPath: process.env.DOCKER_SOCKET_PATH ?? '/var/run/docker.sock' }); -} - -function sleep(ms: number): Promise { - return new Promise(resolve => setTimeout(resolve, ms)); -} - -function streamToPromise(stream: NodeJS.ReadableStream): Promise { - return new Promise((resolve, reject) => { - stream.on('end', () => resolve()); - stream.on('error', reject); - }); -} - -async function pullImageIfMissing(docker: Docker): Promise { - const images = (await docker.listImages()) as { RepoTags?: string[] }[]; - const hasImage = images.some(image => image.RepoTags?.includes(IMAGE)); - if (hasImage) return; - - process.stdout.write(`[testenv] pulling image ${IMAGE}\n`); - const stream = await docker.pull(IMAGE); - await new Promise((resolve, reject) => { - docker.modem.followProgress(stream, err => { - if (err) { - reject(err instanceof Error ? err : new Error(String(err))); - return; - } - resolve(); - }); - }); -} - -async function getContainer(docker: Docker) { - const containers = await docker.listContainers({ - all: true, - filters: { name: [CONTAINER_NAME] }, - }); - if (containers.length === 0) return undefined; - const [containerInfo] = containers; - assert.ok(containerInfo.Id); - return docker.getContainer(containerInfo.Id); -} - -async function ensureContainerRunning(docker: Docker) { - const existing = await getContainer(docker); - if (existing) { - const inspect = await existing.inspect(); - if (!inspect.State.Running) { - process.stdout.write(`[testenv] starting existing container ${CONTAINER_NAME}\n`); - await existing.start(); - } else { - process.stdout.write(`[testenv] container ${CONTAINER_NAME} already running\n`); - } - return existing; - } - - process.stdout.write(`[testenv] creating container ${CONTAINER_NAME}\n`); - const container = await docker.createContainer({ - name: CONTAINER_NAME, - Image: IMAGE, - Env: [ - `POSTGRES_USER=${USER}`, - `POSTGRES_PASSWORD=${PASSWORD}`, - `POSTGRES_DB=${DATABASE}`, - `POSTGRES_PORT=${PORT}`, +import type { ContainerConfig } from './docker-container.ts'; +import { runDown, runUp } from './docker-container.ts'; + +function defaultContainers(): ContainerConfig[] { + const postgres: ContainerConfig = { + image: 'postgres:17', + name: `metadata-api-test-postgres`, + ports: [{ host: 5432, container: 5432 }], + env: [ + 'POSTGRES_USER=postgres', + 'POSTGRES_PASSWORD=postgres', + 'POSTGRES_DB=postgres', ], - ExposedPorts: { - '5432/tcp': {}, - }, - HostConfig: { - PortBindings: { - '5432/tcp': [{ HostPort: String(PORT), HostIp: HOST }], - }, - AutoRemove: false, - }, - Labels: { - 'com.hiro.token-metadata-api.testenv': 'postgres', - }, - Healthcheck: { - Test: ['CMD-SHELL', `pg_isready -U ${USER} -d ${DATABASE}`], - Interval: 2_000_000_000, - Timeout: 2_000_000_000, - Retries: 30, - StartPeriod: 2_000_000_000, - }, - }); - await container.start(); - return container; -} - -async function waitForPort(): Promise { - const startedAt = Date.now(); - while (Date.now() - startedAt < STARTUP_TIMEOUT_MS) { - const ok = await new Promise(resolve => { - const socket = net.createConnection(PORT, HOST); - socket.setTimeout(1_000); - socket.on('connect', () => { - socket.end(); - resolve(true); - }); - socket.on('timeout', () => { - socket.destroy(); - resolve(false); - }); - socket.on('error', () => resolve(false)); - }); - if (ok) return; - await sleep(500); - } - throw new Error(`timed out waiting for postgres on ${HOST}:${PORT}`); + // waitPort: 5432, + healthcheck: 'pg_isready -U postgres', + }; + return [postgres]; } -export async function runUp(): Promise { - const docker = createDockerClient(); - await pullImageIfMissing(docker); - await ensureContainerRunning(docker); - await waitForPort(); - process.stdout.write(`[testenv] postgres ready on ${HOST}:${PORT}\n`); -} - -export async function runDown(): Promise { - const docker = createDockerClient(); - const container = await getContainer(docker); - if (!container) { - process.stdout.write(`[testenv] container ${CONTAINER_NAME} is already absent\n`); - return; +export async function globalSetup() { + const containers = defaultContainers(); + for (const config of containers) { + await runUp(config); } - const inspect = await container.inspect(); - if (inspect.State.Running) { - process.stdout.write(`[testenv] stopping ${CONTAINER_NAME}\n`); - await container.stop({ t: 0 }); - } - process.stdout.write(`[testenv] removing ${CONTAINER_NAME}\n`); - await container.remove({ force: true, v: true }); + process.stdout.write(`[testenv:metadata-api] all containers ready\n`); } -async function runLogs(argv: string[]): Promise { - const follow = argv.includes('-f') || argv.includes('--follow') || !argv.includes('--once'); - const docker = createDockerClient(); - const container = await getContainer(docker); - if (!container) { - throw new Error(`container ${CONTAINER_NAME} not found`); - } - if (follow) { - const logStream = await container.logs({ - stdout: true, - stderr: true, - follow: true, - timestamps: true, - tail: 200, - }); - container.modem.demuxStream(logStream, process.stdout, process.stderr); - await streamToPromise(logStream); - return; +export async function globalTeardown() { + const containers = defaultContainers(); + for (const config of [...containers].reverse()) { + await runDown(config); } - const output = await container.logs({ - stdout: true, - stderr: true, - follow: false, - timestamps: true, - tail: 200, - }); - process.stdout.write(output.toString('utf8')); -} - -async function main(): Promise { - const [command = 'up', ...args] = process.argv.slice(2); - if (command === 'up') { - await runUp(); - return; - } - if (command === 'down') { - await runDown(); - return; - } - if (command === 'logs') { - await runLogs(args); - return; - } - throw new Error(`unsupported command: ${command}`); -} - -// Only run CLI when invoked directly (not when loaded via --import) -if (process.argv[1]?.includes('setup.ts') || process.argv[1]?.includes('setup.js')) { - void main().catch(error => { - const message = error instanceof Error ? error.message : String(error); - process.stderr.write(`[testenv] ${message}\n`); - process.exitCode = 1; - }); + process.stdout.write(`[testenv:metadata-api] all containers removed\n`); } diff --git a/tests/stacks-core/block-processor.test.ts b/tests/stacks-core/block-processor.test.ts index 418eac6..9028389 100644 --- a/tests/stacks-core/block-processor.test.ts +++ b/tests/stacks-core/block-processor.test.ts @@ -9,6 +9,7 @@ import { markAllJobsAsDone, TestTransactionBuilder, TestBlockBuilder, + setupEnv, } from '../helpers.js'; import { StacksCoreBlockProcessor } from '../../src/stacks-core/stacks-core-block-processor.js'; import { afterEach, beforeEach, describe, test } from 'node:test'; @@ -18,7 +19,7 @@ describe('block processor', () => { let processor: StacksCoreBlockProcessor; beforeEach(async () => { - ENV.PGDATABASE = 'postgres'; + setupEnv(); db = await PgStore.connect({ skipMigrations: true }); await cycleMigrations(MIGRATIONS_DIR); processor = new StacksCoreBlockProcessor({ db: db.core }); diff --git a/tests/stacks-core/ft-events.test.ts b/tests/stacks-core/ft-events.test.ts index 037e684..59c7142 100644 --- a/tests/stacks-core/ft-events.test.ts +++ b/tests/stacks-core/ft-events.test.ts @@ -1,13 +1,13 @@ import { strict as assert } from 'node:assert'; import { DbProcessedTokenUpdateBundle, DbSipNumber } from '../../src/pg/types.js'; import { cycleMigrations } from '@stacks/api-toolkit'; -import { ENV } from '../../src/env.js'; import { PgStore, MIGRATIONS_DIR } from '../../src/pg/pg-store.js'; import { insertAndEnqueueTestContractWithTokens, markAllJobsAsDone, TestTransactionBuilder, TestBlockBuilder, + setupEnv, } from '../helpers.js'; import { StacksCoreBlockProcessor } from '../../src/stacks-core/stacks-core-block-processor.js'; import { afterEach, beforeEach, describe, test } from 'node:test'; @@ -17,7 +17,7 @@ describe('ft events', () => { let processor: StacksCoreBlockProcessor; beforeEach(async () => { - ENV.PGDATABASE = 'postgres'; + setupEnv(); db = await PgStore.connect({ skipMigrations: true }); await cycleMigrations(MIGRATIONS_DIR); processor = new StacksCoreBlockProcessor({ db: db.core }); diff --git a/tests/stacks-core/nft-events.test.ts b/tests/stacks-core/nft-events.test.ts index d838ef8..2f322e2 100644 --- a/tests/stacks-core/nft-events.test.ts +++ b/tests/stacks-core/nft-events.test.ts @@ -2,7 +2,6 @@ import { strict as assert } from 'node:assert'; import { cvToHex, uintCV } from '@stacks/transactions'; import { DbSipNumber } from '../../src/pg/types.js'; import { cycleMigrations } from '@stacks/api-toolkit'; -import { ENV } from '../../src/env.js'; import { PgStore, MIGRATIONS_DIR } from '../../src/pg/pg-store.js'; import { insertAndEnqueueTestContractWithTokens, @@ -10,6 +9,7 @@ import { TestTransactionBuilder, TestBlockBuilder, SIP_009_ABI, + setupEnv, } from '../helpers.js'; import { StacksCoreBlockProcessor } from '../../src/stacks-core/stacks-core-block-processor.js'; import { afterEach, beforeEach, describe, test } from 'node:test'; @@ -19,7 +19,7 @@ describe('nft events', () => { let processor: StacksCoreBlockProcessor; beforeEach(async () => { - ENV.PGDATABASE = 'postgres'; + setupEnv(); db = await PgStore.connect({ skipMigrations: true }); await cycleMigrations(MIGRATIONS_DIR); processor = new StacksCoreBlockProcessor({ db: db.core }); diff --git a/tests/stacks-core/notifications.test.ts b/tests/stacks-core/notifications.test.ts index 87f5769..2ae4e1d 100644 --- a/tests/stacks-core/notifications.test.ts +++ b/tests/stacks-core/notifications.test.ts @@ -2,7 +2,6 @@ import { strict as assert } from 'node:assert'; import { cvToHex, tupleCV, bufferCV, listCV, uintCV, stringUtf8CV } from '@stacks/transactions'; import { DbSipNumber } from '../../src/pg/types.js'; import { cycleMigrations } from '@stacks/api-toolkit'; -import { ENV } from '../../src/env.js'; import { PgStore, MIGRATIONS_DIR } from '../../src/pg/pg-store.js'; import { getLatestContractTokenNotifications, @@ -11,6 +10,7 @@ import { markAllJobsAsDone, TestTransactionBuilder, TestBlockBuilder, + setupEnv, } from '../helpers.js'; import { StacksCoreBlockProcessor } from '../../src/stacks-core/stacks-core-block-processor.js'; import { afterEach, beforeEach, describe, test } from 'node:test'; @@ -20,7 +20,7 @@ describe('token metadata notifications', () => { let processor: StacksCoreBlockProcessor; beforeEach(async () => { - ENV.PGDATABASE = 'postgres'; + setupEnv(); db = await PgStore.connect({ skipMigrations: true }); await cycleMigrations(MIGRATIONS_DIR); processor = new StacksCoreBlockProcessor({ db: db.core }); diff --git a/tests/stacks-core/reorg.test.ts b/tests/stacks-core/reorg.test.ts index 6a6aa75..4e526ca 100644 --- a/tests/stacks-core/reorg.test.ts +++ b/tests/stacks-core/reorg.test.ts @@ -2,7 +2,6 @@ import { strict as assert } from 'node:assert'; import { cvToHex, tupleCV, bufferCV, uintCV } from '@stacks/transactions'; import { DbSipNumber } from '../../src/pg/types.js'; import { cycleMigrations } from '@stacks/api-toolkit'; -import { ENV } from '../../src/env.js'; import { PgStore, MIGRATIONS_DIR } from '../../src/pg/pg-store.js'; import { TestTransactionBuilder, @@ -10,6 +9,7 @@ import { SIP_009_ABI, SIP_010_ABI, markAllJobsAsDone, + setupEnv, } from '../helpers.js'; import { StacksCoreBlockProcessor } from '../../src/stacks-core/stacks-core-block-processor.js'; import { after, before, describe, test } from 'node:test'; @@ -23,7 +23,7 @@ describe('re-org handling', () => { const nftContractId = `${address}.test-nft`; before(async () => { - ENV.PGDATABASE = 'postgres'; + setupEnv(); db = await PgStore.connect({ skipMigrations: true }); await cycleMigrations(MIGRATIONS_DIR); processor = new StacksCoreBlockProcessor({ db: db.core }); diff --git a/tests/stacks-core/sft-events.test.ts b/tests/stacks-core/sft-events.test.ts index 558b504..368d61f 100644 --- a/tests/stacks-core/sft-events.test.ts +++ b/tests/stacks-core/sft-events.test.ts @@ -2,13 +2,13 @@ import { strict as assert } from 'node:assert'; import { cvToHex, tupleCV, bufferCV, uintCV } from '@stacks/transactions'; import { DbSipNumber, DbTokenType } from '../../src/pg/types.js'; import { cycleMigrations } from '@stacks/api-toolkit'; -import { ENV } from '../../src/env.js'; import { PgStore, MIGRATIONS_DIR } from '../../src/pg/pg-store.js'; import { insertAndEnqueueTestContract, TestTransactionBuilder, TestBlockBuilder, markAllJobsAsDone, + setupEnv, } from '../helpers.js'; import { StacksCoreBlockProcessor } from '../../src/stacks-core/stacks-core-block-processor.js'; import { afterEach, beforeEach, describe, test } from 'node:test'; @@ -18,7 +18,7 @@ describe('sft events', () => { let processor: StacksCoreBlockProcessor; beforeEach(async () => { - ENV.PGDATABASE = 'postgres'; + setupEnv(); db = await PgStore.connect({ skipMigrations: true }); await cycleMigrations(MIGRATIONS_DIR); processor = new StacksCoreBlockProcessor({ db: db.core }); diff --git a/tests/stacks-core/smart-contracts.test.ts b/tests/stacks-core/smart-contracts.test.ts index c1bf3fb..0e35309 100644 --- a/tests/stacks-core/smart-contracts.test.ts +++ b/tests/stacks-core/smart-contracts.test.ts @@ -1,9 +1,8 @@ import { strict as assert } from 'node:assert'; import { DbSipNumber } from '../../src/pg/types.js'; import { cycleMigrations } from '@stacks/api-toolkit'; -import { ENV } from '../../src/env.js'; import { PgStore, MIGRATIONS_DIR } from '../../src/pg/pg-store.js'; -import { SIP_009_ABI, TestTransactionBuilder, TestBlockBuilder } from '../helpers.js'; +import { SIP_009_ABI, TestTransactionBuilder, TestBlockBuilder, setupEnv } from '../helpers.js'; import { StacksCoreBlockProcessor } from '../../src/stacks-core/stacks-core-block-processor.js'; import { afterEach, beforeEach, describe, test } from 'node:test'; @@ -12,7 +11,7 @@ describe('contract deployments', () => { let processor: StacksCoreBlockProcessor; beforeEach(async () => { - ENV.PGDATABASE = 'postgres'; + setupEnv(); db = await PgStore.connect({ skipMigrations: true }); await cycleMigrations(MIGRATIONS_DIR); processor = new StacksCoreBlockProcessor({ db: db.core }); diff --git a/tests/token-queue/job-queue.test.ts b/tests/token-queue/job-queue.test.ts index 205115c..6382956 100644 --- a/tests/token-queue/job-queue.test.ts +++ b/tests/token-queue/job-queue.test.ts @@ -3,7 +3,7 @@ import { ENV } from '../../src/env.js'; import { MIGRATIONS_DIR, PgStore } from '../../src/pg/pg-store.js'; import { DbJob, DbJobStatus, DbSipNumber } from '../../src/pg/types.js'; import { JobQueue } from '../../src/token-processor/queue/job-queue.js'; -import { insertAndEnqueueTestContract } from '../helpers.js'; +import { insertAndEnqueueTestContract, setupEnv } from '../helpers.js'; import { cycleMigrations, timeout } from '@stacks/api-toolkit'; import { StacksNetworkName } from '@stacks/network'; import { afterEach, beforeEach, describe, test } from 'node:test'; @@ -25,7 +25,7 @@ describe('JobQueue', () => { let queue: TestJobQueue; beforeEach(async () => { - ENV.PGDATABASE = 'postgres'; + setupEnv(); db = await PgStore.connect({ skipMigrations: true }); await cycleMigrations(MIGRATIONS_DIR); queue = new TestJobQueue({ db, network: 'mainnet' }); diff --git a/tests/token-queue/job.test.ts b/tests/token-queue/job.test.ts index 96ee501..951a92b 100644 --- a/tests/token-queue/job.test.ts +++ b/tests/token-queue/job.test.ts @@ -6,7 +6,7 @@ import { DbJob, DbSipNumber } from '../../src/pg/types.js'; import { RetryableJobError } from '../../src/token-processor/queue/errors.js'; import { Job } from '../../src/token-processor/queue/job/job.js'; import { UserError } from '../../src/token-processor/util/errors.js'; -import { insertAndEnqueueTestContract } from '../helpers.js'; +import { insertAndEnqueueTestContract, setupEnv } from '../helpers.js'; import { afterEach, beforeEach, describe, test } from 'node:test'; class TestRetryableJob extends Job { @@ -41,7 +41,7 @@ describe('Job', () => { let dbJob: DbJob; beforeEach(async () => { - ENV.PGDATABASE = 'postgres'; + setupEnv(); db = await PgStore.connect({ skipMigrations: true }); await cycleMigrations(MIGRATIONS_DIR); dbJob = await insertAndEnqueueTestContract(db, 'ABCD.test-ft', DbSipNumber.sip010); diff --git a/tests/token-queue/process-smart-contract-job.test.ts b/tests/token-queue/process-smart-contract-job.test.ts index b1d9c64..9ac6af6 100644 --- a/tests/token-queue/process-smart-contract-job.test.ts +++ b/tests/token-queue/process-smart-contract-job.test.ts @@ -6,14 +6,14 @@ import { DbSipNumber, DbToken, DbTokenType } from '../../src/pg/types.js'; import { ProcessSmartContractJob } from '../../src/token-processor/queue/job/process-smart-contract-job.js'; import { ENV } from '../../src/env.js'; import { cycleMigrations } from '@stacks/api-toolkit'; -import { insertAndEnqueueTestContract } from '../helpers.js'; +import { insertAndEnqueueTestContract, setupEnv } from '../helpers.js'; import { afterEach, beforeEach, describe, test } from 'node:test'; describe('ProcessSmartContractJob', () => { let db: PgStore; beforeEach(async () => { - ENV.PGDATABASE = 'postgres'; + setupEnv(); db = await PgStore.connect({ skipMigrations: true }); await cycleMigrations(MIGRATIONS_DIR); }); diff --git a/tests/token-queue/process-token-job.test.ts b/tests/token-queue/process-token-job.test.ts index f75d17a..13adbae 100644 --- a/tests/token-queue/process-token-job.test.ts +++ b/tests/token-queue/process-token-job.test.ts @@ -15,7 +15,7 @@ import { ProcessTokenJob } from '../../src/token-processor/queue/job/process-tok import { parseRetryAfterResponseHeader } from '../../src/token-processor/util/helpers.js'; import { RetryableJobError } from '../../src/token-processor/queue/errors.js'; import { cycleMigrations } from '@stacks/api-toolkit'; -import { insertAndEnqueueTestContractWithTokens } from '../helpers.js'; +import { insertAndEnqueueTestContractWithTokens, setupEnv } from '../helpers.js'; import { InvalidTokenError } from '../../src/pg/errors.js'; import { afterEach, beforeEach, describe, test } from 'node:test'; @@ -23,7 +23,7 @@ describe('ProcessTokenJob', () => { let db: PgStore; beforeEach(async () => { - ENV.PGDATABASE = 'postgres'; + setupEnv(); db = await PgStore.connect({ skipMigrations: true }); await cycleMigrations(MIGRATIONS_DIR); }); diff --git a/tests/token-queue/update-token-supply-job.test.ts b/tests/token-queue/update-token-supply-job.test.ts index c7018f4..7121106 100644 --- a/tests/token-queue/update-token-supply-job.test.ts +++ b/tests/token-queue/update-token-supply-job.test.ts @@ -5,7 +5,7 @@ import { MIGRATIONS_DIR, PgStore } from '../../src/pg/pg-store.js'; import { DbJob, DbSipNumber } from '../../src/pg/types.js'; import { ENV } from '../../src/env.js'; import { cycleMigrations } from '@stacks/api-toolkit'; -import { insertAndEnqueueTestContractWithTokens, markAllJobsAsDone } from '../helpers.js'; +import { insertAndEnqueueTestContractWithTokens, markAllJobsAsDone, setupEnv } from '../helpers.js'; import { UpdateTokenSupplyJob } from '../../src/token-processor/queue/job/update-token-supply-job.js'; import { afterEach, beforeEach, describe, test } from 'node:test'; @@ -13,7 +13,7 @@ describe('UpdateTokenSupplyJob', () => { let db: PgStore; beforeEach(async () => { - ENV.PGDATABASE = 'postgres'; + setupEnv(); db = await PgStore.connect({ skipMigrations: true }); await cycleMigrations(MIGRATIONS_DIR); }); diff --git a/tests/tsconfig.json b/tests/tsconfig.json new file mode 100644 index 0000000..02b7c79 --- /dev/null +++ b/tests/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "allowImportingTsExtensions": true + }, + "include": ["./**/*", "../src/**/*"] +} diff --git a/tsconfig.json b/tsconfig.json index 98b7b91..802f329 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,115 +1,19 @@ { "compilerOptions": { - /* Visit https://aka.ms/tsconfig to read more about this file */ - - /* Projects */ - // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ - // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ - // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ - // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ - // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ - // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ - - /* Language and Environment */ - "target": "es2022" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, - "lib": [ - "es2022" - ] /* Specify a set of bundled library declaration files that describe the target runtime environment. */, - // "jsx": "preserve", /* Specify what JSX code is generated. */ - // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ - // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ - // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ - // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ - // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ - // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ - // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ - // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ - // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ - - /* Modules */ - "module": "nodenext" /* Specify what module code is generated. */, - // "rootDir": "./", /* Specify the root folder within your source files. */ - "moduleResolution": "nodenext" /* Specify how TypeScript looks up a file from a given module specifier. */, - // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ - // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ - // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ - "typeRoots": [ - "./src/api/@types", - "./node_modules/@types" - ] /* Specify multiple folders that act like './node_modules/@types'. */, - // "types": [], /* Specify type package names to be included without being referenced in a source file. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ - // "resolveJsonModule": true, /* Enable importing .json files. */ - // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ - - /* JavaScript Support */ - // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ - // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ - // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ - - /* Emit */ - // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ - // "declarationMap": true, /* Create sourcemaps for d.ts files. */ - // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ - "sourceMap": true /* Create source map files for emitted JavaScript files. */, - // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ - "outDir": "./dist" /* Specify an output folder for all emitted files. */, - // "removeComments": true, /* Disable emitting comments. */ - // "noEmit": true, /* Disable emitting files from a compilation. */ - // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ - // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ - // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ - // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ - // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ - // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ - // "newLine": "crlf", /* Set the newline character for emitting files. */ - // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ - // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ - // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ - // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ - // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ - // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ - - /* Interop Constraints */ - // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ - "allowSyntheticDefaultImports": true /* Allow 'import x from y' when a module doesn't have a default export. */, - "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, - // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ - "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, - - /* Type Checking */ - "strict": true /* Enable all strict type-checking options. */, - // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ - // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ - // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ - // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ - // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ - // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ - // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ - // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ - // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ - // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ - // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ - // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ - // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ - // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ - // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ - // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ - // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ - // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ - - /* Completeness */ - // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ - "skipLibCheck": true /* Skip type checking all .d.ts files. */ + "target": "es2022", + "lib": ["es2022"], + "module": "nodenext", + "moduleResolution": "nodenext", + "typeRoots": ["./src/api/@types", "./node_modules/@types"], + "sourceMap": true, + "outDir": "./dist", + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "noEmit": true }, - "include": [ - "./src/**/*.ts", - "./tests/**/*.ts", - "./migrations/**/*.ts", - "./scripts/**/*.ts", - "./util/**/*.ts" - ] + "include": ["./src/**/*.ts", "./migrations/**/*.ts", "./scripts/**/*.ts", "./util/**/*.ts"], + "exclude": ["lib", "node_modules"] } From 72e7e4a61362b675b6090a1a9fd5db9183e857a3 Mon Sep 17 00:00:00 2001 From: Rafa Cardenas <253999660+rafa-stacks@users.noreply.github.com> Date: Thu, 26 Mar 2026 16:01:04 -0600 Subject: [PATCH 08/12] json5 --- src/token-processor/util/metadata-helpers.ts | 3 ++- tests/token-queue/metadata-helpers.test.ts | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/token-processor/util/metadata-helpers.ts b/src/token-processor/util/metadata-helpers.ts index 74fd1d0..13116f0 100644 --- a/src/token-processor/util/metadata-helpers.ts +++ b/src/token-processor/util/metadata-helpers.ts @@ -1,5 +1,5 @@ import * as querystring from 'querystring'; -import * as JSON5 from 'json5'; +import JSON5 from 'json5'; import { Agent, errors, request } from 'undici'; import { DbMetadataAttributeInsert, @@ -358,6 +358,7 @@ function parseJsonMetadata(url: string, content?: string): RawMetadata { throw new MetadataParseError(`Invalid raw metadata JSON schema: ${url}`); } } catch (error) { + if (error instanceof MetadataParseError) throw error; throw new MetadataParseError(`JSON parse error: ${url}`); } } diff --git a/tests/token-queue/metadata-helpers.test.ts b/tests/token-queue/metadata-helpers.test.ts index 36624d2..72019ae 100644 --- a/tests/token-queue/metadata-helpers.test.ts +++ b/tests/token-queue/metadata-helpers.test.ts @@ -43,7 +43,7 @@ describe('Metadata Helpers', () => { await assert.rejects( getMetadataFromUri('http://test.io/1.json', 'ABCD.test', 1n), - /JSON parse error/ + MetadataParseError ); }); From d1ff6b92caebfc2d7e293f31106b600b916c4102 Mon Sep 17 00:00:00 2001 From: Rafa Cardenas <253999660+rafa-stacks@users.noreply.github.com> Date: Thu, 26 Mar 2026 16:10:03 -0600 Subject: [PATCH 09/12] remove old deps --- .commitlintrc.json | 3 - .github/workflows/ci.yml | 11 - .vscode/launch.json | 53 +-- .vscode/tasks.json | 36 -- package-lock.json | 901 +-------------------------------------- package.json | 7 +- 6 files changed, 29 insertions(+), 982 deletions(-) delete mode 100644 .commitlintrc.json delete mode 100644 .vscode/tasks.json diff --git a/.commitlintrc.json b/.commitlintrc.json deleted file mode 100644 index c30e5a9..0000000 --- a/.commitlintrc.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": ["@commitlint/config-conventional"] -} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 757a4f4..d3a4913 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -59,17 +59,6 @@ jobs: matrix: suite: [admin, api, stacks-core, token-queue] runs-on: ubuntu-latest - env: - API_HOST: 127.0.0.1 - API_PORT: 3000 - PROMETHEUS_PORT: 9153 - PGHOST: 127.0.0.1 - PGPORT: 5432 - PGUSER: postgres - PGPASSWORD: postgres - PGDATABASE: postgres - STACKS_NODE_RPC_HOST: 127.0.0.1 - STACKS_NODE_RPC_PORT: 24440 steps: - uses: actions/checkout@v6 with: diff --git a/.vscode/launch.json b/.vscode/launch.json index 89c3a0c..60992d7 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -6,8 +6,8 @@ "request": "launch", "name": "start", "runtimeArgs": [ - "-r", - "ts-node/register" + "--import", + "tsx" ], "args": [ "${workspaceFolder}/src/index.ts" @@ -15,8 +15,7 @@ "outputCapture": "std", "internalConsoleOptions": "openOnSessionStart", "env": { - "NODE_ENV": "development", - "TS_NODE_SKIP_IGNORE": "true" + "NODE_ENV": "development" }, "killBehavior": "polite", }, @@ -25,8 +24,8 @@ "request": "launch", "name": "start: readonly", "runtimeArgs": [ - "-r", - "ts-node/register" + "--import", + "tsx" ], "args": [ "${workspaceFolder}/src/index.ts" @@ -35,7 +34,6 @@ "internalConsoleOptions": "openOnSessionStart", "env": { "NODE_ENV": "development", - "TS_NODE_SKIP_IGNORE": "true", "RUN_MODE": "readonly" }, "killBehavior": "polite", @@ -45,8 +43,8 @@ "request": "launch", "name": "start: writeonly", "runtimeArgs": [ - "-r", - "ts-node/register" + "--import", + "tsx" ], "args": [ "${workspaceFolder}/src/index.ts" @@ -55,32 +53,10 @@ "internalConsoleOptions": "openOnSessionStart", "env": { "NODE_ENV": "development", - "TS_NODE_SKIP_IGNORE": "true", "RUN_MODE": "writeonly" }, "killBehavior": "polite", }, - { - "type": "node", - "request": "launch", - "name": "test", - "runtimeExecutable": "node", - "args": [ - "--import", - "tsx", - "--import", - "${workspaceFolder}/tests/setup-env.ts", - "--test", - "--test-concurrency=1", - ], - "outputCapture": "std", - "console": "integratedTerminal", - "preLaunchTask": "npm: testenv:run", - "postDebugTask": "npm: testenv:stop", - "env": { - "NODE_ENV": "test" - }, - }, { "type": "node", "request": "launch", @@ -108,16 +84,13 @@ "args": [ "--import", "tsx", - "--import", - "${workspaceFolder}/tests/setup-env.ts", "--test", + "--test-global-setup=./tests/setup.ts", "--test-concurrency=1", "${workspaceFolder}/tests/api/*.test.ts" ], "outputCapture": "std", "console": "integratedTerminal", - "preLaunchTask": "npm: testenv:run", - "postDebugTask": "npm: testenv:stop", "env": { "NODE_ENV": "test" }, @@ -130,16 +103,13 @@ "args": [ "--import", "tsx", - "--import", - "${workspaceFolder}/tests/setup-env.ts", "--test", + "--test-global-setup=./tests/setup.ts", "--test-concurrency=1", "${workspaceFolder}/tests/stacks-core/*.test.ts", ], "outputCapture": "std", "console": "integratedTerminal", - "preLaunchTask": "npm: testenv:run", - "postDebugTask": "npm: testenv:stop", "env": { "NODE_ENV": "test" }, @@ -152,16 +122,13 @@ "args": [ "--import", "tsx", - "--import", - "${workspaceFolder}/tests/setup-env.ts", "--test", + "--test-global-setup=./tests/setup.ts", "--test-concurrency=1", "${workspaceFolder}/tests/token-queue/*.test.ts" ], "outputCapture": "std", "console": "integratedTerminal", - "preLaunchTask": "npm: testenv:run", - "postDebugTask": "npm: testenv:stop", "env": { "NODE_ENV": "test" }, diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index 2af66cf..0000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "npm: testenv:run", - "type": "shell", - "command": "npm run testenv:run", - "isBackground": true, - "problemMatcher": [ - { - "pattern": [ - { "regexp": ".", "file": 1, "location": 2, "message": 3 } - ], - "background": { - "activeOnStart": true, - "beginsPattern": ".", - "endsPattern": "." - } - } - ] - }, - { - "label": "npm: testenv:stop", - "type": "shell", - "command": "npm run testenv:stop", - "presentation": { - "echo": true, - "reveal": "silent", - "focus": false, - "panel": "shared", - "showReuseMessage": true, - "clear": false - } - } - ] -} diff --git a/package-lock.json b/package-lock.json index 07a233e..875e469 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,7 +18,7 @@ "@stacks/blockchain-api-client": "^8.14.2", "@stacks/codec": "^1.6.0", "@stacks/node-publisher-client": "^2.0.5", - "@stacks/transactions": "^7.3.1", + "@stacks/transactions": "^7.4.0", "@types/node": "^24.0.0", "bignumber.js": "^10.0.2", "env-schema": "^7.0.0", @@ -26,13 +26,11 @@ "fastify-metrics": "^12.1.0", "json5": "^2.2.3", "node-pg-migrate": "^8.0.4", - "p-queue": "^8.1.0", + "p-queue": "^9.1.0", "sharp": "^0.34.5", "undici": "^7.24.4" }, "devDependencies": { - "@commitlint/cli": "^20.5.0", - "@commitlint/config-conventional": "^20.5.0", "@stacks/eslint-config": "^2.0.0", "@types/dockerode": "^3.3.40", "@typescript-eslint/eslint-plugin": "^8.57.1", @@ -47,7 +45,6 @@ "openapi-typescript": "^7.13.0", "prettier": "^3.8.1", "rimraf": "^6.1.3", - "ts-node": "^10.9.2", "tsx": "^4.20.6", "typescript": "^5.9.3" }, @@ -102,339 +99,6 @@ "dev": true, "license": "Apache-2.0" }, - "node_modules/@commitlint/cli": { - "version": "20.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-20.5.0.tgz", - "integrity": "sha512-yNkyN/tuKTJS3wdVfsZ2tXDM4G4Gi7z+jW54Cki8N8tZqwKBltbIvUUrSbT4hz1bhW/h0CdR+5sCSpXD+wMKaQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@commitlint/format": "^20.5.0", - "@commitlint/lint": "^20.5.0", - "@commitlint/load": "^20.5.0", - "@commitlint/read": "^20.5.0", - "@commitlint/types": "^20.5.0", - "tinyexec": "^1.0.0", - "yargs": "^17.0.0" - }, - "bin": { - "commitlint": "cli.js" - }, - "engines": { - "node": ">=v18" - } - }, - "node_modules/@commitlint/config-conventional": { - "version": "20.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-20.5.0.tgz", - "integrity": "sha512-t3Ni88rFw1XMa4nZHgOKJ8fIAT9M2j5TnKyTqJzsxea7FUetlNdYFus9dz+MhIRZmc16P0PPyEfh6X2d/qw8SA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@commitlint/types": "^20.5.0", - "conventional-changelog-conventionalcommits": "^9.2.0" - }, - "engines": { - "node": ">=v18" - } - }, - "node_modules/@commitlint/config-validator": { - "version": "20.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-20.5.0.tgz", - "integrity": "sha512-T/Uh6iJUzyx7j35GmHWdIiGRQB+ouZDk0pwAaYq4SXgB54KZhFdJ0vYmxiW6AMYICTIWuyMxDBl1jK74oFp/Gw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@commitlint/types": "^20.5.0", - "ajv": "^8.11.0" - }, - "engines": { - "node": ">=v18" - } - }, - "node_modules/@commitlint/ensure": { - "version": "20.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-20.5.0.tgz", - "integrity": "sha512-IpHqAUesBeW1EDDdjzJeaOxU9tnogLAyXLRBn03SHlj1SGENn2JGZqSWGkFvBJkJzfXAuCNtsoYzax+ZPS+puw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@commitlint/types": "^20.5.0", - "lodash.camelcase": "^4.3.0", - "lodash.kebabcase": "^4.1.1", - "lodash.snakecase": "^4.1.1", - "lodash.startcase": "^4.4.0", - "lodash.upperfirst": "^4.3.1" - }, - "engines": { - "node": ">=v18" - } - }, - "node_modules/@commitlint/execute-rule": { - "version": "20.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-20.0.0.tgz", - "integrity": "sha512-xyCoOShoPuPL44gVa+5EdZsBVao/pNzpQhkzq3RdtlFdKZtjWcLlUFQHSWBuhk5utKYykeJPSz2i8ABHQA+ZZw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=v18" - } - }, - "node_modules/@commitlint/format": { - "version": "20.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-20.5.0.tgz", - "integrity": "sha512-TI9EwFU/qZWSK7a5qyXMpKPPv3qta7FO4tKW+Wt2al7sgMbLWTsAcDpX1cU8k16TRdsiiet9aOw0zpvRXNJu7Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@commitlint/types": "^20.5.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=v18" - } - }, - "node_modules/@commitlint/is-ignored": { - "version": "20.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-20.5.0.tgz", - "integrity": "sha512-JWLarAsurHJhPozbuAH6GbP4p/hdOCoqS9zJMfqwswne+/GPs5V0+rrsfOkP68Y8PSLphwtFXV0EzJ+GTXTTGg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@commitlint/types": "^20.5.0", - "semver": "^7.6.0" - }, - "engines": { - "node": ">=v18" - } - }, - "node_modules/@commitlint/is-ignored/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@commitlint/lint": { - "version": "20.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-20.5.0.tgz", - "integrity": "sha512-jiM3hNUdu04jFBf1VgPdjtIPvbuVfDTBAc6L98AWcoLjF5sYqkulBHBzlVWll4rMF1T5zeQFB6r//a+s+BBKlA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@commitlint/is-ignored": "^20.5.0", - "@commitlint/parse": "^20.5.0", - "@commitlint/rules": "^20.5.0", - "@commitlint/types": "^20.5.0" - }, - "engines": { - "node": ">=v18" - } - }, - "node_modules/@commitlint/load": { - "version": "20.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-20.5.0.tgz", - "integrity": "sha512-sLhhYTL/KxeOTZjjabKDhwidGZan84XKK1+XFkwDYL/4883kIajcz/dZFAhBJmZPtL8+nBx6bnkzA95YxPeDPw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@commitlint/config-validator": "^20.5.0", - "@commitlint/execute-rule": "^20.0.0", - "@commitlint/resolve-extends": "^20.5.0", - "@commitlint/types": "^20.5.0", - "cosmiconfig": "^9.0.1", - "cosmiconfig-typescript-loader": "^6.1.0", - "is-plain-obj": "^4.1.0", - "lodash.mergewith": "^4.6.2", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=v18" - } - }, - "node_modules/@commitlint/message": { - "version": "20.4.3", - "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-20.4.3.tgz", - "integrity": "sha512-6akwCYrzcrFcTYz9GyUaWlhisY4lmQ3KvrnabmhoeAV8nRH4dXJAh4+EUQ3uArtxxKQkvxJS78hNX2EU3USgxQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=v18" - } - }, - "node_modules/@commitlint/parse": { - "version": "20.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-20.5.0.tgz", - "integrity": "sha512-SeKWHBMk7YOTnnEWUhx+d1a9vHsjjuo6Uo1xRfPNfeY4bdYFasCH1dDpAv13Lyn+dDPOels+jP6D2GRZqzc5fA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@commitlint/types": "^20.5.0", - "conventional-changelog-angular": "^8.2.0", - "conventional-commits-parser": "^6.3.0" - }, - "engines": { - "node": ">=v18" - } - }, - "node_modules/@commitlint/read": { - "version": "20.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-20.5.0.tgz", - "integrity": "sha512-JDEIJ2+GnWpK8QqwfmW7O42h0aycJEWNqcdkJnyzLD11nf9dW2dWLTVEa8Wtlo4IZFGLPATjR5neA5QlOvIH1w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@commitlint/top-level": "^20.4.3", - "@commitlint/types": "^20.5.0", - "git-raw-commits": "^5.0.0", - "minimist": "^1.2.8", - "tinyexec": "^1.0.0" - }, - "engines": { - "node": ">=v18" - } - }, - "node_modules/@commitlint/resolve-extends": { - "version": "20.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-20.5.0.tgz", - "integrity": "sha512-3SHPWUW2v0tyspCTcfSsYml0gses92l6TlogwzvM2cbxDgmhSRc+fldDjvGkCXJrjSM87BBaWYTPWwwyASZRrg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@commitlint/config-validator": "^20.5.0", - "@commitlint/types": "^20.5.0", - "global-directory": "^4.0.1", - "import-meta-resolve": "^4.0.0", - "lodash.mergewith": "^4.6.2", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=v18" - } - }, - "node_modules/@commitlint/rules": { - "version": "20.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-20.5.0.tgz", - "integrity": "sha512-5NdQXQEdnDPT5pK8O39ZA7HohzPRHEsDGU23cyVCNPQy4WegAbAwrQk3nIu7p2sl3dutPk8RZd91yKTrMTnRkQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@commitlint/ensure": "^20.5.0", - "@commitlint/message": "^20.4.3", - "@commitlint/to-lines": "^20.0.0", - "@commitlint/types": "^20.5.0" - }, - "engines": { - "node": ">=v18" - } - }, - "node_modules/@commitlint/to-lines": { - "version": "20.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-20.0.0.tgz", - "integrity": "sha512-2l9gmwiCRqZNWgV+pX1X7z4yP0b3ex/86UmUFgoRt672Ez6cAM2lOQeHFRUTuE6sPpi8XBCGnd8Kh3bMoyHwJw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=v18" - } - }, - "node_modules/@commitlint/top-level": { - "version": "20.4.3", - "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-20.4.3.tgz", - "integrity": "sha512-qD9xfP6dFg5jQ3NMrOhG0/w5y3bBUsVGyJvXxdWEwBm8hyx4WOk3kKXw28T5czBYvyeCVJgJJ6aoJZUWDpaacQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "escalade": "^3.2.0" - }, - "engines": { - "node": ">=v18" - } - }, - "node_modules/@commitlint/types": { - "version": "20.5.0", - "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-20.5.0.tgz", - "integrity": "sha512-ZJoS8oSq2CAZEpc/YI9SulLrdiIyXeHb/OGqGrkUP6Q7YV+0ouNAa7GjqRdXeQPncHQIDz/jbCTlHScvYvO/gA==", - "dev": true, - "license": "MIT", - "dependencies": { - "conventional-commits-parser": "^6.3.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=v18" - } - }, - "node_modules/@conventional-changelog/git-client": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@conventional-changelog/git-client/-/git-client-2.6.0.tgz", - "integrity": "sha512-T+uPDciKf0/ioNNDpMGc8FDsehJClZP0yR3Q5MN6wE/Y/1QZ7F+80OgznnTCOlMEG4AV0LvH2UJi3C/nBnaBUg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@simple-libs/child-process-utils": "^1.0.0", - "@simple-libs/stream-utils": "^1.2.0", - "semver": "^7.5.2" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "conventional-commits-filter": "^5.0.0", - "conventional-commits-parser": "^6.3.0" - }, - "peerDependenciesMeta": { - "conventional-commits-filter": { - "optional": true - }, - "conventional-commits-parser": { - "optional": true - } - } - }, - "node_modules/@conventional-changelog/git-client/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, "node_modules/@emnapi/core": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.0.tgz", @@ -2012,23 +1676,6 @@ "node": ">=18" } }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "dev": true, - "license": "MIT" - }, "node_modules/@js-sdsl/ordered-map": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", @@ -2412,35 +2059,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@simple-libs/child-process-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@simple-libs/child-process-utils/-/child-process-utils-1.0.2.tgz", - "integrity": "sha512-/4R8QKnd/8agJynkNdJmNw2MBxuFTRcNFnE5Sg/G+jkSsV8/UBgULMzhizWWW42p8L5H7flImV2ATi79Ove2Tw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@simple-libs/stream-utils": "^1.2.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://ko-fi.com/dangreen" - } - }, - "node_modules/@simple-libs/stream-utils": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@simple-libs/stream-utils/-/stream-utils-1.2.0.tgz", - "integrity": "sha512-KxXvfapcixpz6rVEB6HPjOUZT22yN6v0vI0urQSk1L8MlEWPDFCZkhw2xmkyoTGYeFw7tWTZd7e3lVzRZRN/EA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://ko-fi.com/dangreen" - } - }, "node_modules/@sinclair/typebox": { "version": "0.34.48", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", @@ -3059,9 +2677,9 @@ } }, "node_modules/@stacks/transactions": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/@stacks/transactions/-/transactions-7.3.1.tgz", - "integrity": "sha512-ufnC1BPrOKz5b5gxxdseP3vBrFq1+qx1L6t+J/QnjXULyWdkhtS+LBEqRw2bL5qNteMvU2GhqPgFtYQPzolGbw==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@stacks/transactions/-/transactions-7.4.0.tgz", + "integrity": "sha512-scsQO3rSNNKcPHp56Wy5OeZiIpQNmmZOORz8bkQKWjzvzycAodtSWmAoHiMFAKSleR1NyeRIz642fReqlZU9tw==", "license": "MIT", "dependencies": { "@noble/hashes": "1.1.5", @@ -3080,34 +2698,6 @@ "node": ">= 10" } }, - "node_modules/@tsconfig/node10": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.12.tgz", - "integrity": "sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true, - "license": "MIT" - }, "node_modules/@tybys/wasm-util": { "version": "0.10.1", "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", @@ -3173,7 +2763,6 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.0.tgz", "integrity": "sha512-GYDxsZi3ChgmckRT9HPU0WEhKLP08ev/Yfcq2AstjrDASOYCSXeyjDsHg4v5t4jOj7cyDX3vmprafKlWIG9MXQ==", "license": "MIT", - "peer": true, "dependencies": { "undici-types": "~7.16.0" } @@ -3888,19 +3477,6 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/acorn-walk": { - "version": "8.3.5", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.5.tgz", - "integrity": "sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==", - "dev": true, - "license": "MIT", - "dependencies": { - "acorn": "^8.11.0" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/agent-base": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", @@ -3975,13 +3551,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true, - "license": "MIT" - }, "node_modules/array-buffer-byte-length": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", @@ -3999,13 +3568,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array-ify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", - "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", - "dev": true, - "license": "MIT" - }, "node_modules/array-includes": { "version": "3.1.9", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", @@ -4512,17 +4074,6 @@ "node": ">= 0.8" } }, - "node_modules/compare-func": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", - "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-ify": "^1.0.0", - "dot-prop": "^5.1.0" - } - }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -4530,49 +4081,6 @@ "dev": true, "license": "MIT" }, - "node_modules/conventional-changelog-angular": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-8.3.0.tgz", - "integrity": "sha512-DOuBwYSqWzfwuRByY9O4oOIvDlkUCTDzfbOgcSbkY+imXXj+4tmrEFao3K+FxemClYfYnZzsvudbwrhje9VHDA==", - "dev": true, - "license": "ISC", - "dependencies": { - "compare-func": "^2.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/conventional-changelog-conventionalcommits": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-9.3.0.tgz", - "integrity": "sha512-kYFx6gAyjSIMwNtASkI3ZE99U1fuVDJr0yTYgVy+I2QG46zNZfl2her+0+eoviG82c5WQvW1jMt1eOQTeJLodA==", - "dev": true, - "license": "ISC", - "dependencies": { - "compare-func": "^2.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/conventional-commits-parser": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-6.3.0.tgz", - "integrity": "sha512-RfOq/Cqy9xV9bOA8N+ZH6DlrDR+5S3Mi0B5kACEjESpE+AviIpAptx9a9cFpWCCvgRtWT+0BbUw+e1BZfts9jg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@simple-libs/stream-utils": "^1.2.0", - "meow": "^13.0.0" - }, - "bin": { - "conventional-commits-parser": "dist/cli/index.js" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/cookie": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", @@ -4586,71 +4094,6 @@ "url": "https://opencollective.com/express" } }, - "node_modules/cosmiconfig": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.1.tgz", - "integrity": "sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "env-paths": "^2.2.1", - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" - }, - "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/cosmiconfig-typescript-loader": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-6.2.0.tgz", - "integrity": "sha512-GEN39v7TgdxgIoNcdkRE3uiAzQt3UXLyHbRHD6YoL048XAeOomyxaP+Hh/+2C6C2wYjxJ2onhJcsQp+L4YEkVQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "jiti": "^2.6.1" - }, - "engines": { - "node": ">=v18" - }, - "peerDependencies": { - "@types/node": "*", - "cosmiconfig": ">=9", - "typescript": ">=5" - } - }, - "node_modules/cosmiconfig/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, - "node_modules/cosmiconfig/node_modules/js-yaml": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/cpu-features": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.10.tgz", @@ -4666,13 +4109,6 @@ "node": ">=10.0.0" } }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true, - "license": "MIT" - }, "node_modules/cross-fetch": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz", @@ -4847,16 +4283,6 @@ "node": ">=8" } }, - "node_modules/diff": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz", - "integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/docker-modem": { "version": "5.0.6", "resolved": "https://registry.npmjs.org/docker-modem/-/docker-modem-5.0.6.tgz", @@ -4934,19 +4360,6 @@ "node": ">=0.10.0" } }, - "node_modules/dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-obj": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -5027,16 +4440,6 @@ "node": ">=10.0.0" } }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/env-schema": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/env-schema/-/env-schema-7.0.0.tgz", @@ -5056,16 +4459,6 @@ "ajv": "^8.12.0" } }, - "node_modules/error-ex": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", - "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, "node_modules/es-abstract": { "version": "1.24.1", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.1.tgz", @@ -6602,23 +5995,6 @@ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, - "node_modules/git-raw-commits": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-5.0.1.tgz", - "integrity": "sha512-Y+csSm2GD/PCSh6Isd/WiMjNAydu0VBiG9J7EdQsNA5P9uXvLayqjmTsNlK5Gs9IhblFZqOU0yid5Il5JPoLiQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@conventional-changelog/git-client": "^2.6.0", - "meow": "^13.0.0" - }, - "bin": { - "git-raw-commits": "src/cli.js" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/glob": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz", @@ -6655,22 +6031,6 @@ "node": ">=10.13.0" } }, - "node_modules/global-directory": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz", - "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ini": "4.1.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/globals": { "version": "14.0.0", "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", @@ -6944,17 +6304,6 @@ "node": ">=4" } }, - "node_modules/import-meta-resolve": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", - "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -6982,16 +6331,6 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, - "node_modules/ini": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", - "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, "node_modules/internal-slot": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", @@ -7034,13 +6373,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true, - "license": "MIT" - }, "node_modules/is-async-function": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", @@ -7296,29 +6628,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", - "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-regex": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", @@ -7502,16 +6811,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/jiti": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", - "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", - "dev": true, - "license": "MIT", - "bin": { - "jiti": "lib/jiti-cli.mjs" - } - }, "node_modules/jju": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", @@ -7560,13 +6859,6 @@ "dev": true, "license": "MIT" }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true, - "license": "MIT" - }, "node_modules/json-schema-ref-resolver": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/json-schema-ref-resolver/-/json-schema-ref-resolver-3.0.0.tgz", @@ -7618,7 +6910,8 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/json5": { "version": "2.2.3", @@ -7717,13 +7010,6 @@ ], "license": "MIT" }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true, - "license": "MIT" - }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -7752,13 +7038,6 @@ "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" }, - "node_modules/lodash.kebabcase": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", - "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==", - "dev": true, - "license": "MIT" - }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -7766,34 +7045,6 @@ "dev": true, "license": "MIT" }, - "node_modules/lodash.mergewith": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", - "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.snakecase": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", - "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.startcase": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", - "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.upperfirst": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", - "integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==", - "dev": true, - "license": "MIT" - }, "node_modules/long": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", @@ -7812,12 +7063,6 @@ "node": ">=10" } }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -7828,19 +7073,6 @@ "node": ">= 0.4" } }, - "node_modules/meow": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz", - "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -8291,16 +7523,16 @@ } }, "node_modules/p-queue": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-8.1.1.tgz", - "integrity": "sha512-aNZ+VfjobsWryoiPnEApGGmf5WmNsCo9xu8dfaYamG5qaLP7ClhLN6NgsFe6SwJ2UbLEBK5dv9x8Mn5+RVhMWQ==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-9.1.0.tgz", + "integrity": "sha512-O/ZPaXuQV29uSLbxWBGGZO1mCQXV2BLIwUr59JUU9SoH76mnYvtms7aafH/isNSNGwuEfP6W/4xD0/TJXxrizw==", "license": "MIT", "dependencies": { "eventemitter3": "^5.0.1", - "p-timeout": "^6.1.2" + "p-timeout": "^7.0.0" }, "engines": { - "node": ">=18" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -8313,12 +7545,12 @@ "license": "MIT" }, "node_modules/p-timeout": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.4.tgz", - "integrity": "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-7.0.1.tgz", + "integrity": "sha512-AxTM2wDGORHGEkPCt8yqxOTMgpfbEHqF51f/5fJCmwFC3C/zNcGT63SymH2ttOAaiIws2zVg4+izQCjrakcwHg==", "license": "MIT", "engines": { - "node": ">=14.16" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -8348,25 +7580,6 @@ "node": ">=6" } }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -8711,6 +7924,7 @@ "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -8905,16 +8119,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/resolve-pkg-maps": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", @@ -9735,16 +8939,6 @@ "real-require": "^0.2.0" } }, - "node_modules/tinyexec": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.4.tgz", - "integrity": "sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - } - }, "node_modules/tinyglobby": { "version": "0.2.15", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", @@ -9789,50 +8983,6 @@ "typescript": ">=4.8.4" } }, - "node_modules/ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, "node_modules/tsconfig-paths": { "version": "3.15.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", @@ -10114,13 +9264,6 @@ "uuid": "dist/bin/uuid" } }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true, - "license": "MIT" - }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", @@ -10366,16 +9509,6 @@ "node": ">=12" } }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 9df1460..8a3394a 100644 --- a/package.json +++ b/package.json @@ -31,8 +31,6 @@ }, "prettier": "@stacks/prettier-config", "devDependencies": { - "@commitlint/cli": "^20.5.0", - "@commitlint/config-conventional": "^20.5.0", "@stacks/eslint-config": "^2.0.0", "@types/dockerode": "^3.3.40", "@typescript-eslint/eslint-plugin": "^8.57.1", @@ -47,7 +45,6 @@ "openapi-typescript": "^7.13.0", "prettier": "^3.8.1", "rimraf": "^6.1.3", - "ts-node": "^10.9.2", "tsx": "^4.20.6", "typescript": "^5.9.3" }, @@ -61,7 +58,7 @@ "@stacks/blockchain-api-client": "^8.14.2", "@stacks/codec": "^1.6.0", "@stacks/node-publisher-client": "^2.0.5", - "@stacks/transactions": "^7.3.1", + "@stacks/transactions": "^7.4.0", "@types/node": "^24.0.0", "bignumber.js": "^10.0.2", "env-schema": "^7.0.0", @@ -69,7 +66,7 @@ "fastify-metrics": "^12.1.0", "json5": "^2.2.3", "node-pg-migrate": "^8.0.4", - "p-queue": "^8.1.0", + "p-queue": "^9.1.0", "sharp": "^0.34.5", "undici": "^7.24.4" } From c1ef740705a8079a880966fdbaaab160f08a5dde Mon Sep 17 00:00:00 2001 From: Rafa Cardenas <253999660+rafa-stacks@users.noreply.github.com> Date: Thu, 26 Mar 2026 16:22:19 -0600 Subject: [PATCH 10/12] lint errors --- .github/workflows/ci.yml | 11 + eslint.config.js | 9 +- package-lock.json | 661 +++--------------- package.json | 6 +- src/admin-rpc/init.ts | 9 +- src/api/@types/fastify/index.d.ts | 10 +- src/api/init.ts | 2 +- src/api/routes/ft.ts | 4 +- src/api/routes/nft.ts | 2 +- src/api/routes/search.ts | 2 +- src/api/routes/sft.ts | 2 +- src/api/routes/status.ts | 4 +- src/api/util/cache.ts | 7 +- src/api/util/errors.ts | 2 +- src/token-processor/images/image-cache.ts | 4 +- src/token-processor/queue/job/job.ts | 6 +- .../queue/job/process-smart-contract-job.ts | 4 +- .../queue/job/process-token-job.ts | 2 +- .../queue/job/update-token-supply-job.ts | 2 +- .../stacks-node/stacks-node-rpc-client.ts | 6 +- src/token-processor/util/metadata-helpers.ts | 8 +- src/token-processor/util/sip-validation.ts | 9 +- 22 files changed, 149 insertions(+), 623 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d3a4913..757a4f4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -59,6 +59,17 @@ jobs: matrix: suite: [admin, api, stacks-core, token-queue] runs-on: ubuntu-latest + env: + API_HOST: 127.0.0.1 + API_PORT: 3000 + PROMETHEUS_PORT: 9153 + PGHOST: 127.0.0.1 + PGPORT: 5432 + PGUSER: postgres + PGPASSWORD: postgres + PGDATABASE: postgres + STACKS_NODE_RPC_HOST: 127.0.0.1 + STACKS_NODE_RPC_PORT: 24440 steps: - uses: actions/checkout@v6 with: diff --git a/eslint.config.js b/eslint.config.js index 699a43f..6fb0109 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -3,14 +3,7 @@ import tsdoc from 'eslint-plugin-tsdoc'; export default [ { - ignores: [ - 'lib/**', - 'client/**', - 'utils/**', - 'migrations/**', - 'tests/**', - 'stacks-blockchain/**', - ], + ignores: ['dist/**', 'client/**', 'util/**', 'migrations/**', 'tests/**', 'coverage/**'], }, ...stacksConfig, { diff --git a/package-lock.json b/package-lock.json index 875e469..705ab0e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,7 +31,7 @@ "undici": "^7.24.4" }, "devDependencies": { - "@stacks/eslint-config": "^2.0.0", + "@stacks/eslint-config": "^3.0.0-develop.2", "@types/dockerode": "^3.3.40", "@typescript-eslint/eslint-plugin": "^8.57.1", "@typescript-eslint/parser": "^8.57.1", @@ -99,18 +99,6 @@ "dev": true, "license": "Apache-2.0" }, - "node_modules/@emnapi/core": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.0.tgz", - "integrity": "sha512-0DQ98G9ZQZOxfUcQn1waV2yS8aWdZ6kJMbYCJB3oUBecjWYO1fqJ+a1DRfPF3O5JEkwqwP1A9QEN/9mYm2Yd0w==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/wasi-threads": "1.2.0", - "tslib": "^2.4.0" - } - }, "node_modules/@emnapi/runtime": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.0.tgz", @@ -121,17 +109,6 @@ "tslib": "^2.4.0" } }, - "node_modules/@emnapi/wasi-threads": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.0.tgz", - "integrity": "sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, "node_modules/@esbuild/aix-ppc64": { "version": "0.27.4", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.4.tgz", @@ -1725,19 +1702,6 @@ "node": ">=18" } }, - "node_modules/@napi-rs/wasm-runtime": { - "version": "0.2.12", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", - "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "^1.4.3", - "@emnapi/runtime": "^1.4.3", - "@tybys/wasm-util": "^0.10.0" - } - }, "node_modules/@noble/hashes": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.1.5.tgz", @@ -2551,89 +2515,22 @@ "license": "MIT" }, "node_modules/@stacks/eslint-config": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@stacks/eslint-config/-/eslint-config-2.0.0.tgz", - "integrity": "sha512-GrRiJE7nadre+wCGAkaxCmHGD8tEYOtVW/cjjMdh/H37yl3vGj/lX723MfiXj/YcQDJ1qs/8V9Rx9b4VsFp10Q==", + "version": "3.0.0-develop.2", + "resolved": "https://registry.npmjs.org/@stacks/eslint-config/-/eslint-config-3.0.0-develop.2.tgz", + "integrity": "sha512-vsJGRVAO0RnxvLcUzVHA97wfnD7Po4M3d+vHngjh+sXbiYQgZCmDvCaXdftF9foOxbDMbQ/ORn/fWty9A75reg==", "dev": true, "license": "MIT", "dependencies": { + "@eslint/js": ">= 9", "@stacks/prettier-config": "^0.0.10", - "@typescript-eslint/eslint-plugin": ">=6", - "@typescript-eslint/parser": ">=6", - "eslint": ">=8", - "eslint-config-prettier": "^9.0.0", - "eslint-import-resolver-typescript": ">=3", - "eslint-plugin-import": ">=2", - "eslint-plugin-prettier": ">=5", - "eslint-plugin-unused-imports": ">=3" + "eslint-config-prettier": ">= 9", + "eslint-plugin-prettier": ">= 5", + "typescript-eslint": ">= 8" }, "peerDependencies": { - "eslint": ">=8", - "eslint-plugin-import": ">=2", - "eslint-plugin-prettier": ">=5", - "eslint-plugin-unused-imports": ">=3" + "@eslint/js": ">= 9" } }, - "node_modules/@stacks/eslint-config/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@stacks/eslint-config/node_modules/eslint-import-resolver-typescript": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-4.4.4.tgz", - "integrity": "sha512-1iM2zeBvrYmUNTj2vSC/90JTHDth+dfOfiNKkxApWRsTJYNrc8rOdxxIf5vazX+BiAXTeOT0UvWpGI/7qIWQOw==", - "dev": true, - "license": "ISC", - "dependencies": { - "debug": "^4.4.1", - "eslint-import-context": "^0.1.8", - "get-tsconfig": "^4.10.1", - "is-bun-module": "^2.0.0", - "stable-hash-x": "^0.2.0", - "tinyglobby": "^0.2.14", - "unrs-resolver": "^1.7.11" - }, - "engines": { - "node": "^16.17.0 || >=18.6.0" - }, - "funding": { - "url": "https://opencollective.com/eslint-import-resolver-typescript" - }, - "peerDependencies": { - "eslint": "*", - "eslint-plugin-import": "*", - "eslint-plugin-import-x": "*" - }, - "peerDependenciesMeta": { - "eslint-plugin-import": { - "optional": true - }, - "eslint-plugin-import-x": { - "optional": true - } - } - }, - "node_modules/@stacks/eslint-config/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, "node_modules/@stacks/network": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/@stacks/network/-/network-7.3.1.tgz", @@ -2698,17 +2595,6 @@ "node": ">= 10" } }, - "node_modules/@tybys/wasm-util": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", - "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, "node_modules/@types/caseless": { "version": "0.12.5", "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz", @@ -2821,18 +2707,17 @@ "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.1.tgz", - "integrity": "sha512-Gn3aqnvNl4NGc6x3/Bqk1AOn0thyTU9bqDRhiRnUWezgvr2OnhYCWCgC8zXXRVqBsIL1pSDt7T9nJUe0oM0kDQ==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.2.tgz", + "integrity": "sha512-NZZgp0Fm2IkD+La5PR81sd+g+8oS6JwJje+aRWsDocxHkjyRw0J5L5ZTlN3LI1LlOcGL7ph3eaIUmTXMIjLk0w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.57.1", - "@typescript-eslint/type-utils": "8.57.1", - "@typescript-eslint/utils": "8.57.1", - "@typescript-eslint/visitor-keys": "8.57.1", + "@typescript-eslint/scope-manager": "8.57.2", + "@typescript-eslint/type-utils": "8.57.2", + "@typescript-eslint/utils": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" @@ -2845,23 +2730,23 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.57.1", + "@typescript-eslint/parser": "^8.57.2", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/parser": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.57.1.tgz", - "integrity": "sha512-k4eNDan0EIMTT/dUKc/g+rsJ6wcHYhNPdY19VoX/EOtaAG8DLtKCykhrUnuHPYvinn5jhAPgD2Qw9hXBwrahsw==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.57.2.tgz", + "integrity": "sha512-30ScMRHIAD33JJQkgfGW1t8CURZtjc2JpTrq5n2HFhOefbAhb7ucc7xJwdWcrEtqUIYJ73Nybpsggii6GtAHjA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@typescript-eslint/scope-manager": "8.57.1", - "@typescript-eslint/types": "8.57.1", - "@typescript-eslint/typescript-estree": "8.57.1", - "@typescript-eslint/visitor-keys": "8.57.1", + "@typescript-eslint/scope-manager": "8.57.2", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/typescript-estree": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2", "debug": "^4.4.3" }, "engines": { @@ -2902,14 +2787,14 @@ "license": "MIT" }, "node_modules/@typescript-eslint/project-service": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.57.1.tgz", - "integrity": "sha512-vx1F37BRO1OftsYlmG9xay1TqnjNVlqALymwWVuYTdo18XuKxtBpCj1QlzNIEHlvlB27osvXFWptYiEWsVdYsg==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.57.2.tgz", + "integrity": "sha512-FuH0wipFywXRTHf+bTTjNyuNQQsQC3qh/dYzaM4I4W0jrCqjCVuUh99+xd9KamUfmCGPvbO8NDngo/vsnNVqgw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.57.1", - "@typescript-eslint/types": "^8.57.1", + "@typescript-eslint/tsconfig-utils": "^8.57.2", + "@typescript-eslint/types": "^8.57.2", "debug": "^4.4.3" }, "engines": { @@ -2949,14 +2834,14 @@ "license": "MIT" }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.57.1.tgz", - "integrity": "sha512-hs/QcpCwlwT2L5S+3fT6gp0PabyGk4Q0Rv2doJXA0435/OpnSR3VRgvrp8Xdoc3UAYSg9cyUjTeFXZEPg/3OKg==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.57.2.tgz", + "integrity": "sha512-snZKH+W4WbWkrBqj4gUNRIGb/jipDW3qMqVJ4C9rzdFc+wLwruxk+2a5D+uoFcKPAqyqEnSb4l2ULuZf95eSkw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.57.1", - "@typescript-eslint/visitor-keys": "8.57.1" + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2967,9 +2852,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.57.1.tgz", - "integrity": "sha512-0lgOZB8cl19fHO4eI46YUx2EceQqhgkPSuCGLlGi79L2jwYY1cxeYc1Nae8Aw1xjgW3PKVDLlr3YJ6Bxx8HkWg==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.57.2.tgz", + "integrity": "sha512-3Lm5DSM+DCowsUOJC+YqHHnKEfFh5CoGkj5Z31NQSNF4l5wdOwqGn99wmwN/LImhfY3KJnmordBq/4+VDe2eKw==", "dev": true, "license": "MIT", "engines": { @@ -2984,15 +2869,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.57.1.tgz", - "integrity": "sha512-+Bwwm0ScukFdyoJsh2u6pp4S9ktegF98pYUU0hkphOOqdMB+1sNQhIz8y5E9+4pOioZijrkfNO/HUJVAFFfPKA==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.57.2.tgz", + "integrity": "sha512-Co6ZCShm6kIbAM/s+oYVpKFfW7LBc6FXoPXjTRQ449PPNBY8U0KZXuevz5IFuuUj2H9ss40atTaf9dlGLzbWZg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.57.1", - "@typescript-eslint/typescript-estree": "8.57.1", - "@typescript-eslint/utils": "8.57.1", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/typescript-estree": "8.57.2", + "@typescript-eslint/utils": "8.57.2", "debug": "^4.4.3", "ts-api-utils": "^2.4.0" }, @@ -3034,9 +2919,9 @@ "license": "MIT" }, "node_modules/@typescript-eslint/types": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.57.1.tgz", - "integrity": "sha512-S29BOBPJSFUiblEl6RzPPjJt6w25A6XsBqRVDt53tA/tlL8q7ceQNZHTjPeONt/3S7KRI4quk+yP9jK2WjBiPQ==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.57.2.tgz", + "integrity": "sha512-/iZM6FnM4tnx9csuTxspMW4BOSegshwX5oBDznJ7S4WggL7Vczz5d2W11ecc4vRrQMQHXRSxzrCsyG5EsPPTbA==", "dev": true, "license": "MIT", "engines": { @@ -3048,16 +2933,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.1.tgz", - "integrity": "sha512-ybe2hS9G6pXpqGtPli9Gx9quNV0TWLOmh58ADlmZe9DguLq0tiAKVjirSbtM1szG6+QH6rVXyU6GTLQbWnMY+g==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.2.tgz", + "integrity": "sha512-2MKM+I6g8tJxfSmFKOnHv2t8Sk3T6rF20A1Puk0svLK+uVapDZB/4pfAeB7nE83uAZrU6OxW+HmOd5wHVdXwXA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.57.1", - "@typescript-eslint/tsconfig-utils": "8.57.1", - "@typescript-eslint/types": "8.57.1", - "@typescript-eslint/visitor-keys": "8.57.1", + "@typescript-eslint/project-service": "8.57.2", + "@typescript-eslint/tsconfig-utils": "8.57.2", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -3114,16 +2999,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.57.1.tgz", - "integrity": "sha512-XUNSJ/lEVFttPMMoDVA2r2bwrl8/oPx8cURtczkSEswY5T3AeLmCy+EKWQNdL4u0MmAHOjcWrqJp2cdvgjn8dQ==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.57.2.tgz", + "integrity": "sha512-krRIbvPK1ju1WBKIefiX+bngPs+odIQUtR7kymzPfo1POVw3jlF+nLkmexdSSd4UCbDcQn+wMBATOOmpBbqgKg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.57.1", - "@typescript-eslint/types": "8.57.1", - "@typescript-eslint/typescript-estree": "8.57.1" + "@typescript-eslint/scope-manager": "8.57.2", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/typescript-estree": "8.57.2" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3138,13 +3023,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.1.tgz", - "integrity": "sha512-YWnmJkXbofiz9KbnbbwuA2rpGkFPLbAIetcCNO6mJ8gdhdZ/v7WDXsoGFAJuM6ikUFKTlSQnjWnVO4ux+UzS6A==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.2.tgz", + "integrity": "sha512-zhahknjobV2FiD6Ee9iLbS7OV9zi10rG26odsQdfBO/hjSzUQbkIYgda+iNKK1zNiW2ey+Lf8MU5btN17V3dUw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.57.1", + "@typescript-eslint/types": "8.57.2", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -3168,275 +3053,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/@unrs/resolver-binding-android-arm-eabi": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz", - "integrity": "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@unrs/resolver-binding-android-arm64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz", - "integrity": "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@unrs/resolver-binding-darwin-arm64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz", - "integrity": "sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@unrs/resolver-binding-darwin-x64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz", - "integrity": "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@unrs/resolver-binding-freebsd-x64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz", - "integrity": "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz", - "integrity": "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz", - "integrity": "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz", - "integrity": "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz", - "integrity": "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz", - "integrity": "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz", - "integrity": "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz", - "integrity": "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz", - "integrity": "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-x64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz", - "integrity": "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-x64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz", - "integrity": "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-wasm32-wasi": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz", - "integrity": "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==", - "cpu": [ - "wasm32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@napi-rs/wasm-runtime": "^0.2.11" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz", - "integrity": "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz", - "integrity": "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@unrs/resolver-binding-win32-x64-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz", - "integrity": "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, "node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -4743,31 +4359,6 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/eslint-import-context": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/eslint-import-context/-/eslint-import-context-0.1.9.tgz", - "integrity": "sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-tsconfig": "^4.10.1", - "stable-hash-x": "^0.2.0" - }, - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint-import-context" - }, - "peerDependencies": { - "unrs-resolver": "^1.0.0" - }, - "peerDependenciesMeta": { - "unrs-resolver": { - "optional": true - } - } - }, "node_modules/eslint-import-resolver-node": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", @@ -4824,7 +4415,6 @@ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -5129,22 +4719,6 @@ "node": ">=10" } }, - "node_modules/eslint-plugin-unused-imports": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-4.4.1.tgz", - "integrity": "sha512-oZGYUz1X3sRMGUB+0cZyK2VcvRX5lm/vB56PgNNcU+7ficUCKm66oZWKUubXWnOuPjQ8PvmXtCViXBMONPe7tQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@typescript-eslint/eslint-plugin": "^8.0.0-0 || ^7.0.0 || ^6.0.0 || ^5.0.0", - "eslint": "^10.0.0 || ^9.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "@typescript-eslint/eslint-plugin": { - "optional": true - } - } - }, "node_modules/eslint-scope": { "version": "8.4.0", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", @@ -6426,29 +6000,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-bun-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-2.0.0.tgz", - "integrity": "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.7.1" - } - }, - "node_modules/is-bun-module/node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", @@ -7167,22 +6718,6 @@ "license": "MIT", "optional": true }, - "node_modules/napi-postinstall": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", - "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==", - "dev": true, - "license": "MIT", - "bin": { - "napi-postinstall": "lib/cli.js" - }, - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/napi-postinstall" - } - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -8621,16 +8156,6 @@ "nan": "^2.23.0" } }, - "node_modules/stable-hash-x": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/stable-hash-x/-/stable-hash-x-0.2.0.tgz", - "integrity": "sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/stop-iteration-iterator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", @@ -9166,6 +8691,30 @@ "node": ">=14.17" } }, + "node_modules/typescript-eslint": { + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.57.2.tgz", + "integrity": "sha512-VEPQ0iPgWO/sBaZOU1xo4nuNdODVOajPnTIbog2GKYr31nIlZ0fWPoCQgGfF3ETyBl1vn63F/p50Um9Z4J8O8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.57.2", + "@typescript-eslint/parser": "8.57.2", + "@typescript-eslint/typescript-estree": "8.57.2", + "@typescript-eslint/utils": "8.57.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, "node_modules/unbox-primitive": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", @@ -9200,42 +8749,6 @@ "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", "license": "MIT" }, - "node_modules/unrs-resolver": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz", - "integrity": "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "peer": true, - "dependencies": { - "napi-postinstall": "^0.3.0" - }, - "funding": { - "url": "https://opencollective.com/unrs-resolver" - }, - "optionalDependencies": { - "@unrs/resolver-binding-android-arm-eabi": "1.11.1", - "@unrs/resolver-binding-android-arm64": "1.11.1", - "@unrs/resolver-binding-darwin-arm64": "1.11.1", - "@unrs/resolver-binding-darwin-x64": "1.11.1", - "@unrs/resolver-binding-freebsd-x64": "1.11.1", - "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", - "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", - "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", - "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", - "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", - "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-x64-musl": "1.11.1", - "@unrs/resolver-binding-wasm32-wasi": "1.11.1", - "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", - "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", - "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" - } - }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", diff --git a/package.json b/package.json index 8a3394a..139891a 100644 --- a/package.json +++ b/package.json @@ -23,15 +23,15 @@ "test:stacks-core": "NODE_ENV=test node --import tsx --test --test-global-setup=./tests/setup.ts --test-concurrency=1 ./tests/stacks-core/*.test.ts", "test:token-queue": "NODE_ENV=test node --import tsx --test --test-global-setup=./tests/setup.ts --test-concurrency=1 ./tests/token-queue/*.test.ts", "migrate": "node --import tsx node_modules/.bin/node-pg-migrate -j ts", - "lint:eslint": "eslint . --ext .js,.jsx,.ts,.tsx -f unix", - "lint:prettier": "prettier --check src/**/*.ts tests/**/*.ts migrations/**/*.ts", + "lint:eslint": "eslint .", + "lint:prettier": "prettier --check src/**/*.ts", "generate:openapi": "rimraf ./openapi.yaml && node --import tsx ./util/openapi-generator.ts", "generate:git-info": "rimraf .git-info && node_modules/.bin/api-toolkit-git-info", "generate:client": "openapi-typescript ./openapi.yaml -o ./client/src/generated/schema.d.ts" }, "prettier": "@stacks/prettier-config", "devDependencies": { - "@stacks/eslint-config": "^2.0.0", + "@stacks/eslint-config": "^3.0.0-develop.2", "@types/dockerode": "^3.3.40", "@typescript-eslint/eslint-plugin": "^8.57.1", "@typescript-eslint/parser": "^8.57.1", diff --git a/src/admin-rpc/init.ts b/src/admin-rpc/init.ts index e781d9a..8e17a26 100644 --- a/src/admin-rpc/init.ts +++ b/src/admin-rpc/init.ts @@ -14,7 +14,7 @@ import { getSmartContractSip } from '../token-processor/util/sip-validation.js'; export const AdminApi: FastifyPluginCallback, Server, TypeBoxTypeProvider> = ( fastify, - options, + _options, done ) => { fastify.post( @@ -95,7 +95,7 @@ export const AdminApi: FastifyPluginCallback, Server, TypeB description: 'Retry all failed and invalid jobs', }, }, - async (request, reply) => { + async (_request, reply) => { await fastify.db.core.retryAllFailedJobs(); logger.info(`AdminRPC retrying all failed and invalid jobs`); await reply.code(200).send(); @@ -132,7 +132,7 @@ export const AdminApi: FastifyPluginCallback, Server, TypeB fastify.post( '/job-queue/start', { schema: { description: 'Starts the job queue' } }, - async (request, reply) => { + async (_request, reply) => { const jobQueue = fastify.jobQueue; if (!jobQueue || jobQueue.isRunning()) { await reply.code(422).send({ error: 'Job queue is already running' }); @@ -146,7 +146,7 @@ export const AdminApi: FastifyPluginCallback, Server, TypeB fastify.post( '/job-queue/stop', { schema: { description: 'Stops the job queue' } }, - async (request, reply) => { + async (_request, reply) => { const jobQueue = fastify.jobQueue; if (!jobQueue || !jobQueue.isRunning()) { await reply.code(422).send({ error: 'Job queue is already stopped' }); @@ -218,6 +218,7 @@ export const AdminApi: FastifyPluginCallback, Server, TypeB // We need to convert to `any` first because there's a bug in the Stacks API types // library that causes TS to incorrectly think `tx_index` is not available in the // transaction response. + // eslint-disable-next-line @typescript-eslint/no-explicit-any tx_index: (transaction as any).tx_index, fungible_token_name: abi.fungible_tokens[0]?.name ?? null, non_fungible_token_name: abi.non_fungible_tokens[0]?.name ?? null, diff --git a/src/api/@types/fastify/index.d.ts b/src/api/@types/fastify/index.d.ts index 473b298..07b83d1 100644 --- a/src/api/@types/fastify/index.d.ts +++ b/src/api/@types/fastify/index.d.ts @@ -3,11 +3,11 @@ import { JobQueue } from '../../../token-processor/queue/job-queue.js'; declare module 'fastify' { export interface FastifyInstance< - HttpServer = Server, - HttpRequest = IncomingMessage, - HttpResponse = ServerResponse, - Logger = FastifyLoggerInstance, - TypeProvider = FastifyTypeProviderDefault, + _HttpServer = Server, + _HttpRequest = IncomingMessage, + _HttpResponse = ServerResponse, + _Logger = FastifyLoggerInstance, + _TypeProvider = FastifyTypeProviderDefault, > { db: PgStore; jobQueue?: JobQueue; diff --git a/src/api/init.ts b/src/api/init.ts index cae7308..8a6d6bd 100644 --- a/src/api/init.ts +++ b/src/api/init.ts @@ -16,7 +16,7 @@ import { PINO_LOGGER_CONFIG } from '@stacks/api-toolkit'; export const Api: FastifyPluginAsync, Server, TypeBoxTypeProvider> = async ( fastify, - options + _options ) => { await fastify.register(FtRoutes); await fastify.register(NftRoutes); diff --git a/src/api/routes/ft.ts b/src/api/routes/ft.ts index ac4d233..7434793 100644 --- a/src/api/routes/ft.ts +++ b/src/api/routes/ft.ts @@ -22,7 +22,7 @@ import { parseMetadataLocaleBundle } from '../util/helpers.js'; const IndexRoutes: FastifyPluginCallback, Server, TypeBoxTypeProvider> = ( fastify, - options, + _options, done ) => { fastify.addHook('preHandler', handleChainTipCache); @@ -98,7 +98,7 @@ const IndexRoutes: FastifyPluginCallback, Server, TypeBoxTy const ShowRoutes: FastifyPluginCallback, Server, TypeBoxTypeProvider> = ( fastify, - options, + _options, done ) => { fastify.addHook('preHandler', handleTokenCache); diff --git a/src/api/routes/nft.ts b/src/api/routes/nft.ts index 39f0d08..9f3ca5d 100644 --- a/src/api/routes/nft.ts +++ b/src/api/routes/nft.ts @@ -14,7 +14,7 @@ import { generateTokenErrorResponse, TokenErrorResponseSchema } from '../util/er export const NftRoutes: FastifyPluginCallback, Server, TypeBoxTypeProvider> = ( fastify, - options, + _options, done ) => { fastify.addHook('preHandler', handleTokenCache); diff --git a/src/api/routes/search.ts b/src/api/routes/search.ts index 61f4e74..0a7532f 100644 --- a/src/api/routes/search.ts +++ b/src/api/routes/search.ts @@ -9,7 +9,7 @@ export const SearchRoutes: FastifyPluginCallback< Record, Server, TypeBoxTypeProvider -> = (fastify, options, done) => { +> = (fastify, _options, done) => { fastify.addHook('preHandler', handleBulkTokenCache); fastify.get( '/search', diff --git a/src/api/routes/sft.ts b/src/api/routes/sft.ts index f260719..2925d89 100644 --- a/src/api/routes/sft.ts +++ b/src/api/routes/sft.ts @@ -14,7 +14,7 @@ import { generateTokenErrorResponse, TokenErrorResponseSchema } from '../util/er export const SftRoutes: FastifyPluginCallback, Server, TypeBoxTypeProvider> = ( fastify, - options, + _options, done ) => { fastify.addHook('preHandler', handleTokenCache); diff --git a/src/api/routes/status.ts b/src/api/routes/status.ts index be0642f..8a92504 100644 --- a/src/api/routes/status.ts +++ b/src/api/routes/status.ts @@ -9,7 +9,7 @@ export const StatusRoutes: FastifyPluginCallback< Record, Server, TypeBoxTypeProvider -> = (fastify, options, done) => { +> = (fastify, _options, done) => { fastify.addHook('preHandler', handleChainTipCache); fastify.get( '/', @@ -24,7 +24,7 @@ export const StatusRoutes: FastifyPluginCallback< }, }, }, - async (request, reply) => { + async (_request, reply) => { const result = await fastify.db.sqlTransaction(async sql => { let chain_tip = null; const chainTipResult = await fastify.db.core.getChainTip(sql); diff --git a/src/api/util/cache.ts b/src/api/util/cache.ts index 6d4a897..54d2c50 100644 --- a/src/api/util/cache.ts +++ b/src/api/util/cache.ts @@ -13,10 +13,11 @@ async function handleCache(type: ETagType, request: FastifyRequest, reply: Fasti const ifNoneMatch = parseIfNoneMatchHeader(request.headers['if-none-match']); let etag: string | undefined; switch (type) { - case ETagType.chainTip: + case ETagType.chainTip: { const chainTip = await request.server.db.core.getChainTip(request.server.db.sql); etag = chainTip?.index_block_hash; break; + } case ETagType.token: etag = await getTokenEtag(request); break; @@ -71,7 +72,7 @@ async function getTokenEtag(request: FastifyRequest): Promise { - await db.sqlWriteTransaction(async sql => { + await db.sqlWriteTransaction(async _sql => { const imageUris = await db.getTokenImageUris(contractPrincipal, tokenIds); for (const token of imageUris) { try { diff --git a/src/token-processor/queue/job/job.ts b/src/token-processor/queue/job/job.ts index 55aef94..e8c80d2 100644 --- a/src/token-processor/queue/job/job.ts +++ b/src/token-processor/queue/job/job.ts @@ -2,7 +2,11 @@ import { logger, resolveOrTimeout, stopwatch } from '@stacks/api-toolkit'; import { ENV } from '../../../env.js'; import { PgStore } from '../../../pg/pg-store.js'; import { DbJob, DbJobInvalidReason, DbJobStatus } from '../../../pg/types.js'; -import { getUserErrorInvalidReason, TooManyRequestsHttpError, UserError } from '../../util/errors.js'; +import { + getUserErrorInvalidReason, + TooManyRequestsHttpError, + UserError, +} from '../../util/errors.js'; import { RetryableJobError } from '../errors.js'; import { getJobQueueProcessingMode, JobQueueProcessingMode } from '../helpers.js'; import { StacksNetworkName } from '@stacks/network'; diff --git a/src/token-processor/queue/job/process-smart-contract-job.ts b/src/token-processor/queue/job/process-smart-contract-job.ts index 7a32a11..efad70d 100644 --- a/src/token-processor/queue/job/process-smart-contract-job.ts +++ b/src/token-processor/queue/job/process-smart-contract-job.ts @@ -21,7 +21,7 @@ export class ProcessSmartContractJob extends Job { } this.contract = contract; switch (contract.sip) { - case DbSipNumber.sip009: + case DbSipNumber.sip009: { // NFT contracts expose their token count in `get-last-token-id`. We'll get that number // through a contract call and then queue that same number of tokens for metadata retrieval. const tokenCount = await this.getNftContractLastTokenId(contract); @@ -29,7 +29,7 @@ export class ProcessSmartContractJob extends Job { await this.enqueueTokens(contract, tokenCount); } break; - + } case DbSipNumber.sip010: // FT contracts only have 1 token to process. Do that immediately. await this.enqueueTokens(contract, 1n); diff --git a/src/token-processor/queue/job/process-token-job.ts b/src/token-processor/queue/job/process-token-job.ts index 533119c..eb28da4 100644 --- a/src/token-processor/queue/job/process-token-job.ts +++ b/src/token-processor/queue/job/process-token-job.ts @@ -32,7 +32,7 @@ export class ProcessTokenJob extends Job { if (!tokenId) { return; } - const [token, contract] = await this.db.sqlTransaction(async sql => { + const [token, contract] = await this.db.sqlTransaction(async _sql => { const token = await this.db.getToken({ id: tokenId }); if (!token) { logger.warn(`ProcessTokenJob token not found id=${tokenId}`); diff --git a/src/token-processor/queue/job/update-token-supply-job.ts b/src/token-processor/queue/job/update-token-supply-job.ts index 2b1bb38..4129d86 100644 --- a/src/token-processor/queue/job/update-token-supply-job.ts +++ b/src/token-processor/queue/job/update-token-supply-job.ts @@ -20,7 +20,7 @@ export class UpdateTokenSupplyJob extends Job { if (!tokenId) { return; } - const [token, contract] = await this.db.sqlTransaction(async sql => { + const [token, contract] = await this.db.sqlTransaction(async _sql => { const token = await this.db.getToken({ id: tokenId }); if (!token) { logger.warn(`UpdateTokenSupplyJob token not found id=${tokenId}`); diff --git a/src/token-processor/stacks-node/stacks-node-rpc-client.ts b/src/token-processor/stacks-node/stacks-node-rpc-client.ts index 939df5d..84ba97f 100644 --- a/src/token-processor/stacks-node/stacks-node-rpc-client.ts +++ b/src/token-processor/stacks-node/stacks-node-rpc-client.ts @@ -69,7 +69,7 @@ export class StacksNodeRpcClient { const uintVal = this.checkAndParseUintCV(clarityValue); try { return BigInt(uintVal.value.toString()); - } catch (error) { + } catch (_error) { throw new SmartContractClarityError(`Invalid uint value '${uintVal.value}'`); } } @@ -88,7 +88,7 @@ export class StacksNodeRpcClient { } try { return JSON.parse(text) as ClarityAbi; - } catch (error) { + } catch (_error) { throw new StacksNodeJsonParseError(`JSON parse error ${url}: ${text}`); } } catch (error) { @@ -122,7 +122,7 @@ export class StacksNodeRpcClient { } try { return JSON.parse(text) as ReadOnlyContractCallResponse; - } catch (error) { + } catch (_error) { throw new StacksNodeJsonParseError(`JSON parse error ${url}: ${text}`); } } catch (error) { diff --git a/src/token-processor/util/metadata-helpers.ts b/src/token-processor/util/metadata-helpers.ts index 13116f0..93fe75c 100644 --- a/src/token-processor/util/metadata-helpers.ts +++ b/src/token-processor/util/metadata-helpers.ts @@ -298,7 +298,9 @@ export async function fetchMetadata( throw new TooManyRequestsHttpError(httpUrl, error); } else if ( error instanceof TypeError && - ((error as UndiciCauseTypeError).cause as any).toString().includes('ECONNRESET') + ((error as UndiciCauseTypeError).cause as { toString(): string }) + .toString() + .includes('ECONNRESET') ) { throw new MetadataHttpError(`Server connection interrupted`, error); } @@ -411,7 +413,7 @@ export function getFetchableMetadataUrl(uri: string): FetchableMetadataUrl { } return result; - } catch (error) { + } catch (_error) { throw new MetadataParseError(`Invalid uri: ${uri}`); } } @@ -454,7 +456,7 @@ export function parseDataUrl( parsed.base64 = !!parts[parts.length - 2]; parsed.data = parts[parts.length - 1] || ''; return parsed; - } catch (e) { + } catch (_e) { return false; } } diff --git a/src/token-processor/util/sip-validation.ts b/src/token-processor/util/sip-validation.ts index 9032601..76d6444 100644 --- a/src/token-processor/util/sip-validation.ts +++ b/src/token-processor/util/sip-validation.ts @@ -224,7 +224,7 @@ export function getSmartContractSip(abi: ClarityAbi): DbSipNumber | undefined { if (abi.fungible_tokens.length > 0 && abiContains(abi, FtTraitFunctions)) { return DbSipNumber.sip010; } - } catch (error) { + } catch (_error) { // Not a token contract. } } @@ -249,10 +249,11 @@ function findFunction(fun: ClarityAbiFunction, functionList: ClarityAbiFunction[ function stringFromValue(value: codec.ClarityValue): string { switch (value.type_id) { - case codec.ClarityTypeID.Buffer: + case codec.ClarityTypeID.Buffer: { const parts = value.buffer.substring(2).match(/.{1,2}/g) ?? []; const arr = Uint8Array.from(parts.map(byte => parseInt(byte, 16))); return Buffer.from(arr).toString('utf8'); + } case codec.ClarityTypeID.StringAscii: case codec.ClarityTypeID.StringUtf8: return value.data; @@ -381,7 +382,7 @@ export function getContractLogMetadataUpdateNotification( update_mode: updateMode, ttl: ttl, }; - } catch (error) { + } catch (_error) { return; } } @@ -411,7 +412,7 @@ export function getContractLogSftMintEvent( amount: BigInt(amount), recipient: recipient, }; - } catch (error) { + } catch (_error) { return; } } From 4a0109add590e290f9265b6ceedce44540213eaf Mon Sep 17 00:00:00 2001 From: Rafa Cardenas <253999660+rafa-stacks@users.noreply.github.com> Date: Thu, 26 Mar 2026 16:24:17 -0600 Subject: [PATCH 11/12] missing env --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 757a4f4..1adaea2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -70,6 +70,7 @@ jobs: PGDATABASE: postgres STACKS_NODE_RPC_HOST: 127.0.0.1 STACKS_NODE_RPC_PORT: 24440 + SNP_REDIS_URL: redis://localhost:6379 steps: - uses: actions/checkout@v6 with: From 2d5c75bae7acfcad9adf5f105f6ae259843bdd21 Mon Sep 17 00:00:00 2001 From: Rafa Cardenas <253999660+rafa-stacks@users.noreply.github.com> Date: Thu, 26 Mar 2026 16:29:46 -0600 Subject: [PATCH 12/12] chore(release): 2.2.2 [skip ci] --- client/package-lock.json | 4 +- client/package.json | 2 +- client/src/generated/schema.d.ts | 20 ++-- openapi.yaml | 180 +++++++++++++++---------------- package-lock.json | 4 +- package.json | 2 +- 6 files changed, 110 insertions(+), 102 deletions(-) diff --git a/client/package-lock.json b/client/package-lock.json index 4a04d45..337e9f8 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -1,12 +1,12 @@ { "name": "@stacks/token-metadata-api-client", - "version": "2.2.1", + "version": "2.2.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@stacks/token-metadata-api-client", - "version": "2.2.1", + "version": "2.2.2", "license": "GPL-3.0", "dependencies": { "openapi-fetch": "^0.12.2" diff --git a/client/package.json b/client/package.json index 38f9c55..4f97b20 100644 --- a/client/package.json +++ b/client/package.json @@ -1,6 +1,6 @@ { "name": "@stacks/token-metadata-api-client", - "version": "2.2.1", + "version": "2.2.2", "description": "Client for the Stacks Token Metadata API", "author": "Stacks Labs", "keywords": [ diff --git a/client/src/generated/schema.d.ts b/client/src/generated/schema.d.ts index 4fed000..44a29aa 100644 --- a/client/src/generated/schema.d.ts +++ b/client/src/generated/schema.d.ts @@ -379,10 +379,12 @@ export interface operations { uri: string; /** @example en */ default: string; - /** @example [ + /** + * @example [ * "en", * "jp" - * ] */ + * ] + */ locales: string[]; }; }; @@ -520,10 +522,12 @@ export interface operations { uri: string; /** @example en */ default: string; - /** @example [ + /** + * @example [ * "en", * "jp" - * ] */ + * ] + */ locales: string[]; }; }; @@ -665,10 +669,12 @@ export interface operations { uri: string; /** @example en */ default: string; - /** @example [ + /** + * @example [ * "en", * "jp" - * ] */ + * ] + */ locales: string[]; }; }; @@ -820,7 +826,9 @@ export interface operations { /** @example ready */ status: string; chain_tip: { + /** @example 163541 */ block_height: number; + /** @example 0x1234567890abcdef1234567890abcdef1234567890abcdef */ index_block_hash: string; } | null; }; diff --git a/openapi.yaml b/openapi.yaml index 18db827..3d68b15 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -5,7 +5,7 @@ info: API](https://docs.hiro.so/token-metadata-api). Service that indexes metadata for every SIP-009, SIP-010, and SIP-013 Token in the Stacks blockchain and exposes it via REST API endpoints. - version: 2.2.1 + version: v2.2.1 components: schemas: {} paths: @@ -28,9 +28,9 @@ paths: name: symbol required: false - schema: + pattern: ^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]{28,41} title: Stacks Address type: string - pattern: ^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]{28,41} example: SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9 in: query name: address @@ -93,6 +93,11 @@ paths: schema: title: Paginated Ft Basic Metadata Response type: object + required: + - limit + - offset + - total + - results properties: limit: type: integer @@ -108,6 +113,11 @@ paths: items: title: Ft Basic Metadata Response type: object + required: + - tx_id + - sender_address + - asset_identifier + - contract_principal properties: name: type: string @@ -159,16 +169,6 @@ paths: contract_principal: type: string example: SP1H1733V5MZ3SZ9XRW9FKYGEZT0JDGEB8Y634C7R.miamicoin-token-v2 - required: - - tx_id - - sender_address - - asset_identifier - - contract_principal - required: - - limit - - offset - - total - - results /metadata/v1/ft/{principal}: get: operationId: getFtMetadata @@ -190,9 +190,9 @@ paths: required: false description: Metadata localization to retrieve - schema: + pattern: ^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]{28,41}\.[a-zA-Z]([a-zA-Z0-9]|[-_]){0,39}$ title: Fungible Token Contract Principal type: string - pattern: ^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]{28,41}\.[a-zA-Z]([a-zA-Z0-9]|[-_]){0,39}$ example: SP32XCD69XPS3GKDEXAQ29PJRDSD5AR643GNEEBXZ.fari-token in: path name: principal @@ -206,6 +206,10 @@ paths: schema: title: Ft Metadata Response type: object + required: + - tx_id + - sender_address + - asset_identifier properties: name: description: Token name @@ -266,6 +270,8 @@ paths: metadata: title: Metadata type: object + required: + - sip properties: sip: type: integer @@ -298,6 +304,9 @@ paths: items: title: Metadata Attribute type: object + required: + - trait_type + - value properties: trait_type: type: string @@ -308,9 +317,6 @@ paths: value: title: Metadata Value example: value - required: - - trait_type - - value properties: title: Metadata Properties type: object @@ -324,6 +330,10 @@ paths: localization: title: Metadata Localization type: object + required: + - uri + - default + - locales properties: uri: format: uri @@ -339,16 +349,6 @@ paths: example: - en - jp - required: - - uri - - default - - locales - required: - - sip - required: - - tx_id - - sender_address - - asset_identifier "404": description: Default Response content: @@ -358,22 +358,22 @@ paths: anyOf: - title: Token Not Found Response type: object + required: + - error properties: error: type: string enum: - Token not found - required: - - error - title: Contract Not Found Response type: object + required: + - error properties: error: type: string enum: - Contract not found - required: - - error "422": description: Default Response content: @@ -383,23 +383,26 @@ paths: anyOf: - title: Token Metadata Fetch In Progress Response type: object + required: + - error properties: error: type: string enum: - Token metadata fetch in progress - required: - - error - title: Locale Not Found Response type: object + required: + - error properties: error: type: string enum: - Locale not found + - type: object required: - error - - type: object + - message properties: error: type: string @@ -407,9 +410,6 @@ paths: - Token error message: type: string - required: - - error - - message /metadata/v1/nft/{principal}/{token_id}: get: operationId: getNftMetadata @@ -431,9 +431,9 @@ paths: required: false description: Metadata localization to retrieve - schema: + pattern: ^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]{28,41}\.[a-zA-Z]([a-zA-Z0-9]|[-_]){0,39}$ title: Non-Fungible Token Contract Principal type: string - pattern: ^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]{28,41}\.[a-zA-Z]([a-zA-Z0-9]|[-_]){0,39}$ example: SP497E7RX3233ATBS2AB9G4WTHB63X5PBSP5VGAQ.boomboxes-cycle-12 in: path name: principal @@ -464,6 +464,8 @@ paths: metadata: title: Metadata type: object + required: + - sip properties: sip: type: integer @@ -496,6 +498,9 @@ paths: items: title: Metadata Attribute type: object + required: + - trait_type + - value properties: trait_type: type: string @@ -506,9 +511,6 @@ paths: value: title: Metadata Value example: value - required: - - trait_type - - value properties: title: Metadata Properties type: object @@ -522,6 +524,10 @@ paths: localization: title: Metadata Localization type: object + required: + - uri + - default + - locales properties: uri: format: uri @@ -537,12 +543,6 @@ paths: example: - en - jp - required: - - uri - - default - - locales - required: - - sip "404": description: Default Response content: @@ -552,22 +552,22 @@ paths: anyOf: - title: Token Not Found Response type: object + required: + - error properties: error: type: string enum: - Token not found - required: - - error - title: Contract Not Found Response type: object + required: + - error properties: error: type: string enum: - Contract not found - required: - - error "422": description: Default Response content: @@ -577,23 +577,26 @@ paths: anyOf: - title: Token Metadata Fetch In Progress Response type: object + required: + - error properties: error: type: string enum: - Token metadata fetch in progress - required: - - error - title: Locale Not Found Response type: object + required: + - error properties: error: type: string enum: - Locale not found + - type: object required: - error - - type: object + - message properties: error: type: string @@ -601,9 +604,6 @@ paths: - Token error message: type: string - required: - - error - - message /metadata/v1/sft/{principal}/{token_id}: get: operationId: getSftMetadata @@ -625,9 +625,9 @@ paths: required: false description: Metadata localization to retrieve - schema: + pattern: ^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]{28,41}\.[a-zA-Z]([a-zA-Z0-9]|[-_]){0,39}$ title: Semi-Fungible Token Contract Principal type: string - pattern: ^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]{28,41}\.[a-zA-Z]([a-zA-Z0-9]|[-_]){0,39}$ example: SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9.key-alex-autoalex-v1 in: path name: principal @@ -664,6 +664,8 @@ paths: metadata: title: Metadata type: object + required: + - sip properties: sip: type: integer @@ -696,6 +698,9 @@ paths: items: title: Metadata Attribute type: object + required: + - trait_type + - value properties: trait_type: type: string @@ -706,9 +711,6 @@ paths: value: title: Metadata Value example: value - required: - - trait_type - - value properties: title: Metadata Properties type: object @@ -722,6 +724,10 @@ paths: localization: title: Metadata Localization type: object + required: + - uri + - default + - locales properties: uri: format: uri @@ -737,12 +743,6 @@ paths: example: - en - jp - required: - - uri - - default - - locales - required: - - sip "404": description: Default Response content: @@ -752,22 +752,22 @@ paths: anyOf: - title: Token Not Found Response type: object + required: + - error properties: error: type: string enum: - Token not found - required: - - error - title: Contract Not Found Response type: object + required: + - error properties: error: type: string enum: - Contract not found - required: - - error "422": description: Default Response content: @@ -777,23 +777,26 @@ paths: anyOf: - title: Token Metadata Fetch In Progress Response type: object + required: + - error properties: error: type: string enum: - Token metadata fetch in progress - required: - - error - title: Locale Not Found Response type: object + required: + - error properties: error: type: string enum: - Locale not found + - type: object required: - error - - type: object + - message properties: error: type: string @@ -801,9 +804,6 @@ paths: - Token error message: type: string - required: - - error - - message /metadata/v1/search: get: operationId: searchTokens @@ -819,13 +819,13 @@ paths: title: Contract Identifiers type: array items: + pattern: ^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]{28,41}\.[a-zA-Z]([a-zA-Z0-9]|[-_]){0,39}(:\d+)?$ title: Contract Identifier description: "Format: PRINCIPAL or PRINCIPAL:TOKEN_NUMBER" examples: - SP32XCD69XPS3GKDEXAQ29PJRDSD5AR643GNEEBXZ.fari-token - SP497E7RX3233ATBS2AB9G4WTHB63X5PBSP5VGAQ.boomboxes-cycle-12:120 type: string - pattern: ^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]{28,41}\.[a-zA-Z]([a-zA-Z0-9]|[-_]){0,39}(:\d+)?$ in: query name: contract required: true @@ -854,6 +854,12 @@ paths: items: title: Search Result Item type: object + required: + - contract_id + - token_number + - token_type + - tx_id + - sender_address properties: contract_id: description: Contract principal @@ -912,12 +918,6 @@ paths: description: Deployer address type: string example: SPZA22A4D15RKH5G8XDGQ7BPC20Q5JNMH0VQKSR6 - required: - - contract_id - - token_number - - token_type - - tx_id - - sender_address /metadata/v1/: get: operationId: getApiStatus @@ -933,6 +933,10 @@ paths: schema: title: Api Status Response type: object + required: + - server_version + - status + - chain_tip properties: server_version: type: string @@ -943,6 +947,9 @@ paths: chain_tip: anyOf: - type: object + required: + - block_height + - index_block_hash properties: block_height: examples: @@ -953,14 +960,7 @@ paths: - "0x1234567890abcdef1234567890abcdef1234567890ab\ cdef" type: string - required: - - block_height - - index_block_hash - type: "null" - required: - - server_version - - status - - chain_tip servers: - url: https://api.hiro.so/ description: mainnet diff --git a/package-lock.json b/package-lock.json index 705ab0e..9002ab4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@stx-labs/token-metadata-api", - "version": "2.2.1", + "version": "2.2.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@stx-labs/token-metadata-api", - "version": "2.2.1", + "version": "2.2.2", "license": "GPL-3.0", "dependencies": { "@fastify/cors": "^11.2.0", diff --git a/package.json b/package.json index 139891a..7777a83 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@stx-labs/token-metadata-api", "description": "A microservice that indexes metadata for all Fungible, Non-Fungible, and Semi-Fungible Tokens in the Stacks blockchain and exposes it via JSON REST API endpoints", - "version": "2.2.1", + "version": "2.2.2", "repository": { "type": "git", "url": "https://github.com/stx-labs/token-metadata-api.git"