@hivehub/rulebook 1.2.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/LICENSE +191 -0
- package/README.md +539 -0
- package/dist/agents/claude-code.d.ts +69 -0
- package/dist/agents/claude-code.d.ts.map +1 -0
- package/dist/agents/claude-code.js +180 -0
- package/dist/agents/claude-code.js.map +1 -0
- package/dist/agents/cursor-agent.d.ts +184 -0
- package/dist/agents/cursor-agent.d.ts.map +1 -0
- package/dist/agents/cursor-agent.js +299 -0
- package/dist/agents/cursor-agent.js.map +1 -0
- package/dist/agents/gemini-cli.d.ts +69 -0
- package/dist/agents/gemini-cli.d.ts.map +1 -0
- package/dist/agents/gemini-cli.js +180 -0
- package/dist/agents/gemini-cli.js.map +1 -0
- package/dist/cli/commands.d.ts +57 -0
- package/dist/cli/commands.d.ts.map +1 -0
- package/dist/cli/commands.js +1370 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/docs-prompts.d.ts +3 -0
- package/dist/cli/docs-prompts.d.ts.map +1 -0
- package/dist/cli/docs-prompts.js +45 -0
- package/dist/cli/docs-prompts.js.map +1 -0
- package/dist/cli/prompts.d.ts +6 -0
- package/dist/cli/prompts.d.ts.map +1 -0
- package/dist/cli/prompts.js +376 -0
- package/dist/cli/prompts.js.map +1 -0
- package/dist/core/agent-manager.d.ts +89 -0
- package/dist/core/agent-manager.d.ts.map +1 -0
- package/dist/core/agent-manager.js +546 -0
- package/dist/core/agent-manager.js.map +1 -0
- package/dist/core/auto-fixer.d.ts +14 -0
- package/dist/core/auto-fixer.d.ts.map +1 -0
- package/dist/core/auto-fixer.js +207 -0
- package/dist/core/auto-fixer.js.map +1 -0
- package/dist/core/changelog-generator.d.ts +44 -0
- package/dist/core/changelog-generator.d.ts.map +1 -0
- package/dist/core/changelog-generator.js +222 -0
- package/dist/core/changelog-generator.js.map +1 -0
- package/dist/core/cli-bridge.d.ts +113 -0
- package/dist/core/cli-bridge.d.ts.map +1 -0
- package/dist/core/cli-bridge.js +1094 -0
- package/dist/core/cli-bridge.js.map +1 -0
- package/dist/core/config-manager.d.ts +65 -0
- package/dist/core/config-manager.d.ts.map +1 -0
- package/dist/core/config-manager.js +266 -0
- package/dist/core/config-manager.js.map +1 -0
- package/dist/core/coverage-checker.d.ts +14 -0
- package/dist/core/coverage-checker.d.ts.map +1 -0
- package/dist/core/coverage-checker.js +176 -0
- package/dist/core/coverage-checker.js.map +1 -0
- package/dist/core/custom-templates.d.ts +27 -0
- package/dist/core/custom-templates.d.ts.map +1 -0
- package/dist/core/custom-templates.js +122 -0
- package/dist/core/custom-templates.js.map +1 -0
- package/dist/core/dependency-checker.d.ts +21 -0
- package/dist/core/dependency-checker.d.ts.map +1 -0
- package/dist/core/dependency-checker.js +247 -0
- package/dist/core/dependency-checker.js.map +1 -0
- package/dist/core/detector.d.ts +3 -0
- package/dist/core/detector.d.ts.map +1 -0
- package/dist/core/detector.js +1443 -0
- package/dist/core/detector.js.map +1 -0
- package/dist/core/docs-generator.d.ts +9 -0
- package/dist/core/docs-generator.d.ts.map +1 -0
- package/dist/core/docs-generator.js +531 -0
- package/dist/core/docs-generator.js.map +1 -0
- package/dist/core/generator.d.ts +16 -0
- package/dist/core/generator.d.ts.map +1 -0
- package/dist/core/generator.js +561 -0
- package/dist/core/generator.js.map +1 -0
- package/dist/core/gitignore-generator.d.ts +13 -0
- package/dist/core/gitignore-generator.d.ts.map +1 -0
- package/dist/core/gitignore-generator.js +307 -0
- package/dist/core/gitignore-generator.js.map +1 -0
- package/dist/core/health-scorer.d.ts +22 -0
- package/dist/core/health-scorer.d.ts.map +1 -0
- package/dist/core/health-scorer.js +395 -0
- package/dist/core/health-scorer.js.map +1 -0
- package/dist/core/logger.d.ts +116 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +289 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/merger.d.ts +6 -0
- package/dist/core/merger.d.ts.map +1 -0
- package/dist/core/merger.js +131 -0
- package/dist/core/merger.js.map +1 -0
- package/dist/core/migrator.d.ts +19 -0
- package/dist/core/migrator.d.ts.map +1 -0
- package/dist/core/migrator.js +102 -0
- package/dist/core/migrator.js.map +1 -0
- package/dist/core/minimal-scaffolder.d.ts +8 -0
- package/dist/core/minimal-scaffolder.d.ts.map +1 -0
- package/dist/core/minimal-scaffolder.js +51 -0
- package/dist/core/minimal-scaffolder.js.map +1 -0
- package/dist/core/modern-console-new.d.ts +81 -0
- package/dist/core/modern-console-new.d.ts.map +1 -0
- package/dist/core/modern-console-new.js +340 -0
- package/dist/core/modern-console-new.js.map +1 -0
- package/dist/core/modern-console.d.ts +99 -0
- package/dist/core/modern-console.d.ts.map +1 -0
- package/dist/core/modern-console.js +568 -0
- package/dist/core/modern-console.js.map +1 -0
- package/dist/core/openspec-manager.d.ts +133 -0
- package/dist/core/openspec-manager.d.ts.map +1 -0
- package/dist/core/openspec-manager.js +605 -0
- package/dist/core/openspec-manager.js.map +1 -0
- package/dist/core/openspec-migrator.d.ts +27 -0
- package/dist/core/openspec-migrator.d.ts.map +1 -0
- package/dist/core/openspec-migrator.js +255 -0
- package/dist/core/openspec-migrator.js.map +1 -0
- package/dist/core/task-manager.d.ts +65 -0
- package/dist/core/task-manager.d.ts.map +1 -0
- package/dist/core/task-manager.js +318 -0
- package/dist/core/task-manager.js.map +1 -0
- package/dist/core/test-task-manager.d.ts +49 -0
- package/dist/core/test-task-manager.d.ts.map +1 -0
- package/dist/core/test-task-manager.js +121 -0
- package/dist/core/test-task-manager.js.map +1 -0
- package/dist/core/validator.d.ts +21 -0
- package/dist/core/validator.d.ts.map +1 -0
- package/dist/core/validator.js +177 -0
- package/dist/core/validator.js.map +1 -0
- package/dist/core/version-bumper.d.ts +19 -0
- package/dist/core/version-bumper.d.ts.map +1 -0
- package/dist/core/version-bumper.js +180 -0
- package/dist/core/version-bumper.js.map +1 -0
- package/dist/core/watcher.d.ts +9 -0
- package/dist/core/watcher.d.ts.map +1 -0
- package/dist/core/watcher.js +22 -0
- package/dist/core/watcher.js.map +1 -0
- package/dist/core/workflow-generator.d.ts +10 -0
- package/dist/core/workflow-generator.d.ts.map +1 -0
- package/dist/core/workflow-generator.js +279 -0
- package/dist/core/workflow-generator.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +159 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/handlers/archive-task.d.ts +17 -0
- package/dist/mcp/handlers/archive-task.d.ts.map +1 -0
- package/dist/mcp/handlers/archive-task.js +36 -0
- package/dist/mcp/handlers/archive-task.js.map +1 -0
- package/dist/mcp/handlers/create-task.d.ts +17 -0
- package/dist/mcp/handlers/create-task.d.ts.map +1 -0
- package/dist/mcp/handlers/create-task.js +56 -0
- package/dist/mcp/handlers/create-task.js.map +1 -0
- package/dist/mcp/handlers/list-tasks.d.ts +22 -0
- package/dist/mcp/handlers/list-tasks.d.ts.map +1 -0
- package/dist/mcp/handlers/list-tasks.js +42 -0
- package/dist/mcp/handlers/list-tasks.js.map +1 -0
- package/dist/mcp/handlers/show-task.d.ts +25 -0
- package/dist/mcp/handlers/show-task.d.ts.map +1 -0
- package/dist/mcp/handlers/show-task.js +43 -0
- package/dist/mcp/handlers/show-task.js.map +1 -0
- package/dist/mcp/handlers/update-task.d.ts +17 -0
- package/dist/mcp/handlers/update-task.d.ts.map +1 -0
- package/dist/mcp/handlers/update-task.js +35 -0
- package/dist/mcp/handlers/update-task.js.map +1 -0
- package/dist/mcp/handlers/validate-task.d.ts +15 -0
- package/dist/mcp/handlers/validate-task.d.ts.map +1 -0
- package/dist/mcp/handlers/validate-task.js +27 -0
- package/dist/mcp/handlers/validate-task.js.map +1 -0
- package/dist/mcp/rulebook-config.d.ts +22 -0
- package/dist/mcp/rulebook-config.d.ts.map +1 -0
- package/dist/mcp/rulebook-config.js +65 -0
- package/dist/mcp/rulebook-config.js.map +1 -0
- package/dist/mcp/rulebook-server.d.ts +4 -0
- package/dist/mcp/rulebook-server.d.ts.map +1 -0
- package/dist/mcp/rulebook-server.js +246 -0
- package/dist/mcp/rulebook-server.js.map +1 -0
- package/dist/types.d.ts +190 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/file-system.d.ts +9 -0
- package/dist/utils/file-system.d.ts.map +1 -0
- package/dist/utils/file-system.js +51 -0
- package/dist/utils/file-system.js.map +1 -0
- package/dist/utils/git-hooks.d.ts +8 -0
- package/dist/utils/git-hooks.d.ts.map +1 -0
- package/dist/utils/git-hooks.js +440 -0
- package/dist/utils/git-hooks.js.map +1 -0
- package/dist/utils/rulesignore.d.ts +9 -0
- package/dist/utils/rulesignore.d.ts.map +1 -0
- package/dist/utils/rulesignore.js +42 -0
- package/dist/utils/rulesignore.js.map +1 -0
- package/package.json +106 -0
- package/templates/cli/AIDER.md +49 -0
- package/templates/cli/AMAZON_Q.md +25 -0
- package/templates/cli/AUGGIE.md +32 -0
- package/templates/cli/CLAUDE.md +32 -0
- package/templates/cli/CLAUDE_CODE.md +35 -0
- package/templates/cli/CLINE.md +32 -0
- package/templates/cli/CODEBUDDY.md +20 -0
- package/templates/cli/CODEIUM.md +20 -0
- package/templates/cli/CODEX.md +21 -0
- package/templates/cli/CONTINUE.md +34 -0
- package/templates/cli/CURSOR_CLI.md +28 -0
- package/templates/cli/FACTORY.md +18 -0
- package/templates/cli/GEMINI.md +35 -0
- package/templates/cli/KILOCODE.md +18 -0
- package/templates/cli/OPENCODE.md +18 -0
- package/templates/cli/_GENERIC_TEMPLATE.md +29 -0
- package/templates/commands/rulebook-task-apply.md +67 -0
- package/templates/commands/rulebook-task-archive.md +70 -0
- package/templates/commands/rulebook-task-create.md +93 -0
- package/templates/commands/rulebook-task-list.md +42 -0
- package/templates/commands/rulebook-task-show.md +52 -0
- package/templates/commands/rulebook-task-validate.md +53 -0
- package/templates/core/AGENT_AUTOMATION.md +184 -0
- package/templates/core/DAG.md +304 -0
- package/templates/core/DOCUMENTATION_RULES.md +37 -0
- package/templates/core/QUALITY_ENFORCEMENT.md +68 -0
- package/templates/core/RULEBOOK.md +1874 -0
- package/templates/frameworks/ANGULAR.md +36 -0
- package/templates/frameworks/DJANGO.md +83 -0
- package/templates/frameworks/ELECTRON.md +147 -0
- package/templates/frameworks/FLASK.md +38 -0
- package/templates/frameworks/FLUTTER.md +55 -0
- package/templates/frameworks/JQUERY.md +32 -0
- package/templates/frameworks/LARAVEL.md +38 -0
- package/templates/frameworks/NESTJS.md +43 -0
- package/templates/frameworks/NEXTJS.md +127 -0
- package/templates/frameworks/NUXT.md +40 -0
- package/templates/frameworks/RAILS.md +66 -0
- package/templates/frameworks/REACT.md +38 -0
- package/templates/frameworks/REACT_NATIVE.md +47 -0
- package/templates/frameworks/SPRING.md +39 -0
- package/templates/frameworks/SYMFONY.md +36 -0
- package/templates/frameworks/VUE.md +36 -0
- package/templates/frameworks/ZEND.md +35 -0
- package/templates/git/CI_CD_PATTERNS.md +661 -0
- package/templates/git/GITHUB_ACTIONS.md +728 -0
- package/templates/git/GITLAB_CI.md +730 -0
- package/templates/git/GIT_WORKFLOW.md +1157 -0
- package/templates/git/SECRETS_MANAGEMENT.md +585 -0
- package/templates/hooks/COMMIT_MSG.md +530 -0
- package/templates/hooks/POST_CHECKOUT.md +546 -0
- package/templates/hooks/PREPARE_COMMIT_MSG.md +619 -0
- package/templates/hooks/PRE_COMMIT.md +414 -0
- package/templates/hooks/PRE_PUSH.md +601 -0
- package/templates/hooks/csharp-pre-commit.sh +23 -0
- package/templates/hooks/csharp-pre-push.sh +23 -0
- package/templates/hooks/dart-pre-commit.sh +30 -0
- package/templates/hooks/dart-pre-push.sh +25 -0
- package/templates/hooks/elixir-pre-commit.sh +32 -0
- package/templates/hooks/elixir-pre-push.sh +31 -0
- package/templates/hooks/erlang-pre-commit.sh +30 -0
- package/templates/hooks/erlang-pre-push.sh +37 -0
- package/templates/hooks/go-pre-commit.sh +40 -0
- package/templates/hooks/go-pre-push.sh +31 -0
- package/templates/hooks/haskell-pre-commit.sh +41 -0
- package/templates/hooks/haskell-pre-push.sh +37 -0
- package/templates/hooks/java-pre-commit.sh +34 -0
- package/templates/hooks/java-pre-push.sh +24 -0
- package/templates/hooks/kotlin-pre-commit.sh +32 -0
- package/templates/hooks/kotlin-pre-push.sh +16 -0
- package/templates/hooks/php-pre-commit.sh +36 -0
- package/templates/hooks/php-pre-push.sh +26 -0
- package/templates/hooks/python-pre-commit.sh +51 -0
- package/templates/hooks/python-pre-push.sh +25 -0
- package/templates/hooks/ruby-pre-commit.sh +33 -0
- package/templates/hooks/ruby-pre-push.sh +32 -0
- package/templates/hooks/rust-pre-commit.sh +30 -0
- package/templates/hooks/rust-pre-push.sh +30 -0
- package/templates/hooks/scala-pre-commit.sh +32 -0
- package/templates/hooks/scala-pre-push.sh +24 -0
- package/templates/hooks/swift-pre-commit.sh +25 -0
- package/templates/hooks/swift-pre-push.sh +23 -0
- package/templates/hooks/typescript-pre-commit.sh +37 -0
- package/templates/hooks/typescript-pre-push.sh +36 -0
- package/templates/ides/COPILOT.md +37 -0
- package/templates/ides/CURSOR.md +43 -0
- package/templates/ides/JETBRAINS_AI.md +35 -0
- package/templates/ides/REPLIT.md +36 -0
- package/templates/ides/TABNINE.md +29 -0
- package/templates/ides/VSCODE.md +40 -0
- package/templates/ides/WINDSURF.md +36 -0
- package/templates/ides/ZED.md +32 -0
- package/templates/languages/ADA.md +58 -0
- package/templates/languages/C.md +333 -0
- package/templates/languages/CPP.md +743 -0
- package/templates/languages/CSHARP.md +417 -0
- package/templates/languages/DART.md +332 -0
- package/templates/languages/ELIXIR.md +454 -0
- package/templates/languages/ERLANG.md +361 -0
- package/templates/languages/GO.md +645 -0
- package/templates/languages/HASKELL.md +177 -0
- package/templates/languages/JAVA.md +607 -0
- package/templates/languages/JAVASCRIPT.md +631 -0
- package/templates/languages/JULIA.md +97 -0
- package/templates/languages/KOTLIN.md +511 -0
- package/templates/languages/LISP.md +100 -0
- package/templates/languages/LUA.md +74 -0
- package/templates/languages/OBJECTIVEC.md +90 -0
- package/templates/languages/PHP.md +416 -0
- package/templates/languages/PYTHON.md +682 -0
- package/templates/languages/R.md +350 -0
- package/templates/languages/RUBY.md +421 -0
- package/templates/languages/RUST.md +477 -0
- package/templates/languages/SAS.md +73 -0
- package/templates/languages/SCALA.md +348 -0
- package/templates/languages/SOLIDITY.md +580 -0
- package/templates/languages/SQL.md +137 -0
- package/templates/languages/SWIFT.md +466 -0
- package/templates/languages/TYPESCRIPT.md +591 -0
- package/templates/languages/ZIG.md +265 -0
- package/templates/modules/ATLASSIAN.md +255 -0
- package/templates/modules/CONTEXT7.md +54 -0
- package/templates/modules/FIGMA.md +267 -0
- package/templates/modules/GITHUB_MCP.md +64 -0
- package/templates/modules/GRAFANA.md +328 -0
- package/templates/modules/NOTION.md +247 -0
- package/templates/modules/PLAYWRIGHT.md +90 -0
- package/templates/modules/RULEBOOK_MCP.md +156 -0
- package/templates/modules/SERENA.md +337 -0
- package/templates/modules/SUPABASE.md +223 -0
- package/templates/modules/SYNAP.md +69 -0
- package/templates/modules/VECTORIZER.md +63 -0
- package/templates/services/AZURE_BLOB.md +184 -0
- package/templates/services/CASSANDRA.md +239 -0
- package/templates/services/DYNAMODB.md +308 -0
- package/templates/services/ELASTICSEARCH.md +347 -0
- package/templates/services/GCS.md +178 -0
- package/templates/services/INFLUXDB.md +265 -0
- package/templates/services/KAFKA.md +341 -0
- package/templates/services/MARIADB.md +183 -0
- package/templates/services/MEMCACHED.md +242 -0
- package/templates/services/MINIO.md +201 -0
- package/templates/services/MONGODB.md +268 -0
- package/templates/services/MYSQL.md +358 -0
- package/templates/services/NEO4J.md +247 -0
- package/templates/services/ORACLE.md +290 -0
- package/templates/services/POSTGRESQL.md +326 -0
- package/templates/services/RABBITMQ.md +286 -0
- package/templates/services/REDIS.md +292 -0
- package/templates/services/S3.md +298 -0
- package/templates/services/SQLITE.md +294 -0
- package/templates/services/SQLSERVER.md +294 -0
- package/templates/workflows/codespell.yml +31 -0
- package/templates/workflows/cpp-lint.yml +47 -0
- package/templates/workflows/cpp-publish.yml +119 -0
- package/templates/workflows/cpp-test.yml +77 -0
- package/templates/workflows/dotnet-lint.yml +29 -0
- package/templates/workflows/dotnet-publish.yml +40 -0
- package/templates/workflows/dotnet-test.yml +41 -0
- package/templates/workflows/elixir-lint.yml +45 -0
- package/templates/workflows/elixir-publish.yml +49 -0
- package/templates/workflows/elixir-test.yml +54 -0
- package/templates/workflows/erlang-lint.yml +47 -0
- package/templates/workflows/erlang-test.yml +62 -0
- package/templates/workflows/go-lint.yml +39 -0
- package/templates/workflows/go-publish.yml +95 -0
- package/templates/workflows/go-test.yml +59 -0
- package/templates/workflows/java-lint.yml +60 -0
- package/templates/workflows/java-publish.yml +120 -0
- package/templates/workflows/java-test.yml +85 -0
- package/templates/workflows/kotlin-lint.yml +34 -0
- package/templates/workflows/kotlin-publish.yml +56 -0
- package/templates/workflows/kotlin-test.yml +48 -0
- package/templates/workflows/php-lint.yml +39 -0
- package/templates/workflows/php-publish.yml +50 -0
- package/templates/workflows/php-test.yml +54 -0
- package/templates/workflows/python-lint.yml +47 -0
- package/templates/workflows/python-publish.yml +91 -0
- package/templates/workflows/python-test.yml +59 -0
- package/templates/workflows/rust-lint.yml +54 -0
- package/templates/workflows/rust-publish.yml +66 -0
- package/templates/workflows/rust-test.yml +75 -0
- package/templates/workflows/solidity-lint.yml +41 -0
- package/templates/workflows/solidity-test.yml +47 -0
- package/templates/workflows/swift-lint.yml +32 -0
- package/templates/workflows/swift-publish.yml +58 -0
- package/templates/workflows/swift-test.yml +44 -0
- package/templates/workflows/typescript-lint.yml +61 -0
- package/templates/workflows/typescript-publish.yml +60 -0
- package/templates/workflows/typescript-test.yml +73 -0
- package/templates/workflows/zig-lint.yml +27 -0
- package/templates/workflows/zig-test.yml +40 -0
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
<!-- INFLUXDB:START -->
|
|
2
|
+
# InfluxDB Time-Series Database Instructions
|
|
3
|
+
|
|
4
|
+
**CRITICAL**: Use InfluxDB for time-series data, metrics, IoT data, and real-time analytics with high write throughput.
|
|
5
|
+
|
|
6
|
+
## Core Features
|
|
7
|
+
|
|
8
|
+
### Connection
|
|
9
|
+
```typescript
|
|
10
|
+
// Using @influxdata/influxdb-client
|
|
11
|
+
import { InfluxDB, Point } from '@influxdata/influxdb-client'
|
|
12
|
+
|
|
13
|
+
const token = process.env.INFLUXDB_TOKEN || ''
|
|
14
|
+
const org = process.env.INFLUXDB_ORG || 'myorg'
|
|
15
|
+
const bucket = process.env.INFLUXDB_BUCKET || 'mybucket'
|
|
16
|
+
|
|
17
|
+
const client = new InfluxDB({
|
|
18
|
+
url: process.env.INFLUXDB_URL || 'http://localhost:8086',
|
|
19
|
+
token,
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
const writeApi = client.getWriteApi(org, bucket, 'ns')
|
|
23
|
+
const queryApi = client.getQueryApi(org)
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Writing Data
|
|
27
|
+
```typescript
|
|
28
|
+
// Create point
|
|
29
|
+
const point = new Point('temperature')
|
|
30
|
+
.tag('location', 'room1')
|
|
31
|
+
.tag('sensor', 'sensor1')
|
|
32
|
+
.floatField('value', 23.5)
|
|
33
|
+
.timestamp(new Date())
|
|
34
|
+
|
|
35
|
+
writeApi.writePoint(point)
|
|
36
|
+
|
|
37
|
+
// Multiple points
|
|
38
|
+
const points = [
|
|
39
|
+
new Point('temperature').tag('location', 'room1').floatField('value', 23.5),
|
|
40
|
+
new Point('humidity').tag('location', 'room1').floatField('value', 65.2),
|
|
41
|
+
new Point('pressure').tag('location', 'room1').floatField('value', 1013.25),
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
writeApi.writePoints(points)
|
|
45
|
+
await writeApi.close()
|
|
46
|
+
|
|
47
|
+
// Using line protocol
|
|
48
|
+
writeApi.writeRecord('temperature,location=room1 value=23.5')
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Querying Data
|
|
52
|
+
```typescript
|
|
53
|
+
// Flux query
|
|
54
|
+
const query = `
|
|
55
|
+
from(bucket: "${bucket}")
|
|
56
|
+
|> range(start: -1h)
|
|
57
|
+
|> filter(fn: (r) => r._measurement == "temperature")
|
|
58
|
+
|> filter(fn: (r) => r.location == "room1")
|
|
59
|
+
|> aggregateWindow(every: 5m, fn: mean, createEmpty: false)
|
|
60
|
+
|> yield(name: "mean")
|
|
61
|
+
`
|
|
62
|
+
|
|
63
|
+
queryApi.queryRows(query, {
|
|
64
|
+
next(row, tableMeta) {
|
|
65
|
+
const record = tableMeta.toObject(row)
|
|
66
|
+
console.log(record)
|
|
67
|
+
},
|
|
68
|
+
error(error) {
|
|
69
|
+
console.error(error)
|
|
70
|
+
},
|
|
71
|
+
complete() {
|
|
72
|
+
console.log('Query completed')
|
|
73
|
+
},
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
// InfluxQL query (legacy)
|
|
77
|
+
const query = `
|
|
78
|
+
SELECT mean("value")
|
|
79
|
+
FROM "temperature"
|
|
80
|
+
WHERE "location" = 'room1'
|
|
81
|
+
AND time >= now() - 1h
|
|
82
|
+
GROUP BY time(5m)
|
|
83
|
+
`
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Common Patterns
|
|
87
|
+
|
|
88
|
+
### Metrics Collection
|
|
89
|
+
```typescript
|
|
90
|
+
async function recordMetric(measurement: string, tags: Record<string, string>, fields: Record<string, number>) {
|
|
91
|
+
const point = new Point(measurement)
|
|
92
|
+
|
|
93
|
+
for (const [key, value] of Object.entries(tags)) {
|
|
94
|
+
point.tag(key, value)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
for (const [key, value] of Object.entries(fields)) {
|
|
98
|
+
point.floatField(key, value)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
point.timestamp(new Date())
|
|
102
|
+
writeApi.writePoint(point)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Usage
|
|
106
|
+
await recordMetric('api_request', {
|
|
107
|
+
endpoint: '/users',
|
|
108
|
+
method: 'GET',
|
|
109
|
+
status: '200',
|
|
110
|
+
}, {
|
|
111
|
+
duration: 125.5,
|
|
112
|
+
bytes: 2048,
|
|
113
|
+
})
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Aggregations
|
|
117
|
+
```typescript
|
|
118
|
+
async function getAverageTemperature(location: string, duration: string) {
|
|
119
|
+
const query = `
|
|
120
|
+
from(bucket: "${bucket}")
|
|
121
|
+
|> range(start: ${duration})
|
|
122
|
+
|> filter(fn: (r) => r._measurement == "temperature")
|
|
123
|
+
|> filter(fn: (r) => r.location == "${location}")
|
|
124
|
+
|> mean()
|
|
125
|
+
`
|
|
126
|
+
|
|
127
|
+
return new Promise((resolve, reject) => {
|
|
128
|
+
const results: number[] = []
|
|
129
|
+
queryApi.queryRows(query, {
|
|
130
|
+
next(row, tableMeta) {
|
|
131
|
+
const record = tableMeta.toObject(row)
|
|
132
|
+
results.push(record._value)
|
|
133
|
+
},
|
|
134
|
+
error: reject,
|
|
135
|
+
complete() {
|
|
136
|
+
resolve(results[0] || 0)
|
|
137
|
+
},
|
|
138
|
+
})
|
|
139
|
+
})
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Batch Writing
|
|
144
|
+
```typescript
|
|
145
|
+
class MetricsBuffer {
|
|
146
|
+
private points: Point[] = []
|
|
147
|
+
private maxSize = 1000
|
|
148
|
+
private flushInterval = 5000 // 5 seconds
|
|
149
|
+
|
|
150
|
+
constructor() {
|
|
151
|
+
setInterval(() => this.flush(), this.flushInterval)
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
add(point: Point) {
|
|
155
|
+
this.points.push(point)
|
|
156
|
+
if (this.points.length >= this.maxSize) {
|
|
157
|
+
this.flush()
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
async flush() {
|
|
162
|
+
if (this.points.length === 0) return
|
|
163
|
+
|
|
164
|
+
const points = [...this.points]
|
|
165
|
+
this.points = []
|
|
166
|
+
|
|
167
|
+
for (const point of points) {
|
|
168
|
+
writeApi.writePoint(point)
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
await writeApi.flush()
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## Best Practices
|
|
177
|
+
|
|
178
|
+
✅ **DO:**
|
|
179
|
+
- Use tags for frequently filtered fields
|
|
180
|
+
- Use fields for numeric values
|
|
181
|
+
- Batch writes for better performance
|
|
182
|
+
- Use appropriate retention policies
|
|
183
|
+
- Monitor disk usage
|
|
184
|
+
- Use downsampling for old data
|
|
185
|
+
- Create continuous queries for aggregations
|
|
186
|
+
- Use appropriate precision (ns, us, ms, s)
|
|
187
|
+
- Tag data with metadata (location, device, etc.)
|
|
188
|
+
- Monitor write performance
|
|
189
|
+
|
|
190
|
+
❌ **DON'T:**
|
|
191
|
+
- Store high-cardinality data in tags
|
|
192
|
+
- Store non-numeric data in fields
|
|
193
|
+
- Write points one at a time
|
|
194
|
+
- Ignore retention policies
|
|
195
|
+
- Store sensitive data without encryption
|
|
196
|
+
- Hardcode connection strings
|
|
197
|
+
- Skip error handling
|
|
198
|
+
- Ignore disk space
|
|
199
|
+
- Use too many tags (affects performance)
|
|
200
|
+
- Store large text in fields
|
|
201
|
+
|
|
202
|
+
## Configuration
|
|
203
|
+
|
|
204
|
+
### Environment Variables
|
|
205
|
+
```bash
|
|
206
|
+
INFLUXDB_URL=http://localhost:8086
|
|
207
|
+
INFLUXDB_TOKEN=your-token
|
|
208
|
+
INFLUXDB_ORG=myorg
|
|
209
|
+
INFLUXDB_BUCKET=mybucket
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Docker Compose
|
|
213
|
+
```yaml
|
|
214
|
+
services:
|
|
215
|
+
influxdb:
|
|
216
|
+
image: influxdb:2.7
|
|
217
|
+
ports:
|
|
218
|
+
- "8086:8086"
|
|
219
|
+
environment:
|
|
220
|
+
DOCKER_INFLUXDB_INIT_MODE: setup
|
|
221
|
+
DOCKER_INFLUXDB_INIT_USERNAME: admin
|
|
222
|
+
DOCKER_INFLUXDB_INIT_PASSWORD: securepassword
|
|
223
|
+
DOCKER_INFLUXDB_INIT_ORG: myorg
|
|
224
|
+
DOCKER_INFLUXDB_INIT_BUCKET: mybucket
|
|
225
|
+
DOCKER_INFLUXDB_INIT_ADMIN_TOKEN: your-token
|
|
226
|
+
volumes:
|
|
227
|
+
- influxdb_data:/var/lib/influxdb2
|
|
228
|
+
healthcheck:
|
|
229
|
+
test: ["CMD", "influx", "ping"]
|
|
230
|
+
interval: 10s
|
|
231
|
+
timeout: 5s
|
|
232
|
+
retries: 5
|
|
233
|
+
|
|
234
|
+
volumes:
|
|
235
|
+
influxdb_data:
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## Integration with Development
|
|
239
|
+
|
|
240
|
+
### Testing
|
|
241
|
+
```typescript
|
|
242
|
+
// Use test bucket
|
|
243
|
+
const testBucket = 'test_bucket'
|
|
244
|
+
const testWriteApi = client.getWriteApi(org, testBucket, 'ns')
|
|
245
|
+
|
|
246
|
+
// Clean up after tests
|
|
247
|
+
afterEach(async () => {
|
|
248
|
+
// Delete test data or use separate test bucket
|
|
249
|
+
})
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Health Checks
|
|
253
|
+
```typescript
|
|
254
|
+
async function checkInfluxDBHealth(): Promise<boolean> {
|
|
255
|
+
try {
|
|
256
|
+
const health = await fetch(`${process.env.INFLUXDB_URL}/health`)
|
|
257
|
+
return health.ok
|
|
258
|
+
} catch {
|
|
259
|
+
return false
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
<!-- INFLUXDB:END -->
|
|
265
|
+
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
<!-- KAFKA:START -->
|
|
2
|
+
# Apache Kafka Message Streaming Instructions
|
|
3
|
+
|
|
4
|
+
**CRITICAL**: Use Kafka for high-throughput event streaming, real-time data pipelines, and distributed messaging with fault tolerance.
|
|
5
|
+
|
|
6
|
+
## Core Features
|
|
7
|
+
|
|
8
|
+
### Connection
|
|
9
|
+
```typescript
|
|
10
|
+
// Using kafkajs
|
|
11
|
+
import { Kafka } from 'kafkajs'
|
|
12
|
+
|
|
13
|
+
const kafka = new Kafka({
|
|
14
|
+
clientId: 'my-app',
|
|
15
|
+
brokers: (process.env.KAFKA_BROKERS || 'localhost:9092').split(','),
|
|
16
|
+
ssl: process.env.KAFKA_SSL === 'true',
|
|
17
|
+
sasl: process.env.KAFKA_USERNAME ? {
|
|
18
|
+
mechanism: 'plain',
|
|
19
|
+
username: process.env.KAFKA_USERNAME,
|
|
20
|
+
password: process.env.KAFKA_PASSWORD,
|
|
21
|
+
} : undefined,
|
|
22
|
+
retry: {
|
|
23
|
+
initialRetryTime: 100,
|
|
24
|
+
retries: 8,
|
|
25
|
+
},
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
const producer = kafka.producer()
|
|
29
|
+
const consumer = kafka.consumer({ groupId: 'my-group' })
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Producing Messages
|
|
33
|
+
```typescript
|
|
34
|
+
await producer.connect()
|
|
35
|
+
|
|
36
|
+
// Send single message
|
|
37
|
+
await producer.send({
|
|
38
|
+
topic: 'users',
|
|
39
|
+
messages: [{
|
|
40
|
+
key: 'user-1',
|
|
41
|
+
value: JSON.stringify({ id: '1', name: 'John', email: 'john@example.com' }),
|
|
42
|
+
headers: {
|
|
43
|
+
'content-type': 'application/json',
|
|
44
|
+
},
|
|
45
|
+
}],
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
// Send multiple messages
|
|
49
|
+
await producer.send({
|
|
50
|
+
topic: 'events',
|
|
51
|
+
messages: [
|
|
52
|
+
{ key: 'event-1', value: JSON.stringify({ type: 'created', id: '1' }) },
|
|
53
|
+
{ key: 'event-2', value: JSON.stringify({ type: 'updated', id: '2' }) },
|
|
54
|
+
],
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
// Send with partition
|
|
58
|
+
await producer.send({
|
|
59
|
+
topic: 'orders',
|
|
60
|
+
messages: [{
|
|
61
|
+
key: 'order-1',
|
|
62
|
+
value: JSON.stringify({ orderId: '1', amount: 100 }),
|
|
63
|
+
partition: 0, // Specific partition
|
|
64
|
+
}],
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
await producer.disconnect()
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Consuming Messages
|
|
71
|
+
```typescript
|
|
72
|
+
await consumer.connect()
|
|
73
|
+
await consumer.subscribe({ topic: 'users', fromBeginning: false })
|
|
74
|
+
|
|
75
|
+
await consumer.run({
|
|
76
|
+
eachMessage: async ({ topic, partition, message }) => {
|
|
77
|
+
const key = message.key?.toString()
|
|
78
|
+
const value = JSON.parse(message.value?.toString() || '{}')
|
|
79
|
+
|
|
80
|
+
console.log({
|
|
81
|
+
topic,
|
|
82
|
+
partition,
|
|
83
|
+
offset: message.offset,
|
|
84
|
+
key,
|
|
85
|
+
value,
|
|
86
|
+
headers: message.headers,
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
// Process message
|
|
90
|
+
await processMessage(value)
|
|
91
|
+
},
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
// Consume from specific partition
|
|
95
|
+
await consumer.subscribe({ topic: 'events' })
|
|
96
|
+
await consumer.run({
|
|
97
|
+
partitionsConsumedConcurrently: 1, // Process one partition at a time
|
|
98
|
+
eachMessage: async ({ topic, partition, message }) => {
|
|
99
|
+
// Process message
|
|
100
|
+
},
|
|
101
|
+
})
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Advanced Features
|
|
105
|
+
```typescript
|
|
106
|
+
// Transactional producer
|
|
107
|
+
const transactionalProducer = kafka.producer({
|
|
108
|
+
transactionalId: 'my-transactional-producer',
|
|
109
|
+
maxInFlightRequests: 1,
|
|
110
|
+
idempotent: true,
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
await transactionalProducer.connect()
|
|
114
|
+
|
|
115
|
+
await transactionalProducer.send({
|
|
116
|
+
topic: 'users',
|
|
117
|
+
messages: [{ key: 'user-1', value: JSON.stringify(userData) }],
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
await transactionalProducer.sendOffsets({
|
|
121
|
+
consumerGroupId: 'my-group',
|
|
122
|
+
topics: [{
|
|
123
|
+
topic: 'users',
|
|
124
|
+
partitions: [{ partition: 0, offset: '100' }],
|
|
125
|
+
}],
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
await transactionalProducer.commitTransaction()
|
|
129
|
+
|
|
130
|
+
// Admin operations
|
|
131
|
+
const admin = kafka.admin()
|
|
132
|
+
await admin.connect()
|
|
133
|
+
|
|
134
|
+
// Create topic
|
|
135
|
+
await admin.createTopics({
|
|
136
|
+
topics: [{
|
|
137
|
+
topic: 'new-topic',
|
|
138
|
+
numPartitions: 3,
|
|
139
|
+
replicationFactor: 1,
|
|
140
|
+
configEntries: [
|
|
141
|
+
{ name: 'retention.ms', value: '604800000' }, // 7 days
|
|
142
|
+
],
|
|
143
|
+
}],
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
// List topics
|
|
147
|
+
const topics = await admin.listTopics()
|
|
148
|
+
|
|
149
|
+
// Delete topic
|
|
150
|
+
await admin.deleteTopics({
|
|
151
|
+
topics: ['old-topic'],
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
await admin.disconnect()
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Common Patterns
|
|
158
|
+
|
|
159
|
+
### Event Sourcing
|
|
160
|
+
```typescript
|
|
161
|
+
async function publishEvent(eventType: string, aggregateId: string, data: any) {
|
|
162
|
+
await producer.send({
|
|
163
|
+
topic: 'events',
|
|
164
|
+
messages: [{
|
|
165
|
+
key: aggregateId,
|
|
166
|
+
value: JSON.stringify({
|
|
167
|
+
eventType,
|
|
168
|
+
aggregateId,
|
|
169
|
+
data,
|
|
170
|
+
timestamp: new Date().toISOString(),
|
|
171
|
+
version: 1,
|
|
172
|
+
}),
|
|
173
|
+
headers: {
|
|
174
|
+
'event-type': eventType,
|
|
175
|
+
},
|
|
176
|
+
}],
|
|
177
|
+
})
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Replay events
|
|
181
|
+
await consumer.subscribe({ topic: 'events', fromBeginning: true })
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### CQRS Pattern
|
|
185
|
+
```typescript
|
|
186
|
+
// Command side (write)
|
|
187
|
+
async function handleCommand(command: any) {
|
|
188
|
+
// Process command
|
|
189
|
+
const result = await processCommand(command)
|
|
190
|
+
|
|
191
|
+
// Publish event
|
|
192
|
+
await producer.send({
|
|
193
|
+
topic: 'commands',
|
|
194
|
+
messages: [{
|
|
195
|
+
key: command.aggregateId,
|
|
196
|
+
value: JSON.stringify({
|
|
197
|
+
commandType: command.type,
|
|
198
|
+
aggregateId: command.aggregateId,
|
|
199
|
+
data: result,
|
|
200
|
+
}),
|
|
201
|
+
}],
|
|
202
|
+
})
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Query side (read)
|
|
206
|
+
await consumer.subscribe({ topic: 'commands' })
|
|
207
|
+
await consumer.run({
|
|
208
|
+
eachMessage: async ({ message }) => {
|
|
209
|
+
const command = JSON.parse(message.value?.toString() || '{}')
|
|
210
|
+
await updateReadModel(command)
|
|
211
|
+
},
|
|
212
|
+
})
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Stream Processing
|
|
216
|
+
```typescript
|
|
217
|
+
// Process stream with state
|
|
218
|
+
const stateStore = new Map<string, any>()
|
|
219
|
+
|
|
220
|
+
await consumer.subscribe({ topic: 'events' })
|
|
221
|
+
await consumer.run({
|
|
222
|
+
eachMessage: async ({ message }) => {
|
|
223
|
+
const event = JSON.parse(message.value?.toString() || '{}')
|
|
224
|
+
const key = event.aggregateId
|
|
225
|
+
|
|
226
|
+
// Update state
|
|
227
|
+
const currentState = stateStore.get(key) || {}
|
|
228
|
+
const newState = { ...currentState, ...event.data }
|
|
229
|
+
stateStore.set(key, newState)
|
|
230
|
+
|
|
231
|
+
// Emit aggregated result
|
|
232
|
+
await producer.send({
|
|
233
|
+
topic: 'aggregated-events',
|
|
234
|
+
messages: [{
|
|
235
|
+
key,
|
|
236
|
+
value: JSON.stringify(newState),
|
|
237
|
+
}],
|
|
238
|
+
})
|
|
239
|
+
},
|
|
240
|
+
})
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## Best Practices
|
|
244
|
+
|
|
245
|
+
✅ **DO:**
|
|
246
|
+
- Use appropriate partition keys for message ordering
|
|
247
|
+
- Implement idempotent consumers
|
|
248
|
+
- Use consumer groups for load balancing
|
|
249
|
+
- Monitor consumer lag
|
|
250
|
+
- Use transactions for exactly-once semantics
|
|
251
|
+
- Set appropriate retention policies
|
|
252
|
+
- Use compression for large messages
|
|
253
|
+
- Implement proper error handling
|
|
254
|
+
- Use schema registry for message validation
|
|
255
|
+
- Monitor topic sizes and partitions
|
|
256
|
+
|
|
257
|
+
❌ **DON'T:**
|
|
258
|
+
- Store large messages (> 1MB, use external storage)
|
|
259
|
+
- Skip error handling
|
|
260
|
+
- Ignore consumer lag
|
|
261
|
+
- Hardcode broker addresses
|
|
262
|
+
- Use too many partitions (affects performance)
|
|
263
|
+
- Skip idempotency checks
|
|
264
|
+
- Ignore message ordering requirements
|
|
265
|
+
- Store sensitive data without encryption
|
|
266
|
+
- Skip monitoring
|
|
267
|
+
- Use synchronous operations
|
|
268
|
+
|
|
269
|
+
## Configuration
|
|
270
|
+
|
|
271
|
+
### Environment Variables
|
|
272
|
+
```bash
|
|
273
|
+
KAFKA_BROKERS=localhost:9092
|
|
274
|
+
KAFKA_BROKERS=broker1:9092,broker2:9092,broker3:9092
|
|
275
|
+
KAFKA_SSL=false
|
|
276
|
+
KAFKA_USERNAME=
|
|
277
|
+
KAFKA_PASSWORD=
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### Docker Compose
|
|
281
|
+
```yaml
|
|
282
|
+
services:
|
|
283
|
+
zookeeper:
|
|
284
|
+
image: confluentinc/cp-zookeeper:latest
|
|
285
|
+
environment:
|
|
286
|
+
ZOOKEEPER_CLIENT_PORT: 2181
|
|
287
|
+
ZOOKEEPER_TICK_TIME: 2000
|
|
288
|
+
ports:
|
|
289
|
+
- "2181:2181"
|
|
290
|
+
|
|
291
|
+
kafka:
|
|
292
|
+
image: confluentinc/cp-kafka:latest
|
|
293
|
+
depends_on:
|
|
294
|
+
- zookeeper
|
|
295
|
+
ports:
|
|
296
|
+
- "9092:9092"
|
|
297
|
+
environment:
|
|
298
|
+
KAFKA_BROKER_ID: 1
|
|
299
|
+
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
|
|
300
|
+
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092
|
|
301
|
+
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
|
|
302
|
+
healthcheck:
|
|
303
|
+
test: ["CMD", "kafka-broker-api-versions", "--bootstrap-server", "localhost:9092"]
|
|
304
|
+
interval: 10s
|
|
305
|
+
timeout: 5s
|
|
306
|
+
retries: 5
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
## Integration with Development
|
|
310
|
+
|
|
311
|
+
### Testing
|
|
312
|
+
```typescript
|
|
313
|
+
// Use test Kafka instance
|
|
314
|
+
const testKafka = new Kafka({
|
|
315
|
+
clientId: 'test-app',
|
|
316
|
+
brokers: ['localhost:9093'], // Different port
|
|
317
|
+
})
|
|
318
|
+
|
|
319
|
+
// Clean up after tests
|
|
320
|
+
afterEach(async () => {
|
|
321
|
+
// Delete test topics or use separate test cluster
|
|
322
|
+
})
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
### Health Checks
|
|
326
|
+
```typescript
|
|
327
|
+
async function checkKafkaHealth(): Promise<boolean> {
|
|
328
|
+
try {
|
|
329
|
+
const admin = kafka.admin()
|
|
330
|
+
await admin.connect()
|
|
331
|
+
await admin.listTopics()
|
|
332
|
+
await admin.disconnect()
|
|
333
|
+
return true
|
|
334
|
+
} catch {
|
|
335
|
+
return false
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
<!-- KAFKA:END -->
|
|
341
|
+
|