@hithink-tech/hithink-finance-cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -0
- package/LICENSE +21 -0
- package/README.md +161 -0
- package/SECURITY.md +3 -0
- package/dist/application/config.d.ts +44 -0
- package/dist/application/config.js +111 -0
- package/dist/application/ports/auth-provider.d.ts +23 -0
- package/dist/application/ports/auth-provider.js +2 -0
- package/dist/application/source-policy.d.ts +13 -0
- package/dist/application/source-policy.js +31 -0
- package/dist/application/use-cases/data-clean.d.ts +2 -0
- package/dist/application/use-cases/data-clean.js +18 -0
- package/dist/application/use-cases/data-init.d.ts +4 -0
- package/dist/application/use-cases/data-init.js +9 -0
- package/dist/application/use-cases/data-remove.d.ts +2 -0
- package/dist/application/use-cases/data-remove.js +27 -0
- package/dist/application/use-cases/data-repair.d.ts +5 -0
- package/dist/application/use-cases/data-repair.js +5 -0
- package/dist/application/use-cases/data-sync.d.ts +25 -0
- package/dist/application/use-cases/data-sync.js +55 -0
- package/dist/application/use-cases/local-query.d.ts +4 -0
- package/dist/application/use-cases/local-query.js +88 -0
- package/dist/application/use-cases/market-history.d.ts +8 -0
- package/dist/application/use-cases/market-history.js +16 -0
- package/dist/application/use-cases/market-panel.d.ts +3 -0
- package/dist/application/use-cases/market-panel.js +5 -0
- package/dist/application/use-cases/remote-query.d.ts +4 -0
- package/dist/application/use-cases/remote-query.js +66 -0
- package/dist/cli/context.d.ts +17 -0
- package/dist/cli/context.js +52 -0
- package/dist/cli/i18n.d.ts +23 -0
- package/dist/cli/i18n.js +150 -0
- package/dist/cli/main.d.ts +3 -0
- package/dist/cli/main.js +80 -0
- package/dist/cli/program.d.ts +20 -0
- package/dist/cli/program.js +111 -0
- package/dist/commands/auth/index.d.ts +10 -0
- package/dist/commands/auth/index.js +131 -0
- package/dist/commands/config/index.d.ts +13 -0
- package/dist/commands/config/index.js +26 -0
- package/dist/commands/data/index.d.ts +10 -0
- package/dist/commands/data/index.js +185 -0
- package/dist/commands/db/index.d.ts +4 -0
- package/dist/commands/db/index.js +72 -0
- package/dist/commands/financials/index.d.ts +5 -0
- package/dist/commands/financials/index.js +6 -0
- package/dist/commands/index/index.d.ts +5 -0
- package/dist/commands/index/index.js +6 -0
- package/dist/commands/market/index.d.ts +5 -0
- package/dist/commands/market/index.js +6 -0
- package/dist/commands/market/local.d.ts +4 -0
- package/dist/commands/market/local.js +97 -0
- package/dist/commands/remote.d.ts +11 -0
- package/dist/commands/remote.js +195 -0
- package/dist/commands/skills/index.d.ts +4 -0
- package/dist/commands/skills/index.js +43 -0
- package/dist/commands/special/index.d.ts +5 -0
- package/dist/commands/special/index.js +6 -0
- package/dist/commands/symbol/index.d.ts +5 -0
- package/dist/commands/symbol/index.js +6 -0
- package/dist/commands/system/capabilities.d.ts +4 -0
- package/dist/commands/system/capabilities.js +24 -0
- package/dist/commands/system/doctor.d.ts +4 -0
- package/dist/commands/system/doctor.js +15 -0
- package/dist/commands/system/schema.d.ts +4 -0
- package/dist/commands/system/schema.js +47 -0
- package/dist/commands/system/uninstall.d.ts +11 -0
- package/dist/commands/system/uninstall.js +68 -0
- package/dist/commands/system/update.d.ts +11 -0
- package/dist/commands/system/update.js +72 -0
- package/dist/contracts/envelope.d.ts +37 -0
- package/dist/contracts/envelope.js +36 -0
- package/dist/contracts/errors.d.ts +23 -0
- package/dist/contracts/errors.js +33 -0
- package/dist/contracts/local-capabilities.d.ts +13 -0
- package/dist/contracts/local-capabilities.js +37 -0
- package/dist/contracts/registry.d.ts +9 -0
- package/dist/contracts/registry.js +4 -0
- package/dist/contracts/remote-capabilities.d.ts +24 -0
- package/dist/contracts/remote-capabilities.js +667 -0
- package/dist/domains/financials/types.d.ts +6 -0
- package/dist/domains/financials/types.js +2 -0
- package/dist/domains/index/types.d.ts +6 -0
- package/dist/domains/index/types.js +2 -0
- package/dist/domains/market/types.d.ts +6 -0
- package/dist/domains/market/types.js +2 -0
- package/dist/domains/special/types.d.ts +5 -0
- package/dist/domains/special/types.js +2 -0
- package/dist/domains/symbol/types.d.ts +6 -0
- package/dist/domains/symbol/types.js +2 -0
- package/dist/infrastructure/credentials/api-key-provider.d.ts +14 -0
- package/dist/infrastructure/credentials/api-key-provider.js +102 -0
- package/dist/infrastructure/credentials/keyring.d.ts +15 -0
- package/dist/infrastructure/credentials/keyring.js +21 -0
- package/dist/infrastructure/credentials/redact.d.ts +3 -0
- package/dist/infrastructure/credentials/redact.js +26 -0
- package/dist/infrastructure/duckdb/connection.d.ts +8 -0
- package/dist/infrastructure/duckdb/connection.js +18 -0
- package/dist/infrastructure/duckdb/dump-client.d.ts +20 -0
- package/dist/infrastructure/duckdb/dump-client.js +66 -0
- package/dist/infrastructure/duckdb/factors.d.ts +3 -0
- package/dist/infrastructure/duckdb/factors.js +83 -0
- package/dist/infrastructure/duckdb/importer.d.ts +11 -0
- package/dist/infrastructure/duckdb/importer.js +105 -0
- package/dist/infrastructure/duckdb/migrations.d.ts +17 -0
- package/dist/infrastructure/duckdb/migrations.js +92 -0
- package/dist/infrastructure/duckdb/quality.d.ts +12 -0
- package/dist/infrastructure/duckdb/quality.js +56 -0
- package/dist/infrastructure/duckdb/schema.d.ts +4 -0
- package/dist/infrastructure/duckdb/schema.js +14 -0
- package/dist/infrastructure/filesystem/atomic-file.d.ts +2 -0
- package/dist/infrastructure/filesystem/atomic-file.js +38 -0
- package/dist/infrastructure/filesystem/platform-paths.d.ts +15 -0
- package/dist/infrastructure/filesystem/platform-paths.js +42 -0
- package/dist/infrastructure/filesystem/process-lock.d.ts +6 -0
- package/dist/infrastructure/filesystem/process-lock.js +56 -0
- package/dist/infrastructure/filesystem/stdin.d.ts +5 -0
- package/dist/infrastructure/filesystem/stdin.js +9 -0
- package/dist/infrastructure/fuyao/client.d.ts +31 -0
- package/dist/infrastructure/fuyao/client.js +145 -0
- package/dist/infrastructure/fuyao/envelope.d.ts +9 -0
- package/dist/infrastructure/fuyao/envelope.js +8 -0
- package/dist/infrastructure/fuyao/pagination.d.ts +16 -0
- package/dist/infrastructure/fuyao/pagination.js +44 -0
- package/dist/infrastructure/fuyao/retry.d.ts +5 -0
- package/dist/infrastructure/fuyao/retry.js +18 -0
- package/dist/infrastructure/fuyao/windowing.d.ts +8 -0
- package/dist/infrastructure/fuyao/windowing.js +25 -0
- package/dist/infrastructure/skills/drift.d.ts +3 -0
- package/dist/infrastructure/skills/drift.js +8 -0
- package/dist/infrastructure/skills/installer.d.ts +13 -0
- package/dist/infrastructure/skills/installer.js +48 -0
- package/dist/infrastructure/skills/manifest.d.ts +11 -0
- package/dist/infrastructure/skills/manifest.js +62 -0
- package/dist/infrastructure/updater/cache.d.ts +15 -0
- package/dist/infrastructure/updater/cache.js +76 -0
- package/dist/infrastructure/updater/check.d.ts +13 -0
- package/dist/infrastructure/updater/check.js +51 -0
- package/dist/infrastructure/updater/install.d.ts +4 -0
- package/dist/infrastructure/updater/install.js +39 -0
- package/dist/output/json.d.ts +3 -0
- package/dist/output/json.js +16 -0
- package/dist/output/renderer.d.ts +4 -0
- package/dist/output/renderer.js +47 -0
- package/dist/output/table.d.ts +2 -0
- package/dist/output/table.js +31 -0
- package/migrations/001-initial.sql +95 -0
- package/migrations/manifest.json +12 -0
- package/package.json +66 -0
- package/schemas/capabilities.json +290 -0
- package/schemas/command-envelope.schema.json +12 -0
- package/scripts/postinstall.mjs +27 -0
- package/scripts/update-check.mjs +23 -0
- package/skills/hithink-finance-data/SKILL.md +74 -0
- package/skills/hithink-finance-data/references/data-clean.md +33 -0
- package/skills/hithink-finance-data/references/data-init.md +35 -0
- package/skills/hithink-finance-data/references/data-migrate.md +33 -0
- package/skills/hithink-finance-data/references/data-remove.md +33 -0
- package/skills/hithink-finance-data/references/data-repair.md +33 -0
- package/skills/hithink-finance-data/references/data-status.md +33 -0
- package/skills/hithink-finance-data/references/data-sync.md +34 -0
- package/skills/hithink-finance-data/references/data-validate.md +33 -0
- package/skills/hithink-finance-data/references/db-describe.md +33 -0
- package/skills/hithink-finance-data/references/db-export.md +33 -0
- package/skills/hithink-finance-data/references/db-query.md +33 -0
- package/skills/hithink-finance-financials/SKILL.md +59 -0
- package/skills/hithink-finance-financials/references/financials-balance-sheet.md +40 -0
- package/skills/hithink-finance-financials/references/financials-cash-flow.md +40 -0
- package/skills/hithink-finance-financials/references/financials-income.md +40 -0
- package/skills/hithink-finance-financials/references/financials-indicators.md +37 -0
- package/skills/hithink-finance-index/SKILL.md +59 -0
- package/skills/hithink-finance-index/references/index-catalog.md +36 -0
- package/skills/hithink-finance-index/references/index-constituents.md +36 -0
- package/skills/hithink-finance-index/references/index-history.md +38 -0
- package/skills/hithink-finance-index/references/index-snapshot.md +37 -0
- package/skills/hithink-finance-market/SKILL.md +63 -0
- package/skills/hithink-finance-market/references/market-adjustment-factors.md +33 -0
- package/skills/hithink-finance-market/references/market-calendar.md +35 -0
- package/skills/hithink-finance-market/references/market-corporate-actions.md +38 -0
- package/skills/hithink-finance-market/references/market-history.md +39 -0
- package/skills/hithink-finance-market/references/market-panel.md +33 -0
- package/skills/hithink-finance-market/references/market-snapshot.md +39 -0
- package/skills/hithink-finance-research/SKILL.md +58 -0
- package/skills/hithink-finance-research/references/research-workflow.md +34 -0
- package/skills/hithink-finance-shared/SKILL.md +55 -0
- package/skills/hithink-finance-shared/references/auth-and-config.md +31 -0
- package/skills/hithink-finance-shared/references/global-rules.md +21 -0
- package/skills/hithink-finance-shared/references/lifecycle.md +23 -0
- package/skills/hithink-finance-shared/references/skills-management.md +22 -0
- package/skills/hithink-finance-special-data/SKILL.md +68 -0
- package/skills/hithink-finance-special-data/references/special-anomaly-list.md +36 -0
- package/skills/hithink-finance-special-data/references/special-anomaly-stock.md +37 -0
- package/skills/hithink-finance-special-data/references/special-dragon-tiger.md +37 -0
- package/skills/hithink-finance-special-data/references/special-hot-stock-history.md +36 -0
- package/skills/hithink-finance-special-data/references/special-hot-stock-trend.md +38 -0
- package/skills/hithink-finance-special-data/references/special-hot-stock.md +36 -0
- package/skills/hithink-finance-special-data/references/special-limit-up-ladder.md +35 -0
- package/skills/hithink-finance-special-data/references/special-limit-up-pool.md +40 -0
- package/skills/hithink-finance-special-data/references/special-skyrocket.md +36 -0
- package/skills/hithink-finance-symbol/SKILL.md +56 -0
- package/skills/hithink-finance-symbol/references/symbol-list.md +39 -0
- package/skills/hithink-finance-symbol/references/symbol-search.md +39 -0
- package/skills/manifest.json +55 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { Command, CommanderError, Option } from 'commander';
|
|
2
|
+
import { localizeText, translate } from './i18n.js';
|
|
3
|
+
import { successEnvelope } from '../contracts/envelope.js';
|
|
4
|
+
import { CliError } from '../contracts/errors.js';
|
|
5
|
+
import { renderResult } from '../output/renderer.js';
|
|
6
|
+
import { registerAuthCommands } from '../commands/auth/index.js';
|
|
7
|
+
import { registerSymbolCommands } from '../commands/symbol/index.js';
|
|
8
|
+
import { registerMarketCommands } from '../commands/market/index.js';
|
|
9
|
+
import { registerSpecialCommands } from '../commands/special/index.js';
|
|
10
|
+
import { registerFinancialCommands } from '../commands/financials/index.js';
|
|
11
|
+
import { registerIndexCommands } from '../commands/index/index.js';
|
|
12
|
+
import { registerCapabilitiesCommand } from '../commands/system/capabilities.js';
|
|
13
|
+
import { registerSchemaCommand } from '../commands/system/schema.js';
|
|
14
|
+
import { registerSkillsCommands } from '../commands/skills/index.js';
|
|
15
|
+
import { registerUpdateCommand } from '../commands/system/update.js';
|
|
16
|
+
import { registerUninstallCommand } from '../commands/system/uninstall.js';
|
|
17
|
+
import { registerDoctorCommand } from '../commands/system/doctor.js';
|
|
18
|
+
import { registerDataCommands } from '../commands/data/index.js';
|
|
19
|
+
import { registerDbCommands } from '../commands/db/index.js';
|
|
20
|
+
import { registerLocalMarketCommands } from '../commands/market/local.js';
|
|
21
|
+
import { registerConfigCommands } from '../commands/config/index.js';
|
|
22
|
+
export function createProgram(metadata, context, dependencies) {
|
|
23
|
+
const program = new Command();
|
|
24
|
+
program
|
|
25
|
+
.name('hithink-finance')
|
|
26
|
+
.description(translate(context.language, 'rootDescription'))
|
|
27
|
+
.addOption(new Option('--format <format>', localizeText(context.language, 'output format'))
|
|
28
|
+
.choices(['auto', 'json', 'ndjson', 'csv', 'table'])
|
|
29
|
+
.default(dependencies.resolvedConfig.format))
|
|
30
|
+
.addOption(new Option('--lang <lang>', localizeText(context.language, 'human interface language')).choices(['zh-CN', 'en']))
|
|
31
|
+
.option('--profile <name>', localizeText(context.language, 'configuration and credential profile'), dependencies.resolvedConfig.profile)
|
|
32
|
+
.option('--config <path>', localizeText(context.language, 'explicit JSON configuration file'))
|
|
33
|
+
.option('--api-key <value>', localizeText(context.language, 'API key for this process'))
|
|
34
|
+
.option('--api-key-stdin', localizeText(context.language, 'read an API key from stdin'))
|
|
35
|
+
.option('--no-input', localizeText(context.language, 'disable interactive input'))
|
|
36
|
+
.option('--yes', localizeText(context.language, 'confirm non-interactive operations'))
|
|
37
|
+
.option('--source <source>', localizeText(context.language, 'data source: auto, local, or remote'), 'auto')
|
|
38
|
+
.option('--db <path>', localizeText(context.language, 'local DuckDB path'))
|
|
39
|
+
.option('--request-id <id>', localizeText(context.language, 'caller-supplied correlation ID'))
|
|
40
|
+
.option('--debug', localizeText(context.language, 'enable diagnostic details on stderr'))
|
|
41
|
+
.option('--no-color', localizeText(context.language, 'disable terminal colors'))
|
|
42
|
+
.showHelpAfterError(false)
|
|
43
|
+
.exitOverride()
|
|
44
|
+
.configureOutput({
|
|
45
|
+
writeOut: (value) => context.stdout.write(value),
|
|
46
|
+
writeErr: () => undefined,
|
|
47
|
+
});
|
|
48
|
+
program.hook('preAction', (_root, action) => {
|
|
49
|
+
const options = action.optsWithGlobals();
|
|
50
|
+
if (options.apiKey !== undefined && options.apiKeyStdin === true)
|
|
51
|
+
throw new CliError({
|
|
52
|
+
code: 'CLI_CONFLICTING_ARGUMENTS',
|
|
53
|
+
category: 'validation',
|
|
54
|
+
message: '--api-key and --api-key-stdin cannot be used together.',
|
|
55
|
+
hint: 'Choose exactly one API key input method.',
|
|
56
|
+
retryable: false,
|
|
57
|
+
exitCode: 2,
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
const versionDescriptor = {
|
|
61
|
+
id: 'version',
|
|
62
|
+
path: ['version'],
|
|
63
|
+
describe: (language) => translate(language, 'versionDescription'),
|
|
64
|
+
register(root) {
|
|
65
|
+
root
|
|
66
|
+
.command('version')
|
|
67
|
+
.description(this.describe(context.language))
|
|
68
|
+
.action(async () => {
|
|
69
|
+
await renderResult(successEnvelope('version', { package: metadata.name, version: metadata.version, node: process.version }, { requestId: context.requestId }), context);
|
|
70
|
+
});
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
versionDescriptor.register(program);
|
|
74
|
+
registerAuthCommands(program, context, metadata, dependencies.authProvider);
|
|
75
|
+
registerConfigCommands(program, context, dependencies.resolvedConfig);
|
|
76
|
+
const remoteDependencies = {
|
|
77
|
+
authProvider: dependencies.authProvider,
|
|
78
|
+
baseUrl: dependencies.fuyaoBaseUrl,
|
|
79
|
+
defaultDbPath: dependencies.platformPaths.defaultDbPath,
|
|
80
|
+
};
|
|
81
|
+
registerSymbolCommands(program, context, remoteDependencies);
|
|
82
|
+
registerMarketCommands(program, context, remoteDependencies);
|
|
83
|
+
registerSpecialCommands(program, context, remoteDependencies);
|
|
84
|
+
registerFinancialCommands(program, context, remoteDependencies);
|
|
85
|
+
registerIndexCommands(program, context, remoteDependencies);
|
|
86
|
+
registerCapabilitiesCommand(program, context);
|
|
87
|
+
registerSchemaCommand(program, context);
|
|
88
|
+
registerSkillsCommands(program, context, dependencies.packageRoot);
|
|
89
|
+
registerUpdateCommand(program, context, metadata, dependencies);
|
|
90
|
+
registerUninstallCommand(program, context, metadata, dependencies);
|
|
91
|
+
registerDoctorCommand(program, context);
|
|
92
|
+
registerDataCommands(program, context, dependencies.platformPaths, {
|
|
93
|
+
...remoteDependencies,
|
|
94
|
+
cliVersion: metadata.version,
|
|
95
|
+
});
|
|
96
|
+
registerDbCommands(program, context, dependencies.platformPaths.defaultDbPath);
|
|
97
|
+
registerLocalMarketCommands(program, context, dependencies.platformPaths.defaultDbPath);
|
|
98
|
+
return program;
|
|
99
|
+
}
|
|
100
|
+
export function commanderError(error, language) {
|
|
101
|
+
const isUnknownCommand = error.code === 'commander.unknownCommand';
|
|
102
|
+
return new CliError({
|
|
103
|
+
code: isUnknownCommand ? 'CLI_UNKNOWN_COMMAND' : 'CLI_BAD_ARGUMENT',
|
|
104
|
+
category: 'validation',
|
|
105
|
+
message: isUnknownCommand ? translate(language, 'unknownCommand') : error.message,
|
|
106
|
+
hint: translate(language, 'unknownCommandHint'),
|
|
107
|
+
retryable: false,
|
|
108
|
+
exitCode: 2,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=program.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Readable } from 'node:stream';
|
|
2
|
+
import type { Command } from 'commander';
|
|
3
|
+
import type { CliContext } from '../../cli/context.js';
|
|
4
|
+
import type { PackageMetadata } from '../../cli/program.js';
|
|
5
|
+
import type { ApiKeyAuthProvider } from '../../infrastructure/credentials/api-key-provider.js';
|
|
6
|
+
export declare function readHiddenApiKey(context: CliContext, input?: Readable & {
|
|
7
|
+
isTTY?: boolean;
|
|
8
|
+
}): Promise<string>;
|
|
9
|
+
export declare function registerAuthCommands(program: Command, context: CliContext, metadata: PackageMetadata, provider: ApiKeyAuthProvider): void;
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { createInterface } from 'node:readline/promises';
|
|
2
|
+
import { Writable } from 'node:stream';
|
|
3
|
+
import { localizeText, translate } from '../../cli/i18n.js';
|
|
4
|
+
import { successEnvelope } from '../../contracts/envelope.js';
|
|
5
|
+
import { CliError } from '../../contracts/errors.js';
|
|
6
|
+
import { renderResult } from '../../output/renderer.js';
|
|
7
|
+
import { readStdin } from '../../infrastructure/filesystem/stdin.js';
|
|
8
|
+
const apiKeyHint = 'Get an API key at https://fuyao.aicubes.cn/admin, then run `hithink-finance auth login` and paste it into the hidden prompt. In non-interactive shells, use `hithink-finance auth login --api-key-stdin`.';
|
|
9
|
+
export async function readHiddenApiKey(context, input = process.stdin) {
|
|
10
|
+
if (input.isTTY !== true) {
|
|
11
|
+
throw new CliError({
|
|
12
|
+
code: 'CLI_MISSING_ARGUMENT',
|
|
13
|
+
category: 'validation',
|
|
14
|
+
message: 'An API key is required in non-interactive mode.',
|
|
15
|
+
hint: apiKeyHint,
|
|
16
|
+
retryable: false,
|
|
17
|
+
exitCode: 2,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
const muted = new Writable({
|
|
21
|
+
write(_chunk, _encoding, callback) {
|
|
22
|
+
callback();
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
const readline = createInterface({ input, output: muted, terminal: true });
|
|
26
|
+
context.stderr.write(context.language === 'zh-CN'
|
|
27
|
+
? [
|
|
28
|
+
'欢迎使用同花顺金融数据 CLI',
|
|
29
|
+
'',
|
|
30
|
+
'请前往同花顺金融数据服务官网,登录同花顺账号,创建您的 API Key,复制到当前终端后按 Enter 完成登录。',
|
|
31
|
+
'',
|
|
32
|
+
'官网 API Key 获取地址:https://fuyao.aicubes.cn/admin',
|
|
33
|
+
'',
|
|
34
|
+
'下方为隐藏输入模式,粘贴或输入时不会显示在终端中;输入完成后按 Enter。',
|
|
35
|
+
'',
|
|
36
|
+
'在此处填写您的 API Key:',
|
|
37
|
+
].join('\n')
|
|
38
|
+
: [
|
|
39
|
+
'Welcome to HiThink Finance CLI',
|
|
40
|
+
'',
|
|
41
|
+
'Visit the HiThink Finance Data Service website, sign in with your HiThink account, create an API key, paste it into this terminal, then press Enter to finish login.',
|
|
42
|
+
'',
|
|
43
|
+
'API key page: https://fuyao.aicubes.cn/admin',
|
|
44
|
+
'',
|
|
45
|
+
'The prompt below uses hidden input mode. Typed or pasted characters will not be shown; press Enter when done.',
|
|
46
|
+
'',
|
|
47
|
+
'Paste your API key here:',
|
|
48
|
+
].join('\n'));
|
|
49
|
+
try {
|
|
50
|
+
return await readline.question('');
|
|
51
|
+
}
|
|
52
|
+
finally {
|
|
53
|
+
readline.close();
|
|
54
|
+
context.stderr.write('\n');
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
export function registerAuthCommands(program, context, metadata, provider) {
|
|
58
|
+
const auth = program
|
|
59
|
+
.command('auth')
|
|
60
|
+
.description(localizeText(context.language, 'Manage API key authentication'));
|
|
61
|
+
const login = auth
|
|
62
|
+
.command('login')
|
|
63
|
+
.description(localizeText(context.language, 'Store an API key in the system credential store'));
|
|
64
|
+
login.action(async () => {
|
|
65
|
+
const options = login.optsWithGlobals();
|
|
66
|
+
if (options.apiKey !== undefined && options.apiKeyStdin === true) {
|
|
67
|
+
throw new CliError({
|
|
68
|
+
code: 'CLI_CONFLICTING_ARGUMENTS',
|
|
69
|
+
category: 'validation',
|
|
70
|
+
message: '--api-key and --api-key-stdin cannot be used together.',
|
|
71
|
+
hint: 'Choose exactly one API key input method.',
|
|
72
|
+
retryable: false,
|
|
73
|
+
exitCode: 2,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
if (options.apiKey === undefined && options.apiKeyStdin !== true && options.input === false) {
|
|
77
|
+
throw new CliError({
|
|
78
|
+
code: 'CLI_MISSING_ARGUMENT',
|
|
79
|
+
category: 'validation',
|
|
80
|
+
message: 'An API key is required when --no-input is set.',
|
|
81
|
+
hint: apiKeyHint,
|
|
82
|
+
retryable: false,
|
|
83
|
+
exitCode: 2,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
const profile = options.profile ?? 'default';
|
|
87
|
+
const existing = await provider.status(profile);
|
|
88
|
+
if (existing.configured) {
|
|
89
|
+
await renderResult(successEnvelope('auth.login', {
|
|
90
|
+
...existing,
|
|
91
|
+
alreadyLoggedIn: true,
|
|
92
|
+
nextStep: translate(context.language, 'authLoginAlreadyConfigured'),
|
|
93
|
+
}, { requestId: context.requestId }), context);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
let apiKey;
|
|
97
|
+
if (options.apiKey !== undefined) {
|
|
98
|
+
context.stderr.write('Warning: --api-key may be visible in shell history and process listings. Prefer --api-key-stdin.\n');
|
|
99
|
+
apiKey = options.apiKey;
|
|
100
|
+
}
|
|
101
|
+
else if (options.apiKeyStdin === true) {
|
|
102
|
+
apiKey = await readStdin(process.stdin, { stripFinalNewlines: true });
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
apiKey = await readHiddenApiKey(context);
|
|
106
|
+
}
|
|
107
|
+
const status = await provider.login({ profile, apiKey });
|
|
108
|
+
await renderResult(successEnvelope('auth.login', status, { requestId: context.requestId }), context);
|
|
109
|
+
});
|
|
110
|
+
const status = auth
|
|
111
|
+
.command('status')
|
|
112
|
+
.description(localizeText(context.language, 'Show whether an API key is configured'));
|
|
113
|
+
status.action(async () => {
|
|
114
|
+
const options = status.optsWithGlobals();
|
|
115
|
+
const result = await provider.status(options.profile ?? 'default');
|
|
116
|
+
await renderResult(successEnvelope('auth.status', result, { requestId: context.requestId }), context);
|
|
117
|
+
});
|
|
118
|
+
const logout = auth
|
|
119
|
+
.command('logout')
|
|
120
|
+
.description(localizeText(context.language, 'Delete API key credentials'))
|
|
121
|
+
.option('--all', localizeText(context.language, 'delete every hithink-finance profile'));
|
|
122
|
+
logout.action(async () => {
|
|
123
|
+
const options = logout.optsWithGlobals();
|
|
124
|
+
if (options.all === true)
|
|
125
|
+
await provider.logoutAll();
|
|
126
|
+
else
|
|
127
|
+
await provider.logout(options.profile ?? 'default');
|
|
128
|
+
await renderResult(successEnvelope('auth.logout', { removed: true, all: options.all === true, cliVersion: metadata.version }, { requestId: context.requestId }), context);
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ResolvedConfig } from '../../application/config.js';
|
|
2
|
+
import type { Command } from 'commander';
|
|
3
|
+
import type { CliContext } from '../../cli/context.js';
|
|
4
|
+
export interface PublicConfig {
|
|
5
|
+
dbPath: string;
|
|
6
|
+
profile: string;
|
|
7
|
+
format: ResolvedConfig['format'];
|
|
8
|
+
language?: ResolvedConfig['language'];
|
|
9
|
+
updateCheck: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function publicConfig(config: ResolvedConfig): PublicConfig;
|
|
12
|
+
export declare function registerConfigCommands(program: Command, context: CliContext, config: ResolvedConfig): void;
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { localizeText } from '../../cli/i18n.js';
|
|
2
|
+
import { successEnvelope } from '../../contracts/envelope.js';
|
|
3
|
+
import { renderResult } from '../../output/renderer.js';
|
|
4
|
+
export function publicConfig(config) {
|
|
5
|
+
const result = {
|
|
6
|
+
dbPath: config.dbPath,
|
|
7
|
+
profile: config.profile,
|
|
8
|
+
format: config.format,
|
|
9
|
+
updateCheck: config.updateCheck,
|
|
10
|
+
};
|
|
11
|
+
if (config.language !== undefined)
|
|
12
|
+
result.language = config.language;
|
|
13
|
+
return result;
|
|
14
|
+
}
|
|
15
|
+
export function registerConfigCommands(program, context, config) {
|
|
16
|
+
const command = program
|
|
17
|
+
.command('config')
|
|
18
|
+
.description(localizeText(context.language, 'Inspect resolved non-secret configuration'));
|
|
19
|
+
command
|
|
20
|
+
.command('show')
|
|
21
|
+
.description(localizeText(context.language, 'Show resolved non-secret configuration'))
|
|
22
|
+
.action(async () => {
|
|
23
|
+
await renderResult(successEnvelope('config.show', publicConfig(config), { requestId: context.requestId }), context);
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
import type { CliContext } from '../../cli/context.js';
|
|
3
|
+
import type { PlatformPaths } from '../../infrastructure/filesystem/platform-paths.js';
|
|
4
|
+
import type { ApiKeyAuthProvider } from '../../infrastructure/credentials/api-key-provider.js';
|
|
5
|
+
export declare function registerDataCommands(program: Command, context: CliContext, paths: PlatformPaths, remote: {
|
|
6
|
+
authProvider: ApiKeyAuthProvider;
|
|
7
|
+
baseUrl: string;
|
|
8
|
+
cliVersion: string;
|
|
9
|
+
}): void;
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { localizeText } from '../../cli/i18n.js';
|
|
2
|
+
import { successEnvelope } from '../../contracts/envelope.js';
|
|
3
|
+
import { CliError } from '../../contracts/errors.js';
|
|
4
|
+
import { openDatabase } from '../../infrastructure/duckdb/connection.js';
|
|
5
|
+
import { applyMigrations, assertSchemaCompatibility, planMigrations, } from '../../infrastructure/duckdb/migrations.js';
|
|
6
|
+
import { rebuildAdjustmentFactors } from '../../infrastructure/duckdb/factors.js';
|
|
7
|
+
import { validateDatabase } from '../../infrastructure/duckdb/quality.js';
|
|
8
|
+
import { renderResult } from '../../output/renderer.js';
|
|
9
|
+
import { initializeData } from '../../application/use-cases/data-init.js';
|
|
10
|
+
import { syncDataFromFuyao } from '../../application/use-cases/data-sync.js';
|
|
11
|
+
import { cleanManagedCache } from '../../application/use-cases/data-clean.js';
|
|
12
|
+
import { removeDatabase } from '../../application/use-cases/data-remove.js';
|
|
13
|
+
import { mkdir, stat } from 'node:fs/promises';
|
|
14
|
+
import path from 'node:path';
|
|
15
|
+
import { withExclusiveDataLock } from '../../infrastructure/filesystem/process-lock.js';
|
|
16
|
+
function dbPath(command, fallback) {
|
|
17
|
+
return (command.optsWithGlobals().db ?? process.env.HITHINK_FINANCE_DB_PATH ?? fallback);
|
|
18
|
+
}
|
|
19
|
+
async function withDataLock(paths, command, cliVersion, action) {
|
|
20
|
+
await mkdir(paths.stateDir, { recursive: true });
|
|
21
|
+
return withExclusiveDataLock(path.join(paths.stateDir, 'data.lock'), { command, cliVersion }, action);
|
|
22
|
+
}
|
|
23
|
+
async function stdinText() {
|
|
24
|
+
const chunks = [];
|
|
25
|
+
for await (const chunk of process.stdin)
|
|
26
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk)));
|
|
27
|
+
return Buffer.concat(chunks).toString('utf8').trim();
|
|
28
|
+
}
|
|
29
|
+
export function registerDataCommands(program, context, paths, remote) {
|
|
30
|
+
const data = program
|
|
31
|
+
.command('data')
|
|
32
|
+
.description(localizeText(context.language, 'Manage local DuckDB data'));
|
|
33
|
+
const init = data
|
|
34
|
+
.command('init')
|
|
35
|
+
.description(localizeText(context.language, 'Initialize local data from a verified dump'))
|
|
36
|
+
.option('--kline <path>')
|
|
37
|
+
.option('--events <path>')
|
|
38
|
+
.option('--symbols <path>');
|
|
39
|
+
init.action(async () => withDataLock(paths, 'data.init', remote.cliVersion, async () => {
|
|
40
|
+
await mkdir(paths.dataDir, { recursive: true });
|
|
41
|
+
const db = await openDatabase(dbPath(init, paths.defaultDbPath));
|
|
42
|
+
try {
|
|
43
|
+
const options = init.opts();
|
|
44
|
+
const hasKline = options.kline !== undefined;
|
|
45
|
+
const hasEvents = options.events !== undefined;
|
|
46
|
+
if (hasKline !== hasEvents)
|
|
47
|
+
throw new CliError({
|
|
48
|
+
code: 'CLI_BAD_ARGUMENT',
|
|
49
|
+
category: 'validation',
|
|
50
|
+
message: '--kline and --events must be provided together.',
|
|
51
|
+
hint: 'Provide both local dump files, or omit both to initialize from Fuyao.',
|
|
52
|
+
retryable: false,
|
|
53
|
+
exitCode: 2,
|
|
54
|
+
});
|
|
55
|
+
const result = options.kline !== undefined && options.events !== undefined
|
|
56
|
+
? {
|
|
57
|
+
decision: 'FULL',
|
|
58
|
+
factorRows: await initializeData(db.connection, {
|
|
59
|
+
klinePath: options.kline,
|
|
60
|
+
eventsPath: options.events,
|
|
61
|
+
...(options.symbols === undefined ? {} : { symbolsPath: options.symbols }),
|
|
62
|
+
batchId: `local-${Date.now()}`,
|
|
63
|
+
source: 'local-files',
|
|
64
|
+
}),
|
|
65
|
+
}
|
|
66
|
+
: await syncDataFromFuyao(db.connection, {
|
|
67
|
+
baseUrl: remote.baseUrl,
|
|
68
|
+
apiKey: (await remote.authProvider.resolve(init.optsWithGlobals().profile ?? 'default', init.optsWithGlobals()
|
|
69
|
+
.apiKeyStdin === true
|
|
70
|
+
? await stdinText()
|
|
71
|
+
: init.optsWithGlobals().apiKey)).apiKey,
|
|
72
|
+
cacheDir: paths.cacheDir,
|
|
73
|
+
});
|
|
74
|
+
await renderResult(successEnvelope('data.init', { initialized: true, path: db.path, ...result }, { requestId: context.requestId }), context);
|
|
75
|
+
}
|
|
76
|
+
finally {
|
|
77
|
+
db.close();
|
|
78
|
+
}
|
|
79
|
+
}));
|
|
80
|
+
const sync = data
|
|
81
|
+
.command('sync')
|
|
82
|
+
.description(localizeText(context.language, 'Synchronize local data'));
|
|
83
|
+
sync.action(async () => withDataLock(paths, 'data.sync', remote.cliVersion, async () => {
|
|
84
|
+
await mkdir(paths.dataDir, { recursive: true });
|
|
85
|
+
const db = await openDatabase(dbPath(sync, paths.defaultDbPath));
|
|
86
|
+
try {
|
|
87
|
+
const globals = sync.optsWithGlobals();
|
|
88
|
+
const auth = await remote.authProvider.resolve(globals.profile ?? 'default', globals.apiKeyStdin === true ? await stdinText() : globals.apiKey);
|
|
89
|
+
const result = await syncDataFromFuyao(db.connection, {
|
|
90
|
+
baseUrl: remote.baseUrl,
|
|
91
|
+
apiKey: auth.apiKey,
|
|
92
|
+
cacheDir: paths.cacheDir,
|
|
93
|
+
});
|
|
94
|
+
await renderResult(successEnvelope('data.sync', result, { requestId: context.requestId }), context);
|
|
95
|
+
}
|
|
96
|
+
finally {
|
|
97
|
+
db.close();
|
|
98
|
+
}
|
|
99
|
+
}));
|
|
100
|
+
data
|
|
101
|
+
.command('status')
|
|
102
|
+
.description(localizeText(context.language, 'Show local database status'))
|
|
103
|
+
.action(async () => {
|
|
104
|
+
const db = await openDatabase(dbPath(data, paths.defaultDbPath));
|
|
105
|
+
try {
|
|
106
|
+
const schema = await assertSchemaCompatibility(db.connection);
|
|
107
|
+
await renderResult(successEnvelope('data.status', { path: db.path, ...schema }, { requestId: context.requestId }), context);
|
|
108
|
+
}
|
|
109
|
+
finally {
|
|
110
|
+
db.close();
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
data
|
|
114
|
+
.command('validate')
|
|
115
|
+
.description(localizeText(context.language, 'Validate local data quality'))
|
|
116
|
+
.action(async () => {
|
|
117
|
+
const db = await openDatabase(dbPath(data, paths.defaultDbPath));
|
|
118
|
+
try {
|
|
119
|
+
await applyMigrations(db.connection);
|
|
120
|
+
await renderResult(successEnvelope('data.validate', await validateDatabase(db.connection), {
|
|
121
|
+
requestId: context.requestId,
|
|
122
|
+
}), context);
|
|
123
|
+
}
|
|
124
|
+
finally {
|
|
125
|
+
db.close();
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
data
|
|
129
|
+
.command('repair')
|
|
130
|
+
.description(localizeText(context.language, 'Rebuild derived factors'))
|
|
131
|
+
.action(async () => withDataLock(paths, 'data.repair', remote.cliVersion, async () => {
|
|
132
|
+
const db = await openDatabase(dbPath(data, paths.defaultDbPath));
|
|
133
|
+
try {
|
|
134
|
+
await applyMigrations(db.connection);
|
|
135
|
+
const factorRows = await rebuildAdjustmentFactors(db.connection);
|
|
136
|
+
await renderResult(successEnvelope('data.repair', { factorRows }, { requestId: context.requestId }), context);
|
|
137
|
+
}
|
|
138
|
+
finally {
|
|
139
|
+
db.close();
|
|
140
|
+
}
|
|
141
|
+
}));
|
|
142
|
+
const migrate = data
|
|
143
|
+
.command('migrate')
|
|
144
|
+
.description(localizeText(context.language, 'Plan or apply schema migrations'))
|
|
145
|
+
.option('--apply')
|
|
146
|
+
.option('--allow-heavy');
|
|
147
|
+
migrate.action(async () => withDataLock(paths, 'data.migrate', remote.cliVersion, async () => {
|
|
148
|
+
const db = await openDatabase(dbPath(migrate, paths.defaultDbPath));
|
|
149
|
+
try {
|
|
150
|
+
const options = migrate.opts();
|
|
151
|
+
const plan = await planMigrations(db.connection);
|
|
152
|
+
if (options.apply === true)
|
|
153
|
+
await applyMigrations(db.connection, undefined, {
|
|
154
|
+
allowHeavy: options.allowHeavy === true,
|
|
155
|
+
});
|
|
156
|
+
await renderResult(successEnvelope('data.migrate', { applied: options.apply === true, versions: plan.map((item) => item.version) }, { requestId: context.requestId }), context);
|
|
157
|
+
}
|
|
158
|
+
finally {
|
|
159
|
+
db.close();
|
|
160
|
+
}
|
|
161
|
+
}));
|
|
162
|
+
const clean = data
|
|
163
|
+
.command('clean')
|
|
164
|
+
.description(localizeText(context.language, 'Clean managed download caches'))
|
|
165
|
+
.option('--cache');
|
|
166
|
+
clean.action(async () => {
|
|
167
|
+
await cleanManagedCache(paths.cacheDir, paths.cacheDir);
|
|
168
|
+
await renderResult(successEnvelope('data.clean', { cacheRemoved: true, path: paths.cacheDir }, { requestId: context.requestId }), context);
|
|
169
|
+
});
|
|
170
|
+
const remove = data
|
|
171
|
+
.command('remove')
|
|
172
|
+
.description(localizeText(context.language, 'Remove the explicitly confirmed database'))
|
|
173
|
+
.option('--plan');
|
|
174
|
+
remove.action(async () => withDataLock(paths, 'data.remove', remote.cliVersion, async () => {
|
|
175
|
+
const target = dbPath(remove, paths.defaultDbPath);
|
|
176
|
+
const globals = remove.optsWithGlobals();
|
|
177
|
+
const size = await stat(target)
|
|
178
|
+
.then((value) => value.size)
|
|
179
|
+
.catch(() => 0);
|
|
180
|
+
if (remove.opts().plan !== true)
|
|
181
|
+
await removeDatabase(target, target, globals.yes === true);
|
|
182
|
+
await renderResult(successEnvelope('data.remove', { path: target, size, removed: remove.opts().plan !== true }, { requestId: context.requestId }), context);
|
|
183
|
+
}));
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { localizeText } from '../../cli/i18n.js';
|
|
2
|
+
import { exportQuery, queryReadOnly } from '../../application/use-cases/local-query.js';
|
|
3
|
+
import { successEnvelope } from '../../contracts/envelope.js';
|
|
4
|
+
import { CliError } from '../../contracts/errors.js';
|
|
5
|
+
import { openDatabase } from '../../infrastructure/duckdb/connection.js';
|
|
6
|
+
import { applyMigrations } from '../../infrastructure/duckdb/migrations.js';
|
|
7
|
+
import { renderResult } from '../../output/renderer.js';
|
|
8
|
+
function databasePath(command, fallback) {
|
|
9
|
+
return (command.optsWithGlobals().db ?? process.env.HITHINK_FINANCE_DB_PATH ?? fallback);
|
|
10
|
+
}
|
|
11
|
+
export function registerDbCommands(program, context, fallback) {
|
|
12
|
+
const db = program
|
|
13
|
+
.command('db')
|
|
14
|
+
.description(localizeText(context.language, 'Query the local DuckDB'));
|
|
15
|
+
db.command('describe')
|
|
16
|
+
.description(localizeText(context.language, 'Describe local database objects'))
|
|
17
|
+
.action(async () => {
|
|
18
|
+
const opened = await openDatabase(databasePath(db, fallback));
|
|
19
|
+
try {
|
|
20
|
+
await applyMigrations(opened.connection);
|
|
21
|
+
const rows = await queryReadOnly(opened.connection, "SELECT table_name,table_type FROM information_schema.tables WHERE table_schema='main' ORDER BY table_name");
|
|
22
|
+
await renderResult(successEnvelope('db.describe', rows, {
|
|
23
|
+
requestId: context.requestId,
|
|
24
|
+
count: rows.length,
|
|
25
|
+
}), context);
|
|
26
|
+
}
|
|
27
|
+
finally {
|
|
28
|
+
opened.close();
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
const query = db
|
|
32
|
+
.command('query')
|
|
33
|
+
.description(localizeText(context.language, 'Run a read-only SQL query'))
|
|
34
|
+
.requiredOption('--sql <sql>');
|
|
35
|
+
query.action(async () => {
|
|
36
|
+
const opened = await openDatabase(databasePath(query, fallback));
|
|
37
|
+
try {
|
|
38
|
+
const rows = await queryReadOnly(opened.connection, query.opts().sql);
|
|
39
|
+
await renderResult(successEnvelope('db.query', rows, { requestId: context.requestId, count: rows.length }), context);
|
|
40
|
+
}
|
|
41
|
+
finally {
|
|
42
|
+
opened.close();
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
const exportCommand = db
|
|
46
|
+
.command('export')
|
|
47
|
+
.description(localizeText(context.language, 'Export a read-only SQL query'))
|
|
48
|
+
.requiredOption('--sql <sql>')
|
|
49
|
+
.requiredOption('--output <path>')
|
|
50
|
+
.option('--file-format <format>', localizeText(context.language, 'ndjson, csv, or parquet'), 'ndjson');
|
|
51
|
+
exportCommand.action(async () => {
|
|
52
|
+
const options = exportCommand.opts();
|
|
53
|
+
if (!['ndjson', 'csv', 'parquet'].includes(options.fileFormat))
|
|
54
|
+
throw new CliError({
|
|
55
|
+
code: 'CLI_BAD_ARGUMENT',
|
|
56
|
+
category: 'validation',
|
|
57
|
+
message: '--file-format must be ndjson, csv, or parquet',
|
|
58
|
+
hint: 'Use --file-format ndjson, --file-format csv, or --file-format parquet.',
|
|
59
|
+
retryable: false,
|
|
60
|
+
exitCode: 2,
|
|
61
|
+
});
|
|
62
|
+
const opened = await openDatabase(databasePath(exportCommand, fallback));
|
|
63
|
+
try {
|
|
64
|
+
const count = await exportQuery(opened.connection, options.sql, options.output, options.fileFormat);
|
|
65
|
+
await renderResult(successEnvelope('db.export', { path: options.output, format: options.fileFormat, count }, { requestId: context.requestId }), context);
|
|
66
|
+
}
|
|
67
|
+
finally {
|
|
68
|
+
opened.close();
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
import type { CliContext } from '../../cli/context.js';
|
|
3
|
+
import { type RemoteCommandDependencies } from '../remote.js';
|
|
4
|
+
export declare function registerFinancialCommands(program: Command, context: CliContext, dependencies: RemoteCommandDependencies): void;
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { remoteCapabilities } from '../../contracts/remote-capabilities.js';
|
|
2
|
+
import { registerRemoteCapabilityGroup } from '../remote.js';
|
|
3
|
+
export function registerFinancialCommands(program, context, dependencies) {
|
|
4
|
+
registerRemoteCapabilityGroup(program, 'financials', remoteCapabilities.filter((item) => item.command[0] === 'financials'), context, dependencies);
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
import type { CliContext } from '../../cli/context.js';
|
|
3
|
+
import { type RemoteCommandDependencies } from '../remote.js';
|
|
4
|
+
export declare function registerIndexCommands(program: Command, context: CliContext, dependencies: RemoteCommandDependencies): void;
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { remoteCapabilities } from '../../contracts/remote-capabilities.js';
|
|
2
|
+
import { registerRemoteCapabilityGroup } from '../remote.js';
|
|
3
|
+
export function registerIndexCommands(program, context, dependencies) {
|
|
4
|
+
registerRemoteCapabilityGroup(program, 'index', remoteCapabilities.filter((item) => item.command[0] === 'index'), context, dependencies);
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
import type { CliContext } from '../../cli/context.js';
|
|
3
|
+
import { type RemoteCommandDependencies } from '../remote.js';
|
|
4
|
+
export declare function registerMarketCommands(program: Command, context: CliContext, dependencies: RemoteCommandDependencies): void;
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { remoteCapabilities } from '../../contracts/remote-capabilities.js';
|
|
2
|
+
import { registerRemoteCapabilityGroup } from '../remote.js';
|
|
3
|
+
export function registerMarketCommands(program, context, dependencies) {
|
|
4
|
+
registerRemoteCapabilityGroup(program, 'market', remoteCapabilities.filter((item) => item.command[0] === 'market'), context, dependencies);
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=index.js.map
|