Files
sim/apps/sim/blocks/registry.ts
Waleed 6326353f5c feat(okta): add complete Okta identity management integration (#3685)
* feat(okta): add complete Okta identity management integration

Add 18 Okta Management API tools covering user lifecycle (list, get,
create, update, activate, deactivate, suspend, unsuspend, reset password,
delete) and group management (list, get, create, update, delete, add/remove
members, list members). Includes block with conditional UI, icon, registry
entries, and generated docs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs(okta): add manual description section to generated docs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(okta): address PR review — SSRF prevention, safe response parsing, consistent sendEmail

- Add validateOktaDomain() to prevent SSRF via user-supplied domain param
- Fix 9 tools to check response.ok before calling response.json()
- Make sendEmail query param explicit in deactivate_user and delete_user

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(okta): only forward boolean switches when explicitly true

Switch subBlocks default to OFF (false), which was being forwarded to
tools and overriding their default-true behavior for sendEmail and
activate params. Now only forward these when explicitly toggled ON.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(okta): use nullish coalescing for boolean switch defaults

Block now forwards sendEmail/activate values as-is (including false).
Tools use ?? operator so: explicit true/false from switches are respected,
undefined (programmatic calls) still defaults to true.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(okta): prevent silent data loss in update operations

- update_group: always include description in PUT body (defaults to '')
  since PUT replaces the full profile object
- update_user: use !== undefined checks so empty strings can clear fields
  via Okta's POST partial update
- block: allow empty strings through passthrough loop and use !== undefined
  for groupDescription mapping

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(okta): move validateOktaDomain to centralized input-validation

- Moved validateOktaDomain from tools/okta/types.ts to
  lib/core/security/input-validation.ts alongside other validation utils
- Added .trim() to handle copy-paste whitespace in domain input
- Updated all 18 tool files to import from the new location

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 16:01:27 -07:00

473 lines
19 KiB
TypeScript

import { A2ABlock } from '@/blocks/blocks/a2a'
import { AgentBlock } from '@/blocks/blocks/agent'
import { AhrefsBlock } from '@/blocks/blocks/ahrefs'
import { AirtableBlock } from '@/blocks/blocks/airtable'
import { AirweaveBlock } from '@/blocks/blocks/airweave'
import { AlgoliaBlock } from '@/blocks/blocks/algolia'
import { AmplitudeBlock } from '@/blocks/blocks/amplitude'
import { ApiBlock } from '@/blocks/blocks/api'
import { ApiTriggerBlock } from '@/blocks/blocks/api_trigger'
import { ApifyBlock } from '@/blocks/blocks/apify'
import { ApolloBlock } from '@/blocks/blocks/apollo'
import { ArxivBlock } from '@/blocks/blocks/arxiv'
import { AsanaBlock } from '@/blocks/blocks/asana'
import { AshbyBlock } from '@/blocks/blocks/ashby'
import { AttioBlock } from '@/blocks/blocks/attio'
import { BoxBlock } from '@/blocks/blocks/box'
import { BrandfetchBlock } from '@/blocks/blocks/brandfetch'
import { BrowserUseBlock } from '@/blocks/blocks/browser_use'
import { CalComBlock } from '@/blocks/blocks/calcom'
import { CalendlyBlock } from '@/blocks/blocks/calendly'
import { ChatTriggerBlock } from '@/blocks/blocks/chat_trigger'
import { CirclebackBlock } from '@/blocks/blocks/circleback'
import { ClayBlock } from '@/blocks/blocks/clay'
import { ClerkBlock } from '@/blocks/blocks/clerk'
import { CloudflareBlock } from '@/blocks/blocks/cloudflare'
import { ConditionBlock } from '@/blocks/blocks/condition'
import { ConfluenceBlock, ConfluenceV2Block } from '@/blocks/blocks/confluence'
import { CursorBlock, CursorV2Block } from '@/blocks/blocks/cursor'
import { DatabricksBlock } from '@/blocks/blocks/databricks'
import { DatadogBlock } from '@/blocks/blocks/datadog'
import { DevinBlock } from '@/blocks/blocks/devin'
import { DiscordBlock } from '@/blocks/blocks/discord'
import { DocuSignBlock } from '@/blocks/blocks/docusign'
import { DropboxBlock } from '@/blocks/blocks/dropbox'
import { DSPyBlock } from '@/blocks/blocks/dspy'
import { DubBlock } from '@/blocks/blocks/dub'
import { DuckDuckGoBlock } from '@/blocks/blocks/duckduckgo'
import { DynamoDBBlock } from '@/blocks/blocks/dynamodb'
import { ElasticsearchBlock } from '@/blocks/blocks/elasticsearch'
import { ElevenLabsBlock } from '@/blocks/blocks/elevenlabs'
import { EnrichBlock } from '@/blocks/blocks/enrich'
import { EvaluatorBlock } from '@/blocks/blocks/evaluator'
import { EvernoteBlock } from '@/blocks/blocks/evernote'
import { ExaBlock } from '@/blocks/blocks/exa'
import { FathomBlock } from '@/blocks/blocks/fathom'
import { FileBlock, FileV2Block, FileV3Block } from '@/blocks/blocks/file'
import { FirecrawlBlock } from '@/blocks/blocks/firecrawl'
import { FirefliesBlock, FirefliesV2Block } from '@/blocks/blocks/fireflies'
import { FunctionBlock } from '@/blocks/blocks/function'
import { GammaBlock } from '@/blocks/blocks/gamma'
import { GenericWebhookBlock } from '@/blocks/blocks/generic_webhook'
import { GitHubBlock, GitHubV2Block } from '@/blocks/blocks/github'
import { GitLabBlock } from '@/blocks/blocks/gitlab'
import { GmailBlock, GmailV2Block } from '@/blocks/blocks/gmail'
import { GongBlock } from '@/blocks/blocks/gong'
import { GoogleSearchBlock } from '@/blocks/blocks/google'
import { GoogleAdsBlock } from '@/blocks/blocks/google_ads'
import { GoogleBigQueryBlock } from '@/blocks/blocks/google_bigquery'
import { GoogleBooksBlock } from '@/blocks/blocks/google_books'
import { GoogleCalendarBlock, GoogleCalendarV2Block } from '@/blocks/blocks/google_calendar'
import { GoogleContactsBlock } from '@/blocks/blocks/google_contacts'
import { GoogleDocsBlock } from '@/blocks/blocks/google_docs'
import { GoogleDriveBlock } from '@/blocks/blocks/google_drive'
import { GoogleFormsBlock } from '@/blocks/blocks/google_forms'
import { GoogleGroupsBlock } from '@/blocks/blocks/google_groups'
import { GoogleMapsBlock } from '@/blocks/blocks/google_maps'
import { GoogleMeetBlock } from '@/blocks/blocks/google_meet'
import { GooglePagespeedBlock } from '@/blocks/blocks/google_pagespeed'
import { GoogleSheetsBlock, GoogleSheetsV2Block } from '@/blocks/blocks/google_sheets'
import { GoogleSlidesBlock, GoogleSlidesV2Block } from '@/blocks/blocks/google_slides'
import { GoogleTasksBlock } from '@/blocks/blocks/google_tasks'
import { GoogleTranslateBlock } from '@/blocks/blocks/google_translate'
import { GoogleVaultBlock } from '@/blocks/blocks/google_vault'
import { GrafanaBlock } from '@/blocks/blocks/grafana'
import { GrainBlock } from '@/blocks/blocks/grain'
import { GreenhouseBlock } from '@/blocks/blocks/greenhouse'
import { GreptileBlock } from '@/blocks/blocks/greptile'
import { GuardrailsBlock } from '@/blocks/blocks/guardrails'
import { HexBlock } from '@/blocks/blocks/hex'
import { HubSpotBlock } from '@/blocks/blocks/hubspot'
import { HuggingFaceBlock } from '@/blocks/blocks/huggingface'
import { HumanInTheLoopBlock } from '@/blocks/blocks/human_in_the_loop'
import { HunterBlock } from '@/blocks/blocks/hunter'
import { ImageGeneratorBlock } from '@/blocks/blocks/image_generator'
import { ImapBlock } from '@/blocks/blocks/imap'
import { IncidentioBlock } from '@/blocks/blocks/incidentio'
import { InfisicalBlock } from '@/blocks/blocks/infisical'
import { InputTriggerBlock } from '@/blocks/blocks/input_trigger'
import { IntercomBlock, IntercomV2Block } from '@/blocks/blocks/intercom'
import { JinaBlock } from '@/blocks/blocks/jina'
import { JiraBlock } from '@/blocks/blocks/jira'
import { JiraServiceManagementBlock } from '@/blocks/blocks/jira_service_management'
import { KalshiBlock, KalshiV2Block } from '@/blocks/blocks/kalshi'
import { KnowledgeBlock } from '@/blocks/blocks/knowledge'
import { LangsmithBlock } from '@/blocks/blocks/langsmith'
import { LemlistBlock } from '@/blocks/blocks/lemlist'
import { LinearBlock } from '@/blocks/blocks/linear'
import { LinkedInBlock } from '@/blocks/blocks/linkedin'
import { LinkupBlock } from '@/blocks/blocks/linkup'
import { LoopsBlock } from '@/blocks/blocks/loops'
import { LumaBlock } from '@/blocks/blocks/luma'
import { MailchimpBlock } from '@/blocks/blocks/mailchimp'
import { MailgunBlock } from '@/blocks/blocks/mailgun'
import { ManualTriggerBlock } from '@/blocks/blocks/manual_trigger'
import { McpBlock } from '@/blocks/blocks/mcp'
import { Mem0Block } from '@/blocks/blocks/mem0'
import { MemoryBlock } from '@/blocks/blocks/memory'
import { MicrosoftAdBlock } from '@/blocks/blocks/microsoft_ad'
import { MicrosoftDataverseBlock } from '@/blocks/blocks/microsoft_dataverse'
import { MicrosoftExcelBlock, MicrosoftExcelV2Block } from '@/blocks/blocks/microsoft_excel'
import { MicrosoftPlannerBlock } from '@/blocks/blocks/microsoft_planner'
import { MicrosoftTeamsBlock } from '@/blocks/blocks/microsoft_teams'
import {
MistralParseBlock,
MistralParseV2Block,
MistralParseV3Block,
} from '@/blocks/blocks/mistral_parse'
import { MongoDBBlock } from '@/blocks/blocks/mongodb'
import { MothershipBlock } from '@/blocks/blocks/mothership'
import { MySQLBlock } from '@/blocks/blocks/mysql'
import { Neo4jBlock } from '@/blocks/blocks/neo4j'
import { NoteBlock } from '@/blocks/blocks/note'
import { NotionBlock, NotionV2Block } from '@/blocks/blocks/notion'
import { ObsidianBlock } from '@/blocks/blocks/obsidian'
import { OktaBlock } from '@/blocks/blocks/okta'
import { OneDriveBlock } from '@/blocks/blocks/onedrive'
import { OnePasswordBlock } from '@/blocks/blocks/onepassword'
import { OpenAIBlock } from '@/blocks/blocks/openai'
import { OutlookBlock } from '@/blocks/blocks/outlook'
import { PagerDutyBlock } from '@/blocks/blocks/pagerduty'
import { ParallelBlock } from '@/blocks/blocks/parallel'
import { PerplexityBlock } from '@/blocks/blocks/perplexity'
import { PineconeBlock } from '@/blocks/blocks/pinecone'
import { PipedriveBlock } from '@/blocks/blocks/pipedrive'
import { PolymarketBlock } from '@/blocks/blocks/polymarket'
import { PostgreSQLBlock } from '@/blocks/blocks/postgresql'
import { PostHogBlock } from '@/blocks/blocks/posthog'
import { PulseBlock, PulseV2Block } from '@/blocks/blocks/pulse'
import { QdrantBlock } from '@/blocks/blocks/qdrant'
import { RDSBlock } from '@/blocks/blocks/rds'
import { RedditBlock } from '@/blocks/blocks/reddit'
import { RedisBlock } from '@/blocks/blocks/redis'
import { ReductoBlock, ReductoV2Block } from '@/blocks/blocks/reducto'
import { ResendBlock } from '@/blocks/blocks/resend'
import { ResponseBlock } from '@/blocks/blocks/response'
import { RevenueCatBlock } from '@/blocks/blocks/revenuecat'
import { RouterBlock, RouterV2Block } from '@/blocks/blocks/router'
import { RssBlock } from '@/blocks/blocks/rss'
import { S3Block } from '@/blocks/blocks/s3'
import { SalesforceBlock } from '@/blocks/blocks/salesforce'
import { ScheduleBlock } from '@/blocks/blocks/schedule'
import { SearchBlock } from '@/blocks/blocks/search'
import { SendGridBlock } from '@/blocks/blocks/sendgrid'
import { SentryBlock } from '@/blocks/blocks/sentry'
import { SerperBlock } from '@/blocks/blocks/serper'
import { ServiceNowBlock } from '@/blocks/blocks/servicenow'
import { SftpBlock } from '@/blocks/blocks/sftp'
import { SharepointBlock } from '@/blocks/blocks/sharepoint'
import { ShopifyBlock } from '@/blocks/blocks/shopify'
import { SimilarwebBlock } from '@/blocks/blocks/similarweb'
import { SlackBlock } from '@/blocks/blocks/slack'
import { SmtpBlock } from '@/blocks/blocks/smtp'
import { SpotifyBlock } from '@/blocks/blocks/spotify'
import { SQSBlock } from '@/blocks/blocks/sqs'
import { SSHBlock } from '@/blocks/blocks/ssh'
import { StagehandBlock } from '@/blocks/blocks/stagehand'
import { StartTriggerBlock } from '@/blocks/blocks/start_trigger'
import { StarterBlock } from '@/blocks/blocks/starter'
import { StripeBlock } from '@/blocks/blocks/stripe'
import { SttBlock, SttV2Block } from '@/blocks/blocks/stt'
import { SupabaseBlock } from '@/blocks/blocks/supabase'
import { TableBlock } from '@/blocks/blocks/table'
import { TavilyBlock } from '@/blocks/blocks/tavily'
import { TelegramBlock } from '@/blocks/blocks/telegram'
import { TextractBlock, TextractV2Block } from '@/blocks/blocks/textract'
import { ThinkingBlock } from '@/blocks/blocks/thinking'
import { TinybirdBlock } from '@/blocks/blocks/tinybird'
import { TranslateBlock } from '@/blocks/blocks/translate'
import { TrelloBlock } from '@/blocks/blocks/trello'
import { TtsBlock } from '@/blocks/blocks/tts'
import { TwilioSMSBlock } from '@/blocks/blocks/twilio'
import { TwilioVoiceBlock } from '@/blocks/blocks/twilio_voice'
import { TypeformBlock } from '@/blocks/blocks/typeform'
import { UpstashBlock } from '@/blocks/blocks/upstash'
import { VariablesBlock } from '@/blocks/blocks/variables'
import { VercelBlock } from '@/blocks/blocks/vercel'
import { VideoGeneratorBlock, VideoGeneratorV2Block } from '@/blocks/blocks/video_generator'
import { VisionBlock, VisionV2Block } from '@/blocks/blocks/vision'
import { WaitBlock } from '@/blocks/blocks/wait'
import { WealthboxBlock } from '@/blocks/blocks/wealthbox'
import { WebflowBlock } from '@/blocks/blocks/webflow'
import { WebhookRequestBlock } from '@/blocks/blocks/webhook_request'
import { WhatsAppBlock } from '@/blocks/blocks/whatsapp'
import { WikipediaBlock } from '@/blocks/blocks/wikipedia'
import { WordPressBlock } from '@/blocks/blocks/wordpress'
import { WorkdayBlock } from '@/blocks/blocks/workday'
import { WorkflowBlock } from '@/blocks/blocks/workflow'
import { WorkflowInputBlock } from '@/blocks/blocks/workflow_input'
import { XBlock } from '@/blocks/blocks/x'
import { YouTubeBlock } from '@/blocks/blocks/youtube'
import { ZendeskBlock } from '@/blocks/blocks/zendesk'
import { ZepBlock } from '@/blocks/blocks/zep'
import { ZoomBlock } from '@/blocks/blocks/zoom'
import type { BlockConfig } from '@/blocks/types'
// Registry of all available blocks, alphabetically sorted
export const registry: Record<string, BlockConfig> = {
a2a: A2ABlock,
agent: AgentBlock,
ahrefs: AhrefsBlock,
airtable: AirtableBlock,
airweave: AirweaveBlock,
algolia: AlgoliaBlock,
amplitude: AmplitudeBlock,
api: ApiBlock,
api_trigger: ApiTriggerBlock,
apify: ApifyBlock,
apollo: ApolloBlock,
arxiv: ArxivBlock,
asana: AsanaBlock,
ashby: AshbyBlock,
attio: AttioBlock,
brandfetch: BrandfetchBlock,
box: BoxBlock,
browser_use: BrowserUseBlock,
calcom: CalComBlock,
calendly: CalendlyBlock,
chat_trigger: ChatTriggerBlock,
circleback: CirclebackBlock,
cloudflare: CloudflareBlock,
clay: ClayBlock,
clerk: ClerkBlock,
condition: ConditionBlock,
confluence: ConfluenceBlock,
confluence_v2: ConfluenceV2Block,
cursor: CursorBlock,
cursor_v2: CursorV2Block,
databricks: DatabricksBlock,
datadog: DatadogBlock,
devin: DevinBlock,
discord: DiscordBlock,
docusign: DocuSignBlock,
dropbox: DropboxBlock,
dspy: DSPyBlock,
dub: DubBlock,
duckduckgo: DuckDuckGoBlock,
dynamodb: DynamoDBBlock,
elasticsearch: ElasticsearchBlock,
elevenlabs: ElevenLabsBlock,
fathom: FathomBlock,
enrich: EnrichBlock,
evernote: EvernoteBlock,
evaluator: EvaluatorBlock,
exa: ExaBlock,
file: FileBlock,
file_v2: FileV2Block,
file_v3: FileV3Block,
firecrawl: FirecrawlBlock,
fireflies: FirefliesBlock,
fireflies_v2: FirefliesV2Block,
function: FunctionBlock,
gamma: GammaBlock,
generic_webhook: GenericWebhookBlock,
github: GitHubBlock,
github_v2: GitHubV2Block,
gitlab: GitLabBlock,
gmail: GmailBlock,
gmail_v2: GmailV2Block,
google_calendar: GoogleCalendarBlock,
google_calendar_v2: GoogleCalendarV2Block,
google_ads: GoogleAdsBlock,
google_books: GoogleBooksBlock,
google_contacts: GoogleContactsBlock,
google_docs: GoogleDocsBlock,
google_drive: GoogleDriveBlock,
google_forms: GoogleFormsBlock,
google_groups: GoogleGroupsBlock,
google_meet: GoogleMeetBlock,
google_maps: GoogleMapsBlock,
google_pagespeed: GooglePagespeedBlock,
google_tasks: GoogleTasksBlock,
google_translate: GoogleTranslateBlock,
gong: GongBlock,
google_search: GoogleSearchBlock,
google_sheets: GoogleSheetsBlock,
google_sheets_v2: GoogleSheetsV2Block,
google_slides: GoogleSlidesBlock,
google_slides_v2: GoogleSlidesV2Block,
google_bigquery: GoogleBigQueryBlock,
google_vault: GoogleVaultBlock,
grafana: GrafanaBlock,
grain: GrainBlock,
greenhouse: GreenhouseBlock,
greptile: GreptileBlock,
guardrails: GuardrailsBlock,
hex: HexBlock,
hubspot: HubSpotBlock,
huggingface: HuggingFaceBlock,
human_in_the_loop: HumanInTheLoopBlock,
hunter: HunterBlock,
image_generator: ImageGeneratorBlock,
imap: ImapBlock,
incidentio: IncidentioBlock,
infisical: InfisicalBlock,
input_trigger: InputTriggerBlock,
intercom: IntercomBlock,
intercom_v2: IntercomV2Block,
jina: JinaBlock,
jira: JiraBlock,
jira_service_management: JiraServiceManagementBlock,
kalshi: KalshiBlock,
kalshi_v2: KalshiV2Block,
knowledge: KnowledgeBlock,
langsmith: LangsmithBlock,
lemlist: LemlistBlock,
linear: LinearBlock,
linkedin: LinkedInBlock,
linkup: LinkupBlock,
loops: LoopsBlock,
luma: LumaBlock,
mailchimp: MailchimpBlock,
mailgun: MailgunBlock,
manual_trigger: ManualTriggerBlock,
mcp: McpBlock,
mem0: Mem0Block,
memory: MemoryBlock,
microsoft_ad: MicrosoftAdBlock,
microsoft_dataverse: MicrosoftDataverseBlock,
microsoft_excel: MicrosoftExcelBlock,
microsoft_excel_v2: MicrosoftExcelV2Block,
microsoft_planner: MicrosoftPlannerBlock,
microsoft_teams: MicrosoftTeamsBlock,
mistral_parse: MistralParseBlock,
mistral_parse_v2: MistralParseV2Block,
mistral_parse_v3: MistralParseV3Block,
mongodb: MongoDBBlock,
mothership: MothershipBlock,
mysql: MySQLBlock,
neo4j: Neo4jBlock,
note: NoteBlock,
notion: NotionBlock,
notion_v2: NotionV2Block,
obsidian: ObsidianBlock,
okta: OktaBlock,
onepassword: OnePasswordBlock,
onedrive: OneDriveBlock,
openai: OpenAIBlock,
outlook: OutlookBlock,
pagerduty: PagerDutyBlock,
parallel_ai: ParallelBlock,
perplexity: PerplexityBlock,
pinecone: PineconeBlock,
pipedrive: PipedriveBlock,
polymarket: PolymarketBlock,
postgresql: PostgreSQLBlock,
posthog: PostHogBlock,
pulse: PulseBlock,
pulse_v2: PulseV2Block,
qdrant: QdrantBlock,
rds: RDSBlock,
reddit: RedditBlock,
redis: RedisBlock,
reducto: ReductoBlock,
reducto_v2: ReductoV2Block,
resend: ResendBlock,
response: ResponseBlock,
revenuecat: RevenueCatBlock,
router: RouterBlock,
router_v2: RouterV2Block,
rss: RssBlock,
s3: S3Block,
salesforce: SalesforceBlock,
schedule: ScheduleBlock,
search: SearchBlock,
sendgrid: SendGridBlock,
sentry: SentryBlock,
serper: SerperBlock,
servicenow: ServiceNowBlock,
sftp: SftpBlock,
sharepoint: SharepointBlock,
shopify: ShopifyBlock,
similarweb: SimilarwebBlock,
slack: SlackBlock,
smtp: SmtpBlock,
spotify: SpotifyBlock,
sqs: SQSBlock,
ssh: SSHBlock,
stagehand: StagehandBlock,
start_trigger: StartTriggerBlock,
starter: StarterBlock,
stripe: StripeBlock,
stt: SttBlock,
stt_v2: SttV2Block,
supabase: SupabaseBlock,
table: TableBlock,
tavily: TavilyBlock,
telegram: TelegramBlock,
textract: TextractBlock,
textract_v2: TextractV2Block,
thinking: ThinkingBlock,
tinybird: TinybirdBlock,
translate: TranslateBlock,
trello: TrelloBlock,
tts: TtsBlock,
twilio_sms: TwilioSMSBlock,
twilio_voice: TwilioVoiceBlock,
typeform: TypeformBlock,
upstash: UpstashBlock,
vercel: VercelBlock,
variables: VariablesBlock,
video_generator: VideoGeneratorBlock,
video_generator_v2: VideoGeneratorV2Block,
vision: VisionBlock,
vision_v2: VisionV2Block,
wait: WaitBlock,
wealthbox: WealthboxBlock,
webflow: WebflowBlock,
webhook_request: WebhookRequestBlock,
whatsapp: WhatsAppBlock,
wikipedia: WikipediaBlock,
wordpress: WordPressBlock,
workday: WorkdayBlock,
workflow: WorkflowBlock,
workflow_input: WorkflowInputBlock,
x: XBlock,
youtube: YouTubeBlock,
zendesk: ZendeskBlock,
zep: ZepBlock,
zoom: ZoomBlock,
}
export const getBlock = (type: string): BlockConfig | undefined => {
if (registry[type]) {
return registry[type]
}
const normalized = type.replace(/-/g, '_')
return registry[normalized]
}
export const getLatestBlock = (baseType: string): BlockConfig | undefined => {
const normalized = baseType.replace(/-/g, '_')
const versionedKeys = Object.keys(registry).filter((key) => {
const match = key.match(new RegExp(`^${normalized}_v(\\d+)$`))
return match !== null
})
if (versionedKeys.length > 0) {
const sorted = versionedKeys.sort((a, b) => {
const versionA = Number.parseInt(a.match(/_v(\d+)$/)?.[1] || '0', 10)
const versionB = Number.parseInt(b.match(/_v(\d+)$/)?.[1] || '0', 10)
return versionB - versionA
})
return registry[sorted[0]]
}
return registry[normalized]
}
export const getBlockByToolName = (toolName: string): BlockConfig | undefined => {
return Object.values(registry).find((block) => block.tools?.access?.includes(toolName))
}
export const getBlocksByCategory = (category: 'blocks' | 'tools' | 'triggers'): BlockConfig[] =>
Object.values(registry).filter((block) => block.category === category)
export const getAllBlockTypes = (): string[] => Object.keys(registry)
export const isValidBlockType = (type: string): type is string =>
type in registry || type.replace(/-/g, '_') in registry
export const getAllBlocks = (): BlockConfig[] => Object.values(registry)