{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "database-schema-viewer",
  "title": "Database Schema Viewer",
  "type": "registry:page",
  "files": [
    {
      "path": "packages/registry-angular/blocks/database-schema-viewer/database-schema-viewer.component.ts",
      "content": "// Visual database schema inspector: cluster health header with search + Export DDL,\n// table navigation sidebar with row counts, column metadata table (types, nullability,\n// defaults, PK/FK indicators), foreign-key relations, B-Tree indexes, and a DDL preview\n// with copy actions. Port of the React block 1:1.\nimport { ChangeDetectionStrategy, Component, Input, computed, signal } from '@angular/core'\nimport {\n  ArrowRight,\n  Check,\n  Clock,\n  Code2,\n  Copy,\n  Database,\n  Download,\n  HardDrive,\n  Key,\n  Layers,\n  Link2,\n  LucideAngularModule,\n  Search,\n  Table2,\n} from 'lucide-angular'\nimport { cn } from '@/lib/utils'\nimport { UiBadgeComponent } from '@/ui/badge/badge.component'\nimport { UiButtonComponent } from '@/ui/button/button.component'\nimport { UiCardComponent } from '@/ui/card/card.component'\nimport { UiInputComponent } from '@/ui/input/input.component'\nimport { UiSeparatorComponent } from '@/ui/separator/separator.component'\nimport {\n  UiTableBodyComponent,\n  UiTableCellComponent,\n  UiTableComponent,\n  UiTableHeadComponent,\n  UiTableHeaderComponent,\n  UiTableRowComponent,\n} from '@/ui/table/table.component'\nimport {\n  UiTabsComponent,\n  UiTabsContentComponent,\n  UiTabsListComponent,\n  UiTabsTriggerComponent,\n} from '@/ui/tabs/tabs.component'\n\nexport interface SchemaColumnDefinition {\n  name: string\n  type: string\n  nullable: boolean\n  defaultValue: string | null\n  isPrimaryKey?: boolean\n  isForeignKey?: boolean\n  foreignKeyRef?: string\n  description?: string\n}\n\nexport interface SchemaForeignKeyDefinition {\n  name: string\n  column: string\n  foreignTable: string\n  foreignColumn: string\n  onDelete: 'CASCADE' | 'RESTRICT' | 'SET NULL' | 'NO ACTION'\n  onUpdate: 'CASCADE' | 'RESTRICT' | 'SET NULL' | 'NO ACTION'\n}\n\nexport interface SchemaIndexDefinition {\n  name: string\n  type: 'B-Tree' | 'GIN' | 'GiST' | 'Hash'\n  columns: string[]\n  size: string\n  isUnique?: boolean\n  isPrimary?: boolean\n}\n\nexport interface SchemaTable {\n  name: string\n  schema: string\n  rowCount: number\n  rowCountFormatted: string\n  size: string\n  primaryKey: string\n  lastAnalyzed: string\n  description: string\n  columns: SchemaColumnDefinition[]\n  foreignKeys: SchemaForeignKeyDefinition[]\n  indexes: SchemaIndexDefinition[]\n  ddl: string\n}\n\nconst schemaTables: SchemaTable[] = [\n  {\n    name: 'users',\n    schema: 'public',\n    rowCount: 42850,\n    rowCountFormatted: '42,850 rows',\n    size: '18.4 MB',\n    primaryKey: 'id (UUID)',\n    lastAnalyzed: '12 mins ago',\n    description: 'User accounts, authentication identities, role assignments, and profile metadata.',\n    columns: [\n      {\n        name: 'id',\n        type: 'uuid',\n        nullable: false,\n        defaultValue: 'gen_random_uuid()',\n        isPrimaryKey: true,\n        description: 'Unique identifier for the user',\n      },\n      {\n        name: 'email',\n        type: 'varchar(255)',\n        nullable: false,\n        defaultValue: null,\n        description: 'Verified primary contact email',\n      },\n      {\n        name: 'encrypted_password',\n        type: 'varchar(255)',\n        nullable: false,\n        defaultValue: null,\n        description: 'Bcrypt hashed password digest',\n      },\n      {\n        name: 'full_name',\n        type: 'varchar(100)',\n        nullable: true,\n        defaultValue: null,\n        description: 'Display name or legal identity',\n      },\n      {\n        name: 'role',\n        type: 'varchar(32)',\n        nullable: false,\n        defaultValue: \"'member'\",\n        description: 'System authorization role',\n      },\n      {\n        name: 'avatar_url',\n        type: 'text',\n        nullable: true,\n        defaultValue: null,\n        description: 'Remote profile avatar image URL',\n      },\n      {\n        name: 'is_verified',\n        type: 'boolean',\n        nullable: false,\n        defaultValue: 'false',\n        description: 'Email verification status flag',\n      },\n      {\n        name: 'created_at',\n        type: 'timestamptz',\n        nullable: false,\n        defaultValue: 'CURRENT_TIMESTAMP',\n        description: 'Account creation timestamp',\n      },\n      {\n        name: 'updated_at',\n        type: 'timestamptz',\n        nullable: false,\n        defaultValue: 'CURRENT_TIMESTAMP',\n        description: 'Last record modification timestamp',\n      },\n    ],\n    foreignKeys: [],\n    indexes: [\n      { name: 'users_pkey', type: 'B-Tree', columns: ['id'], size: '1.2 MB', isPrimary: true, isUnique: true },\n      { name: 'idx_users_email', type: 'B-Tree', columns: ['email'], size: '940 KB', isUnique: true },\n      { name: 'idx_users_role_created', type: 'B-Tree', columns: ['role', 'created_at DESC'], size: '1.8 MB' },\n    ],\n    ddl: `CREATE TABLE public.users (\n  id uuid PRIMARY KEY DEFAULT gen_random_uuid(),\n  email varchar(255) NOT NULL UNIQUE,\n  encrypted_password varchar(255) NOT NULL,\n  full_name varchar(100),\n  role varchar(32) NOT NULL DEFAULT 'member',\n  avatar_url text,\n  is_verified boolean NOT NULL DEFAULT false,\n  created_at timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP,\n  updated_at timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP,\n  CONSTRAINT chk_users_role CHECK (role IN ('admin', 'member', 'viewer'))\n);`,\n  },\n  {\n    name: 'orders',\n    schema: 'public',\n    rowCount: 148290,\n    rowCountFormatted: '148,290 rows',\n    size: '64.2 MB',\n    primaryKey: 'id (UUID)',\n    lastAnalyzed: '2 mins ago',\n    description: 'Customer transactional purchase orders, fulfillment status, and payment totals.',\n    columns: [\n      {\n        name: 'id',\n        type: 'uuid',\n        nullable: false,\n        defaultValue: 'gen_random_uuid()',\n        isPrimaryKey: true,\n        description: 'Unique order identifier',\n      },\n      {\n        name: 'order_number',\n        type: 'varchar(48)',\n        nullable: false,\n        defaultValue: null,\n        description: 'Human-readable sequential invoice reference',\n      },\n      {\n        name: 'user_id',\n        type: 'uuid',\n        nullable: false,\n        defaultValue: null,\n        isForeignKey: true,\n        foreignKeyRef: 'users.id',\n        description: 'Purchaser account reference',\n      },\n      {\n        name: 'status',\n        type: 'varchar(32)',\n        nullable: false,\n        defaultValue: \"'pending'\",\n        description: 'Order lifecycle stage',\n      },\n      {\n        name: 'total_amount',\n        type: 'numeric(10,2)',\n        nullable: false,\n        defaultValue: '0.00',\n        description: 'Grand total charged in base currency',\n      },\n      {\n        name: 'currency',\n        type: 'varchar(3)',\n        nullable: false,\n        defaultValue: \"'USD'\",\n        description: 'ISO 4217 three-letter currency code',\n      },\n      {\n        name: 'billing_address',\n        type: 'jsonb',\n        nullable: true,\n        defaultValue: \"'{}'::jsonb\",\n        description: 'Structured billing snapshot',\n      },\n      {\n        name: 'shipping_address',\n        type: 'jsonb',\n        nullable: true,\n        defaultValue: \"'{}'::jsonb\",\n        description: 'Structured destination address',\n      },\n      {\n        name: 'shipped_at',\n        type: 'timestamptz',\n        nullable: true,\n        defaultValue: null,\n        description: 'Carrier pickup confirmation date',\n      },\n      {\n        name: 'created_at',\n        type: 'timestamptz',\n        nullable: false,\n        defaultValue: 'CURRENT_TIMESTAMP',\n        description: 'Checkout completion timestamp',\n      },\n      {\n        name: 'updated_at',\n        type: 'timestamptz',\n        nullable: false,\n        defaultValue: 'CURRENT_TIMESTAMP',\n        description: 'Order state mutation timestamp',\n      },\n    ],\n    foreignKeys: [\n      {\n        name: 'fk_orders_user_id',\n        column: 'user_id',\n        foreignTable: 'users',\n        foreignColumn: 'id',\n        onDelete: 'CASCADE',\n        onUpdate: 'CASCADE',\n      },\n    ],\n    indexes: [\n      { name: 'orders_pkey', type: 'B-Tree', columns: ['id'], size: '4.8 MB', isPrimary: true, isUnique: true },\n      { name: 'idx_orders_user_id', type: 'B-Tree', columns: ['user_id'], size: '3.4 MB' },\n      { name: 'idx_orders_status_created', type: 'B-Tree', columns: ['status', 'created_at DESC'], size: '5.1 MB' },\n      { name: 'idx_orders_number_unique', type: 'B-Tree', columns: ['order_number'], size: '3.2 MB', isUnique: true },\n    ],\n    ddl: `CREATE TABLE public.orders (\n  id uuid PRIMARY KEY DEFAULT gen_random_uuid(),\n  order_number varchar(48) NOT NULL UNIQUE,\n  user_id uuid NOT NULL REFERENCES public.users(id) ON DELETE CASCADE ON UPDATE CASCADE,\n  status varchar(32) NOT NULL DEFAULT 'pending',\n  total_amount numeric(10,2) NOT NULL DEFAULT 0.00,\n  currency varchar(3) NOT NULL DEFAULT 'USD',\n  billing_address jsonb DEFAULT '{}'::jsonb,\n  shipping_address jsonb DEFAULT '{}'::jsonb,\n  shipped_at timestamptz,\n  created_at timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP,\n  updated_at timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP\n);`,\n  },\n  {\n    name: 'order_items',\n    schema: 'public',\n    rowCount: 384120,\n    rowCountFormatted: '384,120 rows',\n    size: '112.5 MB',\n    primaryKey: 'id (UUID)',\n    lastAnalyzed: '8 mins ago',\n    description: 'Granular line items and unit pricing linked to purchase orders.',\n    columns: [\n      {\n        name: 'id',\n        type: 'uuid',\n        nullable: false,\n        defaultValue: 'gen_random_uuid()',\n        isPrimaryKey: true,\n        description: 'Line item primary key',\n      },\n      {\n        name: 'order_id',\n        type: 'uuid',\n        nullable: false,\n        defaultValue: null,\n        isForeignKey: true,\n        foreignKeyRef: 'orders.id',\n        description: 'Parent order reference',\n      },\n      {\n        name: 'product_id',\n        type: 'uuid',\n        nullable: false,\n        defaultValue: null,\n        isForeignKey: true,\n        foreignKeyRef: 'products.id',\n        description: 'Catalog item reference',\n      },\n      { name: 'quantity', type: 'integer', nullable: false, defaultValue: '1', description: 'Units purchased' },\n      {\n        name: 'unit_price',\n        type: 'numeric(10,2)',\n        nullable: false,\n        defaultValue: '0.00',\n        description: 'Unit price captured at purchase',\n      },\n      {\n        name: 'discount_amount',\n        type: 'numeric(10,2)',\n        nullable: false,\n        defaultValue: '0.00',\n        description: 'Item level discount applied',\n      },\n      {\n        name: 'created_at',\n        type: 'timestamptz',\n        nullable: false,\n        defaultValue: 'CURRENT_TIMESTAMP',\n        description: 'Record insertion timestamp',\n      },\n    ],\n    foreignKeys: [\n      {\n        name: 'fk_order_items_order_id',\n        column: 'order_id',\n        foreignTable: 'orders',\n        foreignColumn: 'id',\n        onDelete: 'CASCADE',\n        onUpdate: 'CASCADE',\n      },\n      {\n        name: 'fk_order_items_product_id',\n        column: 'product_id',\n        foreignTable: 'products',\n        foreignColumn: 'id',\n        onDelete: 'RESTRICT',\n        onUpdate: 'CASCADE',\n      },\n    ],\n    indexes: [\n      { name: 'order_items_pkey', type: 'B-Tree', columns: ['id'], size: '12.1 MB', isPrimary: true, isUnique: true },\n      { name: 'idx_order_items_order_id', type: 'B-Tree', columns: ['order_id'], size: '8.9 MB' },\n      { name: 'idx_order_items_product_id', type: 'B-Tree', columns: ['product_id'], size: '8.4 MB' },\n    ],\n    ddl: `CREATE TABLE public.order_items (\n  id uuid PRIMARY KEY DEFAULT gen_random_uuid(),\n  order_id uuid NOT NULL REFERENCES public.orders(id) ON DELETE CASCADE ON UPDATE CASCADE,\n  product_id uuid NOT NULL REFERENCES public.products(id) ON DELETE RESTRICT ON UPDATE CASCADE,\n  quantity integer NOT NULL DEFAULT 1,\n  unit_price numeric(10,2) NOT NULL DEFAULT 0.00,\n  discount_amount numeric(10,2) NOT NULL DEFAULT 0.00,\n  created_at timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP\n);`,\n  },\n  {\n    name: 'products',\n    schema: 'public',\n    rowCount: 12400,\n    rowCountFormatted: '12,400 rows',\n    size: '9.8 MB',\n    primaryKey: 'id (UUID)',\n    lastAnalyzed: '45 mins ago',\n    description: 'Catalog products, SKU identifiers, real-time inventory counts, and price tiers.',\n    columns: [\n      {\n        name: 'id',\n        type: 'uuid',\n        nullable: false,\n        defaultValue: 'gen_random_uuid()',\n        isPrimaryKey: true,\n        description: 'Product primary key',\n      },\n      {\n        name: 'sku',\n        type: 'varchar(64)',\n        nullable: false,\n        defaultValue: null,\n        description: 'Stock keeping unit barcode index',\n      },\n      { name: 'name', type: 'varchar(255)', nullable: false, defaultValue: null, description: 'Public product title' },\n      {\n        name: 'description',\n        type: 'text',\n        nullable: true,\n        defaultValue: null,\n        description: 'Detailed marketing specifications',\n      },\n      { name: 'price', type: 'numeric(10,2)', nullable: false, defaultValue: '0.00', description: 'Base retail price' },\n      {\n        name: 'stock_quantity',\n        type: 'integer',\n        nullable: false,\n        defaultValue: '0',\n        description: 'Available warehouse stock',\n      },\n      {\n        name: 'is_active',\n        type: 'boolean',\n        nullable: false,\n        defaultValue: 'true',\n        description: 'Visibility in storefront',\n      },\n      {\n        name: 'metadata',\n        type: 'jsonb',\n        nullable: true,\n        defaultValue: \"'{}'::jsonb\",\n        description: 'Custom attributes and tags',\n      },\n      {\n        name: 'created_at',\n        type: 'timestamptz',\n        nullable: false,\n        defaultValue: 'CURRENT_TIMESTAMP',\n        description: 'Product onboarding timestamp',\n      },\n      {\n        name: 'updated_at',\n        type: 'timestamptz',\n        nullable: false,\n        defaultValue: 'CURRENT_TIMESTAMP',\n        description: 'Last catalog revision',\n      },\n    ],\n    foreignKeys: [],\n    indexes: [\n      { name: 'products_pkey', type: 'B-Tree', columns: ['id'], size: '380 KB', isPrimary: true, isUnique: true },\n      { name: 'idx_products_sku', type: 'B-Tree', columns: ['sku'], size: '290 KB', isUnique: true },\n      { name: 'idx_products_is_active', type: 'B-Tree', columns: ['is_active'], size: '180 KB' },\n    ],\n    ddl: `CREATE TABLE public.products (\n  id uuid PRIMARY KEY DEFAULT gen_random_uuid(),\n  sku varchar(64) NOT NULL UNIQUE,\n  name varchar(255) NOT NULL,\n  description text,\n  price numeric(10,2) NOT NULL DEFAULT 0.00,\n  stock_quantity integer NOT NULL DEFAULT 0,\n  is_active boolean NOT NULL DEFAULT true,\n  metadata jsonb DEFAULT '{}'::jsonb,\n  created_at timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP,\n  updated_at timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP\n);`,\n  },\n  {\n    name: 'subscriptions',\n    schema: 'public',\n    rowCount: 19850,\n    rowCountFormatted: '19,850 rows',\n    size: '14.1 MB',\n    primaryKey: 'id (UUID)',\n    lastAnalyzed: '18 mins ago',\n    description: 'Recurring billing contracts, subscription plans, and renewal period bounds.',\n    columns: [\n      {\n        name: 'id',\n        type: 'uuid',\n        nullable: false,\n        defaultValue: 'gen_random_uuid()',\n        isPrimaryKey: true,\n        description: 'Subscription contract ID',\n      },\n      {\n        name: 'user_id',\n        type: 'uuid',\n        nullable: false,\n        defaultValue: null,\n        isForeignKey: true,\n        foreignKeyRef: 'users.id',\n        description: 'Subscriber user ID',\n      },\n      {\n        name: 'plan_tier',\n        type: 'varchar(32)',\n        nullable: false,\n        defaultValue: \"'starter'\",\n        description: 'SaaS plan designation',\n      },\n      {\n        name: 'status',\n        type: 'varchar(32)',\n        nullable: false,\n        defaultValue: \"'active'\",\n        description: 'Lifecycle status',\n      },\n      {\n        name: 'current_period_start',\n        type: 'timestamptz',\n        nullable: false,\n        defaultValue: 'CURRENT_TIMESTAMP',\n        description: 'Current billing window start',\n      },\n      {\n        name: 'current_period_end',\n        type: 'timestamptz',\n        nullable: false,\n        defaultValue: null,\n        description: 'Next scheduled billing date',\n      },\n      {\n        name: 'cancel_at_period_end',\n        type: 'boolean',\n        nullable: false,\n        defaultValue: 'false',\n        description: 'Cancellation intent at renewal',\n      },\n      {\n        name: 'created_at',\n        type: 'timestamptz',\n        nullable: false,\n        defaultValue: 'CURRENT_TIMESTAMP',\n        description: 'Initial signup timestamp',\n      },\n    ],\n    foreignKeys: [\n      {\n        name: 'fk_subscriptions_user_id',\n        column: 'user_id',\n        foreignTable: 'users',\n        foreignColumn: 'id',\n        onDelete: 'CASCADE',\n        onUpdate: 'CASCADE',\n      },\n    ],\n    indexes: [\n      { name: 'subscriptions_pkey', type: 'B-Tree', columns: ['id'], size: '620 KB', isPrimary: true, isUnique: true },\n      { name: 'idx_subscriptions_user_id', type: 'B-Tree', columns: ['user_id'], size: '540 KB' },\n      { name: 'idx_subscriptions_status', type: 'B-Tree', columns: ['status'], size: '410 KB' },\n    ],\n    ddl: `CREATE TABLE public.subscriptions (\n  id uuid PRIMARY KEY DEFAULT gen_random_uuid(),\n  user_id uuid NOT NULL REFERENCES public.users(id) ON DELETE CASCADE ON UPDATE CASCADE,\n  plan_tier varchar(32) NOT NULL DEFAULT 'starter',\n  status varchar(32) NOT NULL DEFAULT 'active',\n  current_period_start timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP,\n  current_period_end timestamptz NOT NULL,\n  cancel_at_period_end boolean NOT NULL DEFAULT false,\n  created_at timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP\n);`,\n  },\n  {\n    name: 'audit_logs',\n    schema: 'public',\n    rowCount: 920400,\n    rowCountFormatted: '920,400 rows',\n    size: '201.0 MB',\n    primaryKey: 'id (UUID)',\n    lastAnalyzed: '1 min ago',\n    description: 'Immutable security event stream, compliance audit records, and state change captures.',\n    columns: [\n      {\n        name: 'id',\n        type: 'uuid',\n        nullable: false,\n        defaultValue: 'gen_random_uuid()',\n        isPrimaryKey: true,\n        description: 'Event ledger entry identifier',\n      },\n      {\n        name: 'actor_id',\n        type: 'uuid',\n        nullable: true,\n        defaultValue: null,\n        isForeignKey: true,\n        foreignKeyRef: 'users.id',\n        description: 'Initiating user account reference',\n      },\n      {\n        name: 'action',\n        type: 'varchar(64)',\n        nullable: false,\n        defaultValue: null,\n        description: 'Standardized action identifier',\n      },\n      {\n        name: 'entity_type',\n        type: 'varchar(64)',\n        nullable: false,\n        defaultValue: null,\n        description: 'Target entity namespace',\n      },\n      {\n        name: 'entity_id',\n        type: 'varchar(128)',\n        nullable: false,\n        defaultValue: null,\n        description: 'Target entity unique identifier',\n      },\n      { name: 'ip_address', type: 'inet', nullable: true, defaultValue: null, description: 'Client network IP' },\n      {\n        name: 'payload',\n        type: 'jsonb',\n        nullable: true,\n        defaultValue: \"'{}'::jsonb\",\n        description: 'Full before/after state diff',\n      },\n      {\n        name: 'created_at',\n        type: 'timestamptz',\n        nullable: false,\n        defaultValue: 'CURRENT_TIMESTAMP',\n        description: 'Exact audit record timestamp',\n      },\n    ],\n    foreignKeys: [\n      {\n        name: 'fk_audit_logs_actor_id',\n        column: 'actor_id',\n        foreignTable: 'users',\n        foreignColumn: 'id',\n        onDelete: 'SET NULL',\n        onUpdate: 'CASCADE',\n      },\n    ],\n    indexes: [\n      { name: 'audit_logs_pkey', type: 'B-Tree', columns: ['id'], size: '28.4 MB', isPrimary: true, isUnique: true },\n      { name: 'idx_audit_logs_actor_id', type: 'B-Tree', columns: ['actor_id'], size: '19.2 MB' },\n      {\n        name: 'idx_audit_logs_action_created',\n        type: 'B-Tree',\n        columns: ['action', 'created_at DESC'],\n        size: '32.6 MB',\n      },\n      { name: 'idx_audit_logs_entity', type: 'B-Tree', columns: ['entity_type', 'entity_id'], size: '24.1 MB' },\n    ],\n    ddl: `CREATE TABLE public.audit_logs (\n  id uuid PRIMARY KEY DEFAULT gen_random_uuid(),\n  actor_id uuid REFERENCES public.users(id) ON DELETE SET NULL ON UPDATE CASCADE,\n  action varchar(64) NOT NULL,\n  entity_type varchar(64) NOT NULL,\n  entity_id varchar(128) NOT NULL,\n  ip_address inet,\n  payload jsonb DEFAULT '{}'::jsonb,\n  created_at timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP\n);`,\n  },\n]\n\nexport function formatSchemaRowCount(count: number): string {\n  if (count >= 1_000_000) return `${(count / 1_000_000).toFixed(1)}M`\n  if (count >= 1_000) return `${(count / 1_000).toFixed(1)}k`\n  return String(count)\n}\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-database-schema-viewer, [ui-database-schema-viewer]',\n  standalone: true,\n  // React renders the root <div> itself: the host stays out of layout and `class` goes to the root.\n  host: { '[attr.class]': '\"contents\"' },\n  imports: [\n    LucideAngularModule,\n    UiBadgeComponent,\n    UiButtonComponent,\n    UiCardComponent,\n    UiInputComponent,\n    UiSeparatorComponent,\n    UiTableBodyComponent,\n    UiTableCellComponent,\n    UiTableComponent,\n    UiTableHeadComponent,\n    UiTableHeaderComponent,\n    UiTableRowComponent,\n    UiTabsComponent,\n    UiTabsContentComponent,\n    UiTabsListComponent,\n    UiTabsTriggerComponent,\n  ],\n  template: `\n    <div data-slot=\"database-schema-viewer\" [class]=\"rootClass\">\n      <!-- Top Database Header -->\n      <header class=\"border-border bg-card/60 border-b px-4 py-3.5 sm:px-6\">\n        <div class=\"flex flex-col gap-4 md:flex-row md:items-center md:justify-between\">\n          <div class=\"flex flex-wrap items-center gap-3\">\n            <div class=\"bg-primary/10 text-primary flex size-9 items-center justify-center rounded-lg\">\n              <lucide-icon [img]=\"Database\" class=\"size-4.5\" />\n            </div>\n            <div class=\"flex flex-col\">\n              <div class=\"flex flex-wrap items-center gap-2\">\n                <span class=\"font-mono text-sm font-semibold tracking-tight\">production-cluster-pg16</span>\n                <span class=\"bg-success flex size-2 rounded-full\" title=\"Connected & Synced\"></span>\n                <span ui-badge variant=\"secondary\" class=\"font-mono text-xs font-normal\">PostgreSQL 16.2</span>\n              </div>\n              <span class=\"text-muted-foreground text-xs\">18 tables · 420 MB</span>\n            </div>\n          </div>\n\n          <div class=\"flex flex-wrap items-center gap-2\">\n            <div class=\"relative w-full sm:w-60\">\n              <lucide-icon\n                [img]=\"Search\"\n                class=\"text-muted-foreground absolute top-1/2 left-2.5 size-3.5 -translate-y-1/2\"\n              />\n              <ui-input\n                [value]=\"searchQuery()\"\n                (valueChange)=\"searchQuery.set($event)\"\n                placeholder=\"Search tables or columns...\"\n                class=\"h-8 pl-8 text-xs\"\n              />\n            </div>\n            <button\n              ui-button\n              aria-label=\"Download attachment\"\n              variant=\"outline\"\n              size=\"sm\"\n              class=\"h-8 shrink-0 gap-1.5 text-xs\"\n              (click)=\"exportAllDDL()\"\n            >\n              @if (exportedAll()) {\n                <lucide-icon [img]=\"Check\" class=\"text-success size-3.5\" />\n              } @else {\n                <lucide-icon [img]=\"Download\" class=\"size-3.5\" />\n              }\n              {{ exportedAll() ? 'DDL Copied!' : 'Export DDL' }}\n            </button>\n          </div>\n        </div>\n      </header>\n\n      <!-- Two-Column Inspector Body -->\n      <div class=\"grid grid-cols-1 md:grid-cols-[240px_1fr] lg:grid-cols-[260px_1fr]\">\n        <!-- Left Sidebar: Tables List -->\n        <aside class=\"border-border bg-muted/20 border-r p-3 sm:p-4\">\n          <div class=\"mb-2.5 flex items-center justify-between gap-x-2 px-1\">\n            <span class=\"text-muted-foreground text-xs font-semibold tracking-wider uppercase\">Database Tables</span>\n            <span ui-badge variant=\"secondary\" class=\"h-5 px-1.5 font-mono text-xs\">{{ filteredTables().length }}</span>\n          </div>\n\n          <div class=\"space-y-1\">\n            @for (table of filteredTables(); track table.name) {\n              <button type=\"button\" [class]=\"tableButtonClass(table.name)\" (click)=\"selectedTableName.set(table.name)\">\n                <div class=\"flex min-w-0 items-center gap-2\">\n                  <lucide-icon [img]=\"Table2\" class=\"size-3.5 shrink-0 opacity-70\" />\n                  <span class=\"truncate font-mono\">{{ table.name }}</span>\n                </div>\n                <span class=\"bg-muted text-muted-foreground ml-2 shrink-0 rounded-full px-1.5 py-0.5 font-mono text-xs\">\n                  {{ formatCount(table.rowCount) }}\n                </span>\n              </button>\n            }\n            @if (filteredTables().length === 0) {\n              <div class=\"text-muted-foreground py-6 text-center text-xs\">No matching tables found</div>\n            }\n          </div>\n\n          <ui-separator class=\"my-4\" />\n\n          <div class=\"border-border/70 bg-card space-y-1.5 rounded-lg border p-3 text-xs\">\n            <div class=\"text-muted-foreground flex items-center justify-between gap-x-2\">\n              <span>Encoding:</span>\n              <span class=\"text-foreground font-mono\">UTF8</span>\n            </div>\n            <div class=\"text-muted-foreground flex items-center justify-between gap-x-2\">\n              <span>Collation:</span>\n              <span class=\"text-foreground font-mono\">en_US.utf8</span>\n            </div>\n            <div class=\"text-muted-foreground flex items-center justify-between gap-x-2\">\n              <span>Default Schema:</span>\n              <span class=\"text-foreground font-mono\">public</span>\n            </div>\n          </div>\n        </aside>\n\n        <!-- Right Main Panel: Table Detail Inspector -->\n        <main class=\"bg-card/30 min-w-0 space-y-5 p-4 sm:p-6\">\n          <!-- Active Table Header & Stats -->\n          <div class=\"border-border space-y-3 border-b pb-2\">\n            <div class=\"flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between\">\n              <div class=\"space-y-1\">\n                <div class=\"flex flex-wrap items-center gap-2\">\n                  <span class=\"text-muted-foreground font-mono text-sm\">public.</span>\n                  <h2 class=\"text-foreground font-mono text-xl font-bold tracking-tight break-all\">\n                    {{ activeTable().name }}\n                  </h2>\n                  <span ui-badge variant=\"outline\" class=\"font-mono text-xs font-normal\">BASE TABLE</span>\n                </div>\n                <p class=\"text-muted-foreground text-xs\">{{ activeTable().description }}</p>\n              </div>\n\n              <button\n                ui-button\n                variant=\"outline\"\n                size=\"sm\"\n                class=\"h-8 shrink-0 gap-1.5 self-start text-xs sm:self-auto\"\n                (click)=\"copyDDL(activeTable().ddl)\"\n              >\n                @if (copiedDDL()) {\n                  <lucide-icon [img]=\"Check\" class=\"text-success size-3.5\" />\n                } @else {\n                  <lucide-icon [img]=\"Copy\" class=\"size-3.5\" />\n                }\n                {{ copiedDDL() ? 'Copied DDL' : 'Copy Table DDL' }}\n              </button>\n            </div>\n\n            <!-- Metadata Stat Badges -->\n            <div class=\"flex flex-wrap items-center gap-2 pt-1\">\n              <div\n                class=\"border-border bg-card text-muted-foreground inline-flex items-center gap-1.5 rounded-md border px-2.5 py-1 text-xs\"\n              >\n                <lucide-icon [img]=\"Table2\" class=\"text-foreground/70 size-3.5\" />\n                <span>Rows:</span>\n                <span class=\"text-foreground font-mono font-medium\">{{ activeTable().rowCountFormatted }}</span>\n              </div>\n              <div\n                class=\"border-border bg-card text-muted-foreground inline-flex items-center gap-1.5 rounded-md border px-2.5 py-1 text-xs\"\n              >\n                <lucide-icon [img]=\"Key\" class=\"text-warning size-3.5\" />\n                <span>Primary Key:</span>\n                <span class=\"text-foreground font-mono font-medium\">{{ activeTable().primaryKey }}</span>\n              </div>\n              <div\n                class=\"border-border bg-card text-muted-foreground inline-flex items-center gap-1.5 rounded-md border px-2.5 py-1 text-xs\"\n              >\n                <lucide-icon [img]=\"HardDrive\" class=\"text-foreground/70 size-3.5\" />\n                <span>Table Size:</span>\n                <span class=\"text-foreground font-mono font-medium\">{{ activeTable().size }}</span>\n              </div>\n              <div\n                class=\"border-border bg-card text-muted-foreground inline-flex items-center gap-1.5 rounded-md border px-2.5 py-1 text-xs\"\n              >\n                <lucide-icon [img]=\"Clock\" class=\"text-foreground/70 size-3.5\" />\n                <span>Last Analyzed:</span>\n                <span class=\"text-foreground font-medium\">{{ activeTable().lastAnalyzed }}</span>\n              </div>\n            </div>\n          </div>\n\n          <!-- View Tabs Navigation -->\n          <ui-tabs [value]=\"activeTab()\" (valueChange)=\"activeTab.set($event)\" class=\"w-full\">\n            <ui-tabs-list class=\"grid h-9 w-full grid-cols-2 p-1 md:grid-cols-4\">\n              <button ui-tabs-trigger value=\"columns\" class=\"gap-1.5 text-xs\">\n                <lucide-icon [img]=\"Table2\" class=\"size-3.5\" />\n                <span>Columns</span>\n                <span class=\"bg-muted py-0.2 rounded-full px-1.5 font-mono text-xs\">\n                  {{ activeTable().columns.length }}\n                </span>\n              </button>\n              <button ui-tabs-trigger value=\"foreign-keys\" class=\"gap-1.5 text-xs\">\n                <lucide-icon [img]=\"Link2\" class=\"size-3.5\" />\n                <span>Foreign Keys</span>\n                <span class=\"bg-muted py-0.2 rounded-full px-1.5 font-mono text-xs\">\n                  {{ activeTable().foreignKeys.length }}\n                </span>\n              </button>\n              <button ui-tabs-trigger value=\"indexes\" class=\"gap-1.5 text-xs\">\n                <lucide-icon [img]=\"Layers\" class=\"size-3.5\" />\n                <span>Indexes</span>\n                <span class=\"bg-muted py-0.2 rounded-full px-1.5 font-mono text-xs\">\n                  {{ activeTable().indexes.length }}\n                </span>\n              </button>\n              <button ui-tabs-trigger value=\"ddl\" class=\"gap-1.5 text-xs\">\n                <lucide-icon [img]=\"Code2\" class=\"size-3.5\" />\n                <span>SQL DDL Preview</span>\n              </button>\n            </ui-tabs-list>\n\n            <!-- Tab 1: Columns List -->\n            <ui-tabs-content value=\"columns\" class=\"mt-4\">\n              <div ui-card class=\"border-border overflow-hidden border shadow-none\">\n                <div class=\"overflow-x-auto\">\n                  <table ui-table>\n                    <thead ui-table-header>\n                      <tr ui-table-row class=\"bg-muted/40 hover:bg-muted/40\">\n                        <th ui-table-head class=\"text-xs font-semibold\">Column Name</th>\n                        <th ui-table-head class=\"text-xs font-semibold\">Data Type</th>\n                        <th ui-table-head class=\"text-xs font-semibold\">Nullable</th>\n                        <th ui-table-head class=\"text-xs font-semibold\">Default Value</th>\n                        <th ui-table-head class=\"text-xs font-semibold\">Constraints</th>\n                        <th ui-table-head class=\"text-xs font-semibold\">Description</th>\n                      </tr>\n                    </thead>\n                    <tbody ui-table-body>\n                      @for (col of activeTable().columns; track col.name) {\n                        <tr ui-table-row class=\"text-xs\">\n                          <td ui-table-cell class=\"font-mono font-medium\">\n                            <div class=\"flex items-center gap-1.5\">\n                              @if (col.isPrimaryKey) {\n                                <lucide-icon [img]=\"Key\" class=\"text-warning size-3.5 shrink-0\" />\n                              } @else if (col.isForeignKey) {\n                                <lucide-icon [img]=\"Link2\" class=\"text-info size-3.5 shrink-0\" />\n                              }\n                              <span [class]=\"col.isPrimaryKey ? 'text-warning font-semibold' : ''\">{{ col.name }}</span>\n                            </div>\n                          </td>\n                          <td ui-table-cell>\n                            <span ui-badge variant=\"secondary\" class=\"font-mono text-xs font-normal\">{{\n                              col.type\n                            }}</span>\n                          </td>\n                          <td ui-table-cell>\n                            @if (!col.nullable) {\n                              <span ui-badge variant=\"outline\" class=\"text-muted-foreground text-xs\">NOT NULL</span>\n                            } @else {\n                              <span class=\"text-muted-foreground\">NULL</span>\n                            }\n                          </td>\n                          <td ui-table-cell class=\"text-muted-foreground font-mono\">{{ col.defaultValue ?? '—' }}</td>\n                          <td ui-table-cell>\n                            <div class=\"flex flex-wrap items-center gap-1\">\n                              @if (col.isPrimaryKey) {\n                                <span ui-badge class=\"border-warning/30 bg-warning/15 text-warning text-xs\">PK</span>\n                              }\n                              @if (col.isForeignKey) {\n                                <span ui-badge variant=\"secondary\" class=\"gap-1 font-mono text-xs\">\n                                  FK &rarr; {{ col.foreignKeyRef }}\n                                </span>\n                              }\n                              @if (!col.isPrimaryKey && !col.isForeignKey) {\n                                <span class=\"text-muted-foreground\">—</span>\n                              }\n                            </div>\n                          </td>\n                          <td ui-table-cell class=\"text-muted-foreground max-w-[200px] truncate\">\n                            {{ col.description ?? '—' }}\n                          </td>\n                        </tr>\n                      }\n                    </tbody>\n                  </table>\n                </div>\n              </div>\n            </ui-tabs-content>\n\n            <!-- Tab 2: Foreign Keys & Relations -->\n            <ui-tabs-content value=\"foreign-keys\" class=\"mt-4 space-y-3\">\n              @if (activeTable().foreignKeys.length > 0) {\n                <div class=\"space-y-3\">\n                  @for (fk of activeTable().foreignKeys; track fk.name) {\n                    <div ui-card class=\"border-border space-y-3 border p-4 shadow-none\">\n                      <div class=\"border-border flex flex-wrap items-center justify-between gap-2 border-b pb-2\">\n                        <div class=\"flex flex-wrap items-center gap-2\">\n                          <lucide-icon [img]=\"Link2\" class=\"text-info size-4\" />\n                          <span class=\"text-foreground font-mono text-xs font-semibold\">{{ fk.name }}</span>\n                        </div>\n                        <span ui-badge variant=\"secondary\" class=\"font-mono text-xs\">Many-to-One (N:1)</span>\n                      </div>\n                      <div\n                        class=\"bg-muted/40 border-border/60 flex flex-col justify-between gap-3 rounded-lg border p-3 sm:flex-row sm:items-center\"\n                      >\n                        <div class=\"flex flex-wrap items-center gap-2\">\n                          <span class=\"text-muted-foreground text-xs\">Source:</span>\n                          <span ui-badge variant=\"outline\" class=\"font-mono text-xs\">\n                            {{ activeTable().name }}.{{ fk.column }}\n                          </span>\n                        </div>\n                        <lucide-icon [img]=\"ArrowRight\" class=\"text-muted-foreground hidden size-4 sm:block\" />\n                        <div class=\"flex flex-wrap items-center gap-2\">\n                          <span class=\"text-muted-foreground text-xs\">References:</span>\n                          <span ui-badge variant=\"default\" class=\"font-mono text-xs\">\n                            {{ fk.foreignTable }}.{{ fk.foreignColumn }}\n                          </span>\n                        </div>\n                      </div>\n                      <div class=\"grid grid-cols-1 gap-2 pt-1 text-xs sm:grid-cols-2\">\n                        <div\n                          class=\"border-border/50 bg-card flex items-center justify-between gap-x-2 rounded-md border px-2.5 py-1.5\"\n                        >\n                          <span class=\"text-muted-foreground\">On Delete Action:</span>\n                          <span ui-badge variant=\"secondary\" class=\"font-mono text-xs\">{{ fk.onDelete }}</span>\n                        </div>\n                        <div\n                          class=\"border-border/50 bg-card flex items-center justify-between gap-x-2 rounded-md border px-2.5 py-1.5\"\n                        >\n                          <span class=\"text-muted-foreground\">On Update Action:</span>\n                          <span ui-badge variant=\"secondary\" class=\"font-mono text-xs\">{{ fk.onUpdate }}</span>\n                        </div>\n                      </div>\n                    </div>\n                  }\n                </div>\n              } @else {\n                <div ui-card class=\"border-border border border-dashed p-8 text-center\">\n                  <div class=\"flex flex-col items-center justify-center space-y-2\">\n                    <div class=\"bg-muted text-muted-foreground flex size-10 items-center justify-center rounded-full\">\n                      <lucide-icon [img]=\"Link2\" class=\"size-5\" />\n                    </div>\n                    <h3 class=\"text-sm font-semibold\">No Outbound Foreign Keys</h3>\n                    <p class=\"text-muted-foreground max-w-sm text-xs\">\n                      Table <span class=\"font-mono font-medium\">{{ activeTable().name }}</span> has no outbound\n                      relations. It acts as an independent entity or is referenced by downstream child tables.\n                    </p>\n                  </div>\n                </div>\n              }\n            </ui-tabs-content>\n\n            <!-- Tab 3: Indexes & Constraints -->\n            <ui-tabs-content value=\"indexes\" class=\"mt-4\">\n              <div ui-card class=\"border-border overflow-hidden border shadow-none\">\n                <div class=\"overflow-x-auto\">\n                  <table ui-table>\n                    <thead ui-table-header>\n                      <tr ui-table-row class=\"bg-muted/40 hover:bg-muted/40\">\n                        <th ui-table-head class=\"text-xs font-semibold\">Index Name</th>\n                        <th ui-table-head class=\"text-xs font-semibold\">Method</th>\n                        <th ui-table-head class=\"text-xs font-semibold\">Indexed Columns</th>\n                        <th ui-table-head class=\"text-xs font-semibold\">Index Size</th>\n                        <th ui-table-head class=\"text-xs font-semibold\">Constraint Type</th>\n                      </tr>\n                    </thead>\n                    <tbody ui-table-body>\n                      @for (idx of activeTable().indexes; track idx.name) {\n                        <tr ui-table-row class=\"text-xs\">\n                          <td ui-table-cell class=\"font-mono font-medium\">\n                            <div class=\"flex items-center gap-1.5\">\n                              <lucide-icon [img]=\"Layers\" class=\"text-muted-foreground size-3.5 shrink-0\" />\n                              <span>{{ idx.name }}</span>\n                            </div>\n                          </td>\n                          <td ui-table-cell>\n                            <span ui-badge variant=\"secondary\" class=\"font-mono text-xs\">{{ idx.type }}</span>\n                          </td>\n                          <td ui-table-cell class=\"text-foreground font-mono\">{{ idx.columns.join(', ') }}</td>\n                          <td ui-table-cell class=\"text-muted-foreground font-mono\">{{ idx.size }}</td>\n                          <td ui-table-cell>\n                            @if (idx.isPrimary) {\n                              <span ui-badge class=\"border-warning/30 bg-warning/15 text-warning text-xs\">\n                                PRIMARY KEY\n                              </span>\n                            } @else if (idx.isUnique) {\n                              <span ui-badge variant=\"secondary\" class=\"text-xs\">UNIQUE</span>\n                            } @else {\n                              <span ui-badge variant=\"outline\" class=\"text-muted-foreground text-xs\">INDEX</span>\n                            }\n                          </td>\n                        </tr>\n                      }\n                    </tbody>\n                  </table>\n                </div>\n              </div>\n            </ui-tabs-content>\n\n            <!-- Tab 4: SQL DDL Preview -->\n            <ui-tabs-content value=\"ddl\" class=\"mt-4\">\n              <div class=\"border-border bg-muted/40 overflow-hidden rounded-lg border\">\n                <div class=\"border-border bg-card flex items-center justify-between gap-x-2 border-b px-4 py-2.5\">\n                  <div class=\"flex flex-wrap items-center gap-2\">\n                    <lucide-icon [img]=\"Code2\" class=\"text-primary size-4\" />\n                    <span class=\"text-foreground font-mono text-xs font-medium\">{{ activeTable().name }}.sql</span>\n                    <span ui-badge variant=\"secondary\" class=\"font-mono text-xs\">PostgreSQL DDL</span>\n                  </div>\n                  <button\n                    ui-button\n                    variant=\"ghost\"\n                    size=\"sm\"\n                    class=\"h-7 gap-1 text-xs\"\n                    (click)=\"copyDDL(activeTable().ddl)\"\n                  >\n                    @if (copiedDDL()) {\n                      <lucide-icon [img]=\"Check\" class=\"text-success size-3\" />\n                    } @else {\n                      <lucide-icon [img]=\"Copy\" class=\"size-3\" />\n                    }\n                    {{ copiedDDL() ? 'Copied' : 'Copy' }}\n                  </button>\n                </div>\n                <div\n                  class=\"overflow-x-auto bg-neutral-950 p-4 font-mono text-xs leading-relaxed text-neutral-100 dark:bg-neutral-950\"\n                >\n                  <pre class=\"whitespace-pre\"><code>{{ activeTable().ddl }}</code></pre>\n                </div>\n              </div>\n            </ui-tabs-content>\n          </ui-tabs>\n        </main>\n      </div>\n    </div>\n  `,\n})\nexport class UiDatabaseSchemaViewerComponent {\n  protected readonly ArrowRight = ArrowRight\n  protected readonly Check = Check\n  protected readonly Clock = Clock\n  protected readonly Code2 = Code2\n  protected readonly Copy = Copy\n  protected readonly Database = Database\n  protected readonly Download = Download\n  protected readonly HardDrive = HardDrive\n  protected readonly Key = Key\n  protected readonly Layers = Layers\n  protected readonly Link2 = Link2\n  protected readonly Search = Search\n  protected readonly Table2 = Table2\n\n  @Input() set initialTable(v: string) {\n    if (v) this.selectedTableName.set(v)\n  }\n  @Input('class') className?: string\n\n  readonly searchQuery = signal('')\n  readonly selectedTableName = signal('orders')\n  readonly activeTab = signal('columns')\n  readonly copiedDDL = signal(false)\n  readonly exportedAll = signal(false)\n  private copyTimer: ReturnType<typeof setTimeout> | undefined\n  private exportTimer: ReturnType<typeof setTimeout> | undefined\n\n  readonly filteredTables = computed(() => {\n    const query = this.searchQuery().trim().toLowerCase()\n    if (!query) return schemaTables\n    return schemaTables.filter(\n      (table) =>\n        table.name.toLowerCase().includes(query) ||\n        table.description.toLowerCase().includes(query) ||\n        table.columns.some((col) => col.name.toLowerCase().includes(query)),\n    )\n  })\n\n  readonly activeTable = computed<SchemaTable>(() => {\n    return schemaTables.find((t) => t.name === this.selectedTableName()) ?? schemaTables[0]!\n  })\n\n  get rootClass(): string {\n    return cn(\n      'bg-background text-foreground border-border w-full overflow-hidden rounded-xl border shadow-xs',\n      this.className,\n    )\n  }\n\n  formatCount(count: number): string {\n    return formatSchemaRowCount(count)\n  }\n\n  tableButtonClass(name: string): string {\n    return cn(\n      'flex w-full items-center justify-between rounded-lg px-2.5 py-2 text-left text-xs transition-colors',\n      this.selectedTableName() === name\n        ? 'bg-primary/10 text-primary border-primary/20 border font-medium shadow-xs'\n        : 'text-muted-foreground hover:bg-muted/70 hover:text-foreground border border-transparent',\n    )\n  }\n\n  copyDDL(text: string): void {\n    try {\n      void navigator.clipboard?.writeText(text)\n    } catch {\n      // Clipboard unavailable in some contexts; the flag still flips for feedback.\n    }\n    this.copiedDDL.set(true)\n    clearTimeout(this.copyTimer)\n    this.copyTimer = setTimeout(() => this.copiedDDL.set(false), 2000)\n  }\n\n  exportAllDDL(): void {\n    const allSql = schemaTables.map((t) => `-- Table: ${t.name}\\n${t.ddl}`).join('\\n\\n')\n    try {\n      void navigator.clipboard?.writeText(allSql)\n    } catch {\n      // Clipboard unavailable in some contexts; the flag still flips for feedback.\n    }\n    this.exportedAll.set(true)\n    clearTimeout(this.exportTimer)\n    this.exportTimer = setTimeout(() => this.exportedAll.set(false), 2000)\n  }\n}\n",
      "type": "registry:page",
      "target": "~/src/app/components/blocks/database-schema-viewer/database-schema-viewer.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/database-schema-viewer/index.ts",
      "content": "export {\n  UiDatabaseSchemaViewerComponent,\n  formatSchemaRowCount,\n  type SchemaColumnDefinition,\n  type SchemaForeignKeyDefinition,\n  type SchemaIndexDefinition,\n  type SchemaTable,\n} from './database-schema-viewer.component'\n",
      "type": "registry:page",
      "target": "~/src/app/components/blocks/database-schema-viewer/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",
    "https://uipkge.dev/r/angular/input.json",
    "https://uipkge.dev/r/angular/separator.json",
    "https://uipkge.dev/r/angular/table.json",
    "https://uipkge.dev/r/angular/tabs.json"
  ],
  "description": "Visual database schema inspector and SQL query previewer with cluster health header, table navigation sidebar with row counts, columns metadata table (data types, nullability, defaults, PK/FK indicators), foreign keys diagram, B-Tree indexes, and syntax-styled DDL preview with copy actions.",
  "categories": [
    "devops",
    "app"
  ]
}