{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "feature-interactive-api-curl-builder",
  "title": "Feature Interactive Api Curl Builder",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-angular/blocks/feature-interactive-api-curl-builder/feature-interactive-api-curl-builder.component.ts",
      "content": "// Interactive edge API console: endpoint + payload flag config on the left, live multi-language\n// snippet generation (cURL / Fetch / Python / Go) with copy on the right, and a simulated HTTP\n// response payload. Port of the React block 1:1.\nimport { ChangeDetectionStrategy, Component, Input, computed, signal } from '@angular/core'\nimport { ArrowRight, Check, Copy, Globe, LucideAngularModule, Play, Terminal } from 'lucide-angular'\nimport { cn } from '@/lib/utils'\nimport { UiBadgeComponent } from '@/ui/badge/badge.component'\nimport { UiButtonComponent } from '@/ui/button/button.component'\nimport { UiCardComponent, UiCardContentComponent } from '@/ui/card/card.component'\n\nexport type CurlHttpMethod = 'GET' | 'POST'\nexport type CurlLanguage = 'curl' | 'javascript' | 'python' | 'go'\n\nexport interface CurlExecutionData {\n  bundleId: string\n  name: string\n  frameworks: string[]\n  astCompiled: boolean\n  sizeBytes: number\n  oklchTokensInlined: number\n  edgeDeliveryTime: string\n}\n\nexport interface CurlExecutionResult {\n  status: number\n  latencyMs: number\n  data: CurlExecutionData\n}\n\nexport const CURL_ENDPOINTS = ['/v1/components/bundle', '/v1/tokens/compile'] as const\n\nexport const CURL_LANGUAGES: { id: CurlLanguage; label: string }[] = [\n  { id: 'curl', label: 'cURL' },\n  { id: 'javascript', label: 'Fetch' },\n  { id: 'python', label: 'Python' },\n  { id: 'go', label: 'Go' },\n]\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-feature-interactive-api-curl-builder, [ui-feature-interactive-api-curl-builder]',\n  standalone: true,\n  // React renders the root <section> itself: the host stays out of layout and `class` goes to the root.\n  host: { '[attr.class]': '\"contents\"' },\n  imports: [LucideAngularModule, UiBadgeComponent, UiButtonComponent, UiCardComponent, UiCardContentComponent],\n  template: `\n    <section data-slot=\"feature-interactive-api-curl-builder\" [class]=\"rootClass\">\n      <div class=\"mx-auto max-w-7xl px-4 sm:px-6 lg:px-8\">\n        <!-- Section Header -->\n        <div class=\"mx-auto max-w-3xl space-y-4 text-center\">\n          <a\n            href=\"#api-builder\"\n            class=\"group border-border/80 bg-secondary/60 hover:bg-secondary text-foreground inline-flex items-center gap-2 rounded-full border px-3.5 py-1 text-xs font-medium shadow-2xs transition-colors\"\n          >\n            <lucide-icon [img]=\"Globe\" class=\"text-primary size-3.5\" />\n            <span>Interactive Edge API Console</span>\n            <lucide-icon\n              [img]=\"ArrowRight\"\n              class=\"text-muted-foreground size-3 transition-transform group-hover:translate-x-0.5\"\n            />\n          </a>\n\n          <h2 class=\"text-foreground text-3xl font-bold tracking-tight sm:text-4xl\">{{ title }}</h2>\n\n          <p class=\"text-muted-foreground text-base sm:text-lg\">{{ description }}</p>\n        </div>\n\n        <!-- API Builder Workbench -->\n        <div class=\"mt-12 grid grid-cols-1 gap-6 lg:grid-cols-12\">\n          <!-- Left Config Parameters (5 cols) -->\n          <div class=\"space-y-4 lg:col-span-5\">\n            <div ui-card class=\"border-border bg-card shadow-xs\">\n              <div ui-card-content class=\"space-y-5 p-6\">\n                <div class=\"border-border flex items-center justify-between border-b pb-3\">\n                  <span class=\"text-muted-foreground text-xs font-bold tracking-wider uppercase\"\n                    >Request Parameters</span\n                  >\n                  <span\n                    ui-badge\n                    variant=\"outline\"\n                    class=\"border-success/30 bg-success/10 text-success font-mono text-xs\"\n                  >\n                    Edge v1\n                  </span>\n                </div>\n\n                <!-- Endpoint Selector -->\n                <div class=\"space-y-2\">\n                  <label class=\"text-foreground text-xs font-bold\">Endpoint Path</label>\n                  <div class=\"border-border bg-muted/40 flex rounded-lg border p-1\">\n                    @for (ep of endpoints; track ep) {\n                      <button\n                        type=\"button\"\n                        [class]=\"endpointClass(ep)\"\n                        class=\"flex-1 rounded-md py-1 font-mono text-xs transition-colors\"\n                        (click)=\"selectEndpoint(ep)\"\n                      >\n                        {{ ep }}\n                      </button>\n                    }\n                  </div>\n                </div>\n\n                <!-- Payload Toggles -->\n                <div class=\"space-y-2.5 pt-2\">\n                  <label class=\"text-foreground text-xs font-bold\">Payload Flags</label>\n                  <div class=\"space-y-2\">\n                    <label\n                      class=\"border-border/80 bg-background hover:bg-muted/20 flex cursor-pointer items-center justify-between rounded-lg border p-3 text-xs\"\n                    >\n                      <span class=\"text-muted-foreground\">Emit AST Syntax Tree</span>\n                      <input\n                        type=\"checkbox\"\n                        [checked]=\"enableAstTree()\"\n                        (change)=\"enableAstTree.set($any($event.target).checked)\"\n                        class=\"accent-primary size-4 cursor-pointer\"\n                      />\n                    </label>\n                    <label\n                      class=\"border-border/80 bg-background hover:bg-muted/20 flex cursor-pointer items-center justify-between rounded-lg border p-3 text-xs\"\n                    >\n                      <span class=\"text-muted-foreground\">Inline OKLCH CSS Tokens</span>\n                      <input\n                        type=\"checkbox\"\n                        [checked]=\"enableOklchTokens()\"\n                        (change)=\"enableOklchTokens.set($any($event.target).checked)\"\n                        class=\"accent-primary size-4 cursor-pointer\"\n                      />\n                    </label>\n                  </div>\n                </div>\n\n                <button ui-button class=\"w-full gap-2 shadow-xs\" [disabled]=\"isExecuting()\" (click)=\"executeRequest()\">\n                  <lucide-icon [img]=\"Play\" class=\"fill-primary-foreground size-3.5\" />\n                  <span>{{ isExecuting() ? 'Executing Edge Call...' : 'Send Live HTTP Request' }}</span>\n                </button>\n              </div>\n            </div>\n          </div>\n\n          <!-- Right Code Preview & Simulated Response (7 cols) -->\n          <div class=\"space-y-4 lg:col-span-7\">\n            <div ui-card class=\"border-border bg-card overflow-hidden font-mono text-xs shadow-xs\">\n              <!-- Language Selector Tabs -->\n              <div class=\"border-border bg-muted/40 flex items-center justify-between border-b px-4 py-2\">\n                <div class=\"flex items-center gap-1\">\n                  @for (lang of languages; track lang.id) {\n                    <button\n                      type=\"button\"\n                      [class]=\"languageClass(lang.id)\"\n                      class=\"rounded px-2.5 py-1 text-xs transition-colors\"\n                      (click)=\"selectLanguage(lang.id)\"\n                    >\n                      {{ lang.label }}\n                    </button>\n                  }\n                </div>\n\n                <button\n                  type=\"button\"\n                  class=\"text-muted-foreground hover:text-foreground inline-flex items-center gap-1 text-xs transition-colors\"\n                  (click)=\"copySnippet()\"\n                >\n                  @if (copiedSnippet()) {\n                    <lucide-icon [img]=\"Check\" class=\"text-success size-3\" />\n                  } @else {\n                    <lucide-icon [img]=\"Copy\" class=\"size-3\" />\n                  }\n                  <span>{{ copiedSnippet() ? 'Copied' : 'Copy' }}</span>\n                </button>\n              </div>\n\n              <div ui-card-content class=\"bg-muted/10 p-4\">\n                <pre\n                  class=\"text-foreground overflow-x-auto text-xs leading-relaxed\"\n                ><code>{{ generatedCode() }}</code></pre>\n              </div>\n            </div>\n\n            <!-- Simulated Live HTTP Response -->\n            <div class=\"border-border bg-muted/30 space-y-2 rounded-xl border p-4 font-mono text-xs\">\n              <div class=\"border-border/80 flex items-center justify-between border-b pb-2\">\n                <div class=\"flex items-center gap-2\">\n                  <lucide-icon [img]=\"Terminal\" class=\"text-primary size-3.5\" />\n                  <span class=\"text-foreground font-bold\">Response Payload</span>\n                </div>\n                <div class=\"flex items-center gap-3 text-xs\">\n                  <span class=\"text-success font-bold\">HTTP {{ executionResult().status }} OK</span>\n                  <span class=\"text-muted-foreground\">{{ executionResult().latencyMs }}ms</span>\n                </div>\n              </div>\n              <pre\n                class=\"text-muted-foreground overflow-x-auto text-xs leading-relaxed\"\n              ><code>{{ responseJson() }}</code></pre>\n            </div>\n          </div>\n        </div>\n      </div>\n    </section>\n  `,\n})\nexport class UiFeatureInteractiveApiCurlBuilderComponent {\n  protected readonly ArrowRight = ArrowRight\n  protected readonly Check = Check\n  protected readonly Copy = Copy\n  protected readonly Globe = Globe\n  protected readonly Play = Play\n  protected readonly Terminal = Terminal\n\n  protected readonly endpoints: readonly string[] = CURL_ENDPOINTS\n  protected readonly languages = CURL_LANGUAGES\n\n  @Input() title = 'Composable REST APIs designed for programmatic automation.'\n  @Input() description =\n    'Synthesize type-safe HTTP payloads, test endpoints in real time, and export snippets directly to your production workflow.'\n  @Input('class') className?: string\n\n  readonly selectedMethod = signal<CurlHttpMethod>('POST')\n  readonly selectedEndpoint = signal<string>('/v1/components/bundle')\n  readonly selectedLanguage = signal<CurlLanguage>('curl')\n  readonly enableAstTree = signal(true)\n  readonly enableOklchTokens = signal(true)\n  readonly copiedSnippet = signal(false)\n  readonly isExecuting = signal(false)\n  readonly executionResult = signal<CurlExecutionResult>({\n    status: 200,\n    latencyMs: 14,\n    data: {\n      bundleId: 'pkg_9981x2',\n      name: 'button',\n      frameworks: ['vue', 'react'],\n      astCompiled: true,\n      sizeBytes: 1480,\n      oklchTokensInlined: 48,\n      edgeDeliveryTime: '0.8ms',\n    },\n  })\n  private copyTimer: ReturnType<typeof setTimeout> | undefined\n\n  readonly generatedCode = computed(() => {\n    const method = this.selectedMethod()\n    const endpoint = this.selectedEndpoint()\n    const language = this.selectedLanguage()\n    const payload = JSON.stringify(\n      {\n        component: 'button',\n        framework: 'vue',\n        astTree: this.enableAstTree(),\n        inlineTokens: this.enableOklchTokens(),\n      },\n      null,\n      2,\n    )\n\n    if (language === 'curl') {\n      return `curl -X ${method} https://api.uipkge.dev${endpoint} \\\\\n  -H \"Authorization: Bearer uipkge_sec_89201\" \\\\\n  -H \"Content-Type: application/json\" \\\\\n  -d '${payload.replace(/\\n/g, '\\n  ')}'`\n    }\n\n    if (language === 'javascript') {\n      return `const res = await fetch(\"https://api.uipkge.dev${endpoint}\", {\n  method: \"${method}\",\n  headers: {\n    \"Authorization\": \"Bearer uipkge_sec_89201\",\n    \"Content-Type\": \"application/json\"\n  },\n  body: JSON.stringify(${payload})\n});\nconst data = await res.json();`\n    }\n\n    if (language === 'python') {\n      return `import requests\n\nres = requests.${method.toLowerCase()}(\n    \"https://api.uipkge.dev${endpoint}\",\n    headers={\"Authorization\": \"Bearer uipkge_sec_89201\"},\n    json=${payload.replace(/true/g, 'True').replace(/false/g, 'False')}\n)\ndata = res.json()`\n    }\n\n    return `// Go HTTP Request\nreq, _ := http.NewRequest(\"${method}\", \"https://api.uipkge.dev${endpoint}\", payload)\nreq.Header.Set(\"Authorization\", \"Bearer uipkge_sec_89201\")\nres, _ := client.Do(req)`\n  })\n\n  readonly responseJson = computed(() => JSON.stringify(this.executionResult().data, null, 2))\n\n  get rootClass(): string {\n    return cn('bg-background relative overflow-hidden py-16 sm:py-24', this.className)\n  }\n\n  endpointClass(ep: string): string {\n    return cn(\n      this.selectedEndpoint() === ep\n        ? 'bg-background text-foreground font-bold shadow-2xs'\n        : 'text-muted-foreground hover:text-foreground',\n    )\n  }\n\n  languageClass(lang: CurlLanguage): string {\n    return cn(\n      this.selectedLanguage() === lang\n        ? 'bg-background text-foreground font-bold shadow-2xs'\n        : 'text-muted-foreground hover:text-foreground',\n    )\n  }\n\n  selectEndpoint(ep: string): void {\n    this.selectedEndpoint.set(ep)\n  }\n\n  selectLanguage(lang: CurlLanguage): void {\n    this.selectedLanguage.set(lang)\n  }\n\n  async copySnippet(): Promise<void> {\n    try {\n      await navigator.clipboard.writeText(this.generatedCode())\n      this.copiedSnippet.set(true)\n      clearTimeout(this.copyTimer)\n      this.copyTimer = setTimeout(() => this.copiedSnippet.set(false), 2000)\n    } catch {\n      // Clipboard unavailable (insecure context / jsdom): leave the label unchanged.\n    }\n  }\n\n  executeRequest(): void {\n    if (this.isExecuting()) return\n    this.isExecuting.set(true)\n    setTimeout(() => {\n      this.isExecuting.set(false)\n      const endpoint = this.selectedEndpoint()\n      const ast = this.enableAstTree()\n      const tokens = this.enableOklchTokens()\n      this.executionResult.set({\n        status: 200,\n        latencyMs: Math.floor(Math.random() * 8) + 11,\n        data: {\n          bundleId: `pkg_${Math.random().toString(36).substring(2, 8)}`,\n          name: endpoint.includes('bundle') ? 'button' : 'tokens',\n          frameworks: ['vue', 'react'],\n          astCompiled: ast,\n          sizeBytes: ast ? 1480 : 1120,\n          oklchTokensInlined: tokens ? 48 : 0,\n          edgeDeliveryTime: '0.8ms',\n        },\n      })\n    }, 350)\n  }\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/feature-interactive-api-curl-builder/feature-interactive-api-curl-builder.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/feature-interactive-api-curl-builder/index.ts",
      "content": "export {\n  UiFeatureInteractiveApiCurlBuilderComponent,\n  CURL_ENDPOINTS,\n  CURL_LANGUAGES,\n  type CurlHttpMethod,\n  type CurlLanguage,\n  type CurlExecutionData,\n  type CurlExecutionResult,\n} from './feature-interactive-api-curl-builder.component'\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/feature-interactive-api-curl-builder/index.ts"
    }
  ],
  "dependencies": [
    "lucide-angular"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/angular/badge.json",
    "https://uipkge.dev/r/angular/button.json",
    "https://uipkge.dev/r/angular/card.json"
  ],
  "description": "Interactive API cURL builder and live payload testing sandbox with multi-language code export.",
  "categories": [
    "feature",
    "marketing"
  ]
}