Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ module.exports = {
// An array of file extensions your modules use

moduleFileExtensions: ['js', 'json', 'ts'],
// extensionsToTreatAsEsm: ['.ts'],

// A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module
// moduleNameMapper: {},
Expand All @@ -95,6 +96,7 @@ module.exports = {
'^@subql/types-core/(.*)$': '<rootDir>/packages/types-core/src/$1',
'^@subql/utils$': '<rootDir>/packages/utils/src/',
'^@subql/utils/(.*)$': '<rootDir>/packages/utils/src/$1',
'^(\\.{1,2}/.*)\\.js$': '$1', // For ESM packages (CLI)
},

// An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader
Expand Down Expand Up @@ -191,10 +193,20 @@ module.exports = {

// A map from regular expressions to paths to transformers
transform: {
'^.+\\.(ts|tsx)?$': [
// ESM package (CLI)
'^.+\\.(t|j)sx?$': [
'ts-jest',
{
tsconfig: 'tsconfig.test.json',
useESM: true,
tsconfig: '<rootDir>/packages/cli/tsconfig.json',
},
],
// Fallback for everything else (CJS)
// Important: this must come last because regex order matters
'^(?!.*packages/cli).*\\.(t|j)sx?$': [
'ts-jest',
{
useESM: false,
},
],
},
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-sort-destructure-keys": "^1.4.0",
"husky": "^7.0.4",
"jest": "^29.5.0",
"jest": "^30.1.3",
"lint-staged": "^15.2.7",
"prettier": "^3.3.3",
"pretty-quick": "^4.2.2",
"ts-jest": "^29.2.4",
"ts-jest": "^29.4.4",
"ts-loader": "^9.5.1",
"ts-node": "^10.9.2",
"tsconfig-paths": "^4.2.0",
Expand Down
14 changes: 10 additions & 4 deletions packages/cli/bin/run
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
#!/usr/bin/env node

const pjson = require('../package.json');
const updateNotifier = require('update-notifier');
const chalk = require('chalk');
const semver = require('semver');
import {readFileSync} from 'fs';
import {fileURLToPath} from 'url';
import {dirname, join} from 'path';
import updateNotifier from 'update-notifier';
import chalk from 'chalk';
import semver from 'semver';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const pjson = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf8'));

const notifier = updateNotifier({pkg: pjson, updateCheckInterval: 0});

Expand Down
2 changes: 2 additions & 0 deletions packages/cli/graphql-codegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const config: CodegenConfig = {
overwrite: true,
schema: 'https://gateway.subquery.network/query/QmQqqmwwaBben8ncfHo3DMnDxyWFk5QcEdTmbevzKj7DBd',
documents: 'src/controller/network/queries/*.graphql',
emitLegacyCommonJSImports: false,
config: {
namingConvention: {
enumValues: 'keep',
Expand All @@ -32,6 +33,7 @@ const config: CodegenConfig = {
preset: 'near-operation-file',
config: {
importOperationTypesFrom: 'Types',
gqlImport: 'graphql-tag#gql',
},
presetConfig: {
folder: '../__graphql__/network',
Expand Down
11 changes: 6 additions & 5 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"description": "CLI for SubQuery",
"version": "6.3.0",
"author": "SubQuery Pte Ltd.",
"type": "module",
"bin": {
"subql": "./bin/run"
},
Expand All @@ -19,7 +20,7 @@
"@walletconnect/sign-client": "^2.17.2",
"@walletconnect/types": "^2.17.2",
"@walletconnect/utils": "^2.17.2",
"chalk": "^4",
"chalk": "^5.3.0",
"dotenv": "^16.4.5",
"ejs": "^3.1.10",
"fuzzy": "^0.1.3",
Expand All @@ -28,20 +29,20 @@
"graphql-request": "^7.2.0",
"json5": "^2.2.3",
"jsonc-parser": "^3.3.1",
"ora": "^5.4.1",
"ora": "^8.1.1",
"qrcode-terminal": "^0.12.0",
"resolve-from": "^5.0.0",
"rimraf": "^5.0.10",
"semver": "^7.6.3",
"simple-git": "^3.25.0",
"simple-git": "^3.28.0",
"siwe": "^3.0.0",
"terser-webpack-plugin": "^5.3.14",
"ts-loader": "^9.5.1",
"ts-node": "^10.9.2",
"tsconfig-paths-webpack-plugin": "^4.2.0",
"tslib": "^2.6.3",
"typescript": "^5.7.3",
"update-notifier": "^5.1.0",
"update-notifier": "^7.0.0",
"webpack": "^5.101.3",
"webpack-merge": "^6.0.1",
"websocket": "^1.0.35",
Expand Down Expand Up @@ -117,7 +118,7 @@
"version": "oclif readme && git add README.md",
"format": "prettier --write \"src/**/*.ts\"",
"changelog:release": "echo \"Updating changelog $npm_package_version\" && npx chan release $npm_package_version --git-url \"https://github.com/subquery/subql\" --release-prefix=\"cli/\"",
"codegen:graphql": "graphql-codegen --config graphql-codegen.ts",
"codegen:graphql": "graphql-codegen-esm --config graphql-codegen.ts",
"codegen:chs": "swagger-typescript-api generate -p chs-swagger.yml -o src/controller/network/consumer-host --api-class-name NetworkConsumerHostServiceApi -n consumer-host-service-api.ts",
"codegen": "yarn codegen:graphql && yarn codegen:chs"
},
Expand Down
6 changes: 3 additions & 3 deletions packages/cli/src/adapters/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
import {stripVTControlCharacters} from 'node:util';
import {confirm, input, search, checkbox} from '@inquirer/prompts';
import {McpServer} from '@modelcontextprotocol/sdk/server/mcp.js';
import {RequestHandlerExtra} from '@modelcontextprotocol/sdk/shared/protocol';
import {CallToolResult, ElicitRequest, ServerNotification, ServerRequest} from '@modelcontextprotocol/sdk/types';
import {RequestHandlerExtra} from '@modelcontextprotocol/sdk/shared/protocol.js';
import {CallToolResult, ElicitRequest, ServerNotification, ServerRequest} from '@modelcontextprotocol/sdk/types.js';
import {Args, Command, Flags} from '@oclif/core';
import {Flag, Arg} from '@oclif/core/lib/interfaces';
import type {Flag, Arg} from '@oclif/core/interfaces';
import fuzzy from 'fuzzy';
import {z, ZodTypeAny, ZodObject, ZodOptional, ZodDefault} from 'zod';

Expand Down Expand Up @@ -36,8 +36,8 @@
T extends z.ZodArray<infer U> ? ZodToPrimitive<U>[] : ZodToPrimitive<T>;

// Check if optional
type HasDefault<T extends ZodTypeAny> = T extends ZodDefault<any> ? true : false;

Check warning on line 39 in packages/cli/src/adapters/utils.ts

View workflow job for this annotation

GitHub Actions / code-style

Unexpected any. Specify a different type
type IsOptional<T extends ZodTypeAny> = T extends ZodOptional<any> ? true : false;

Check warning on line 40 in packages/cli/src/adapters/utils.ts

View workflow job for this annotation

GitHub Actions / code-style

Unexpected any. Specify a different type

// Combine to determine final flag type
type FlagFromZod<T extends ZodTypeAny> =
Expand All @@ -63,7 +63,7 @@
[K in keyof Shape]: ArgFromZod<Shape[K]>;
};

type UnwrapInfo = {type: ZodTypeAny; default: any; array: boolean; optional: boolean};

Check warning on line 66 in packages/cli/src/adapters/utils.ts

View workflow job for this annotation

GitHub Actions / code-style

Unexpected any. Specify a different type

// Unrwap recursive type information to get the primitive and other information
function unwrap(
Expand Down Expand Up @@ -96,7 +96,7 @@

// Runtime impl
export function zodToFlags<Shape extends Record<string, ZodTypeAny>>(schema: ZodObject<Shape>): FlagsFromSchema<Shape> {
const flags: Record<string, Flag<any>> = {};

Check warning on line 99 in packages/cli/src/adapters/utils.ts

View workflow job for this annotation

GitHub Actions / code-style

Unexpected any. Specify a different type

for (const [key, def] of Object.entries(schema.shape)) {
const description = def.description ?? '';
Expand All @@ -108,14 +108,14 @@
description,
required: !optional,
default: defaultValue,
multiple: array as any, // Gets around a type issue

Check warning on line 111 in packages/cli/src/adapters/utils.ts

View workflow job for this annotation

GitHub Actions / code-style

Unexpected any. Specify a different type
});
} else if (type instanceof z.ZodNumber) {
flags[key] = Flags.integer({
description,
required: !optional,
default: defaultValue,
multiple: array as any, // Gets around a type issue

Check warning on line 118 in packages/cli/src/adapters/utils.ts

View workflow job for this annotation

GitHub Actions / code-style

Unexpected any. Specify a different type
});
} else if (type instanceof z.ZodBoolean) {
flags[key] = Flags.boolean({
Expand All @@ -128,7 +128,7 @@
required: !optional,
default: defaultValue,
options: type.options,
multiple: array as any, // Gets around a type issue

Check warning on line 131 in packages/cli/src/adapters/utils.ts

View workflow job for this annotation

GitHub Actions / code-style

Unexpected any. Specify a different type
});
} else {
throw new Error(`Unsupported Zod type for flag: ${key}`);
Expand All @@ -139,7 +139,7 @@
}

export function zodToArgs<Shape extends Record<string, ZodTypeAny>>(schema: ZodObject<Shape>): ArgsFromSchema<Shape> {
const args: Record<string, Arg<any>> = {};

Check warning on line 142 in packages/cli/src/adapters/utils.ts

View workflow job for this annotation

GitHub Actions / code-style

Unexpected any. Specify a different type

for (const [key, def] of Object.entries(schema.shape)) {
const description = def.description ?? '';
Expand Down Expand Up @@ -201,7 +201,7 @@
info: command.log.bind(command),
warn: command.warn.bind(command),
error: command.error.bind(command),
debug: (command as any).debug.bind(command),

Check warning on line 204 in packages/cli/src/adapters/utils.ts

View workflow job for this annotation

GitHub Actions / code-style

Unexpected any. Specify a different type
};
}

Expand Down Expand Up @@ -302,7 +302,7 @@
throw new Error(`Input for ${message} is required`);
}
if (type === 'string') {
return input as any; // TODO fix type, string doesn't work for some reason

Check warning on line 305 in packages/cli/src/adapters/utils.ts

View workflow job for this annotation

GitHub Actions / code-style

Unexpected any. Specify a different type
}
if (type === 'boolean') {
return input === 'true';
Expand Down
8 changes: 4 additions & 4 deletions packages/cli/src/commands/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
import assert from 'node:assert';
import {existsSync, lstatSync} from 'node:fs';
import path from 'node:path';
import {McpServer, RegisteredTool} from '@modelcontextprotocol/sdk/server/mcp';
import {McpServer, RegisteredTool} from '@modelcontextprotocol/sdk/server/mcp.js';
import {Command} from '@oclif/core';
import {glob} from 'glob';
import {z} from 'zod';
import {Logger, zodToFlags, mcpLogger, commandLogger, getMCPWorkingDirectory, zodToArgs} from '../adapters/utils';
import {getBuildEntries, runBundle} from '../controller/build-controller';
import {resolveToAbsolutePath, buildTsManifest} from '../utils';
import {Logger, zodToFlags, mcpLogger, commandLogger, getMCPWorkingDirectory, zodToArgs} from '../adapters/utils.js';
import {getBuildEntries, runBundle} from '../controller/build-controller.js';
import {resolveToAbsolutePath, buildTsManifest} from '../utils/index.js';

export const buildInputs = z.object({
location: z
Expand Down
18 changes: 9 additions & 9 deletions packages/cli/src/commands/codegen/import-abi.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors
// SPDX-License-Identifier: GPL-3.0

import fs from 'fs';
import path from 'path';
import {McpServer, RegisteredTool} from '@modelcontextprotocol/sdk/server/mcp';
import fs from 'node:fs';
import path from 'node:path';
import {McpServer, RegisteredTool} from '@modelcontextprotocol/sdk/server/mcp.js';
import {Command} from '@oclif/core';
import {
NETWORK_FAMILY,
Expand All @@ -28,7 +28,7 @@ import {
withStructuredResponse,
zodToArgs,
zodToFlags,
} from '../../adapters/utils';
} from '../../adapters/utils.js';
import {
filterObjectsByStateMutability,
generateHandlers,
Expand All @@ -42,10 +42,10 @@ import {
saveAbiToFile,
prepareUserInput,
UserInput,
} from '../../controller/generate-controller';
import {loadDependency} from '../../modulars';
import {extractFromTs, buildManifestFromLocation, getTsManifest} from '../../utils';
import {fetchContractDeployHeight, tryFetchAbiFromExplorer} from '../../utils/etherscan';
} from '../../controller/generate-controller.js';
import {loadDependency} from '../../modulars/index.js';
import {fetchContractDeployHeight, tryFetchAbiFromExplorer} from '../../utils/etherscan.js';
import {extractFromTs, buildManifestFromLocation, getTsManifest} from '../../utils/index.js';

const generateInputs = z.object({
location: z.string({description: 'The path to the project, this can be a directory or a project manifest file.'}),
Expand Down Expand Up @@ -159,7 +159,7 @@ async function generateAdapter(
}
}

const ethModule = loadDependency(NETWORK_FAMILY.ethereum, args.location);
const ethModule = await loadDependency(NETWORK_FAMILY.ethereum, args.location);
const abiName = ethModule.parseContractPath(args.abiPath).name;

if (fs.existsSync(path.join(root, 'src/mappings/', `${abiName}Handlers.ts`))) {
Expand Down
8 changes: 4 additions & 4 deletions packages/cli/src/commands/codegen/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
import assert from 'node:assert';
import {existsSync} from 'node:fs';
import path from 'node:path';
import {McpServer, RegisteredTool} from '@modelcontextprotocol/sdk/server/mcp';
import {McpServer, RegisteredTool} from '@modelcontextprotocol/sdk/server/mcp.js';
import {Command} from '@oclif/core';
import {getProjectRootAndManifest, getSchemaPath} from '@subql/common';
import {z} from 'zod';
import {commandLogger, getMCPWorkingDirectory, Logger, mcpLogger, zodToArgs} from '../../adapters/utils';
import {codegen} from '../../controller/codegen-controller';
import {resolveToAbsolutePath, buildManifestFromLocation, getTsManifest} from '../../utils';
import {commandLogger, getMCPWorkingDirectory, Logger, mcpLogger, zodToArgs} from '../../adapters/utils.js';
import {codegen} from '../../controller/codegen-controller.js';
import {resolveToAbsolutePath, buildManifestFromLocation, getTsManifest} from '../../utils/index.js';

const codegenInputs = z.object({
location: z.string({description: 'The project directory or path to project manifest.'}).optional(),
Expand Down
10 changes: 5 additions & 5 deletions packages/cli/src/commands/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import {stripVTControlCharacters} from 'node:util';
import {McpServer, RegisteredTool} from '@modelcontextprotocol/sdk/server/mcp';
import {McpServer, RegisteredTool} from '@modelcontextprotocol/sdk/server/mcp.js';
import {Command} from '@oclif/core';
import {ProjectNetworkConfig} from '@subql/types-core';
import chalk from 'chalk';
Expand All @@ -22,7 +22,7 @@ import {
Prompt,
zodToArgs,
zodToFlags,
} from '../adapters/utils';
} from '../adapters/utils.js';
import {
installDependencies,
cloneProjectTemplate,
Expand All @@ -32,9 +32,9 @@ import {
fetchExampleProjects,
ExampleProjectInterface,
Template,
} from '../controller/init-controller';
import {ProjectSpecBase} from '../types';
import {resolveToAbsolutePath} from '../utils';
} from '../controller/init-controller.js';
import {ProjectSpecBase} from '../types.js';
import {resolveToAbsolutePath} from '../utils/index.js';

const initInputs = z.object({
name: z.string({description: 'The name of the project to create'}),
Expand Down
67 changes: 36 additions & 31 deletions packages/cli/src/commands/mcp.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,46 @@
// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors
// SPDX-License-Identifier: GPL-3.0

import {readFileSync} from 'fs';
import {dirname, join} from 'path';
import {fileURLToPath} from 'url';
import {McpServer} from '@modelcontextprotocol/sdk/server/mcp.js';
import {StdioServerTransport} from '@modelcontextprotocol/sdk/server/stdio.js';
import {Command} from '@oclif/core';
import {MCPToolOptions} from '../adapters/utils';
import {fetchNetworks} from '../controller/init-controller';
import {registerBuildMCPTool} from './build';
import {registerCodegenMCPTool} from './codegen';
import {registerImportAbiMCPTool} from './codegen/import-abi';
import {registerInitMCPTool} from './init';
import {registerMigrateSubgraphMCPTool} from './migrate';
import {registerMultichainAddMCPTool} from './multi-chain/add';
import {registerAddDeploymentBoostMCPTool} from './network/add-deployment-boost';
import {registerConnectWalletMCPTool} from './network/connect-wallet';
import {registerCreateNetworkApiKeyMCPTool} from './network/create-api-key';
import {registerCreateNetworkDeploymentMCPTool} from './network/create-deployment';
import {registerCreateNetworkFlexPlanMCPTool} from './network/create-flex-plan';
import {registerCreateNetworkProjectMCPTool} from './network/create-project';
import {registerDisconnectWalletMCPTool} from './network/disconnect-wallet';
import {registerListAccountBoostsMCPTool} from './network/list-account-boosts';
import {registerListDeploymentBoostsMCPTool} from './network/list-deployment-boosts';
import {registerListDeploymentIndexersMCPTool} from './network/list-deployment-indexers';
import {registerListNetworkDeploymentsMCPTool} from './network/list-deployments';
import {registerListFlexPlansMCPTool} from './network/list-flex-plans';
import {registerListNetworkProjectsMCPTool} from './network/list-projects';
import {registerRemoveDeploymentBoostMCPTool} from './network/remove-deployment-boost';
import {registerStopNetworkFlexPlanMCPTool} from './network/stop-flex-plan';
import {registerSwapDeploymentBoostMCPTool} from './network/swap-deployment-boost';
import {registerCreateDeploymentMCPTool} from './onfinality/create-deployment';
import {registerCreateMultichainDeploymentMCPTool} from './onfinality/create-multichain-deployment';
import {registerCreateProjectMCPTool} from './onfinality/create-project';
import {registerDeleteProjectMCPTool} from './onfinality/delete-project';
import {registerPromoteDeploymentMCPTool} from './onfinality/promote-deployment';
import {registerPublishMCPTool} from './publish';
import {MCPToolOptions} from '../adapters/utils.js';
import {fetchNetworks} from '../controller/init-controller.js';
import {registerBuildMCPTool} from './build.js';
import {registerImportAbiMCPTool} from './codegen/import-abi.js';
import {registerCodegenMCPTool} from './codegen/index.js';
import {registerInitMCPTool} from './init.js';
import {registerMigrateSubgraphMCPTool} from './migrate.js';
import {registerMultichainAddMCPTool} from './multi-chain/add.js';
import {registerAddDeploymentBoostMCPTool} from './network/add-deployment-boost.js';
import {registerConnectWalletMCPTool} from './network/connect-wallet.js';
import {registerCreateNetworkApiKeyMCPTool} from './network/create-api-key.js';
import {registerCreateNetworkDeploymentMCPTool} from './network/create-deployment.js';
import {registerCreateNetworkFlexPlanMCPTool} from './network/create-flex-plan.js';
import {registerCreateNetworkProjectMCPTool} from './network/create-project.js';
import {registerDisconnectWalletMCPTool} from './network/disconnect-wallet.js';
import {registerListAccountBoostsMCPTool} from './network/list-account-boosts.js';
import {registerListDeploymentBoostsMCPTool} from './network/list-deployment-boosts.js';
import {registerListDeploymentIndexersMCPTool} from './network/list-deployment-indexers.js';
import {registerListNetworkDeploymentsMCPTool} from './network/list-deployments.js';
import {registerListFlexPlansMCPTool} from './network/list-flex-plans.js';
import {registerListNetworkProjectsMCPTool} from './network/list-projects.js';
import {registerRemoveDeploymentBoostMCPTool} from './network/remove-deployment-boost.js';
import {registerStopNetworkFlexPlanMCPTool} from './network/stop-flex-plan.js';
import {registerSwapDeploymentBoostMCPTool} from './network/swap-deployment-boost.js';
import {registerCreateDeploymentMCPTool} from './onfinality/create-deployment.js';
import {registerCreateMultichainDeploymentMCPTool} from './onfinality/create-multichain-deployment.js';
import {registerCreateProjectMCPTool} from './onfinality/create-project.js';
import {registerDeleteProjectMCPTool} from './onfinality/delete-project.js';
import {registerPromoteDeploymentMCPTool} from './onfinality/promote-deployment.js';
import {registerPublishMCPTool} from './publish.js';

const pjson = require('../../package.json');
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const pjson = JSON.parse(readFileSync(join(__dirname, '../../package.json'), 'utf8'));

export default class MCP extends Command {
static description = 'Runs an MCP (Model Context Protocol) server over stdio';
Expand Down
8 changes: 4 additions & 4 deletions packages/cli/src/commands/migrate.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// Copyright 2020-2025 SubQuery Pte Ltd authors & contributors
// SPDX-License-Identifier: GPL-3.0

import fs from 'fs';
import path from 'path';
import fs from 'node:fs';
import path from 'node:path';
import {makeTempDir} from '@subql/common';
import {rimraf} from 'rimraf';
import {DEFAULT_SUBQL_MANIFEST} from '../constants';
import Migrate from './migrate';
import {DEFAULT_SUBQL_MANIFEST} from '../constants.js';
import Migrate from './migrate.js';

jest.setTimeout(300_000); // 300s
describe('Integration test - Migrate', () => {
Expand Down
Loading
Loading