{"version":3,"sources":["../src/index.ts","../src/compass.ts","../src/sanitize.ts","../src/service.ts","../src/domain.ts","../src/validation.ts","../src/compass-api.ts"],"sourcesContent":["import utils from '@eventcatalog/sdk';\nimport chalk from 'chalk';\nimport { createHash } from 'node:crypto';\nimport { readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { loadConfig, CompassConfig } from './compass';\nimport { loadService, extractTeamId } from './service';\nimport Domain, { resolveDomain } from './domain';\nimport { GeneratorProps, ResolvedDependency, ServiceIdStrategy, Service } from './types';\nexport type { StructuredLink } from './types';\nimport { GeneratorPropsSchema } from './validation';\nimport { fetchComponents, fetchTeamById, TeamData } from './compass-api';\nimport { sanitizeId, sanitizeHtml } from './sanitize';\n\nconst HASH_MANIFEST_FILE = '.compass-hashes.json';\n\ntype HashManifest = Record<string, string>;\n\nasync function loadHashManifest(projectDir: string): Promise<HashManifest> {\n  try {\n    const raw = await readFile(join(projectDir, HASH_MANIFEST_FILE), 'utf-8');\n    return JSON.parse(raw) as HashManifest;\n  } catch (error) {\n    if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n      const message = error instanceof Error ? error.message : String(error);\n      console.warn(chalk.yellow(`Could not load hash manifest: ${message}. Regenerating all services.`));\n    }\n    return {};\n  }\n}\n\nasync function saveHashManifest(projectDir: string, manifest: HashManifest): Promise<void> {\n  await writeFile(join(projectDir, HASH_MANIFEST_FILE), JSON.stringify(manifest, null, 2) + '\\n');\n}\n\nfunction computeServiceHash(service: Service): string {\n  // Stable JSON: sort keys so field ordering doesn't affect the hash\n  const json = JSON.stringify(service, Object.keys(service).sort());\n  return createHash('sha256').update(json).digest('hex');\n}\n\n// Resolve service ID based on strategy\nfunction resolveServiceId(config: CompassConfig, strategy: ServiceIdStrategy | undefined, fileId?: string): string {\n  // If a file-level override ID is provided (YAML mode), it takes precedence\n  if (fileId) return sanitizeId(fileId);\n\n  if (typeof strategy === 'function') {\n    return sanitizeId(strategy(config));\n  }\n\n  if (strategy === 'compass-id') {\n    return sanitizeId(config.id || config.name);\n  }\n\n  // Default: 'name'\n  return sanitizeId(config.name);\n}\n\n// The event.catalog.js values for your plugin\ntype EventCatalogConfig = Record<string, unknown>;\n\ntype ProcessableEntry = {\n  config: CompassConfig;\n  serviceId: string;\n  version: string;\n};\n\nexport default async (_config: EventCatalogConfig, options: GeneratorProps) => {\n  // Validate configuration\n  GeneratorPropsSchema.parse(options);\n\n  if (!process.env.PROJECT_DIR) {\n    process.env.PROJECT_DIR = process.cwd();\n  }\n\n  const projectDir = process.env.PROJECT_DIR;\n\n  if (options.debug) {\n    console.debug(chalk.magenta('Configuration provided', JSON.stringify(_config)));\n    const { api, markdownTemplate: _tpl, ...safeOptions } = options;\n    if (api) {\n      const { apiToken: _token, email: _email, ...safeApi } = api;\n      console.debug(\n        chalk.magenta(\n          'Generator properties',\n          JSON.stringify({\n            ...safeOptions,\n            api: { ...safeApi, apiToken: '***', email: '***' },\n            markdownTemplate: _tpl ? '[Function]' : undefined,\n          })\n        )\n      );\n    } else {\n      console.debug(\n        chalk.magenta(\n          'Generator properties',\n          JSON.stringify({ ...safeOptions, markdownTemplate: _tpl ? '[Function]' : undefined })\n        )\n      );\n    }\n  }\n\n  // EventCatalog SDK (https://www.eventcatalog.dev/docs/sdk)\n  const { getService, writeService, writeTeam } = utils(projectDir);\n\n  const format = options.format || 'mdx';\n  const dryRun = options.dryRun === true;\n  const teamsWritten = new Set<string>();\n  const incremental = options.incremental === true;\n  const hashManifest = incremental ? await loadHashManifest(projectDir) : {};\n  const newHashManifest: HashManifest = {};\n  let skippedCount = 0;\n\n  const domainRegistry = new Map<string, Domain>();\n  const processedDomainIds = new Set<string>();\n\n  async function getDomainFor(compassConfig: CompassConfig): Promise<Domain | null> {\n    if (!options.domain) return null;\n    const spec = resolveDomain(compassConfig, options.domain);\n    if (!spec) {\n      if (options.debug) {\n        console.debug(chalk.magenta(` - No domain matched for ${compassConfig.name}, skipping domain association`));\n      }\n      return null;\n    }\n\n    if (options.debug) {\n      console.debug(chalk.magenta(` - Resolved domain for ${compassConfig.name}: ${spec.id} (v${spec.version})`));\n    }\n\n    let instance = domainRegistry.get(spec.id);\n    if (!instance) {\n      instance = new Domain(spec.id, spec.name, spec.version, projectDir);\n      domainRegistry.set(spec.id, instance);\n    }\n\n    if (!processedDomainIds.has(spec.id)) {\n      processedDomainIds.add(spec.id);\n      if (dryRun) {\n        console.log(chalk.yellow(`\\n[DRY RUN] Would create/update domain: ${spec.name} (id: ${spec.id}, v${spec.version})`));\n      } else {\n        await instance.processDomain();\n      }\n    }\n\n    return instance;\n  }\n\n  // First pass: build processable entries from either API or YAML mode\n  const serviceMap = new Map<string, { serviceId: string; name: string }>();\n  const processableEntries: ProcessableEntry[] = [];\n  let loadFailureCount = 0;\n  const loadFailures: Array<{ name: string; error: string }> = [];\n\n  if (options.api) {\n    // API mode: fetch components from Compass GraphQL API\n    console.log(chalk.green('Fetching components from Compass API...'));\n    const components = await fetchComponents(options.api);\n    console.log(chalk.green(`Fetched ${components.length} components from Compass API`));\n\n    for (const config of components) {\n      // Apply top-level typeFilter (api.typeFilter is handled server-side in the query)\n      if (options.typeFilter && options.typeFilter.length > 0) {\n        if (!config.typeId || !options.typeFilter.includes(config.typeId)) {\n          console.log(chalk.yellow(`\\nSkipping ${config.name} (type ${config.typeId || 'unknown'} not in typeFilter)`));\n          continue;\n        }\n      }\n\n      // Apply nameFilter to only process specific components\n      if (options.nameFilter && options.nameFilter.length > 0) {\n        if (!options.nameFilter.includes(config.name)) {\n          continue;\n        }\n      }\n\n      // Apply nameMapping: if the component name has a mapping, use the mapped value as service ID\n      const mappedId = options.nameMapping?.[config.name];\n      const serviceId = mappedId ? sanitizeId(mappedId) : resolveServiceId(config, options.serviceIdStrategy);\n      if (config.id) {\n        serviceMap.set(config.id, { serviceId, name: config.name });\n      }\n      processableEntries.push({ config, serviceId, version: options.defaultVersion || '0.0.0' });\n    }\n  } else if (options.services) {\n    // YAML mode: read local files (existing behavior)\n    const compassFiles = Array.isArray(options.services) ? options.services : [options.services];\n    console.log(chalk.green(`Processing ${compassFiles.length} Compass files...`));\n\n    for (const file of compassFiles) {\n      try {\n        const compassConfig: CompassConfig = loadConfig(file.path);\n\n        // If typeFilter is set, skip components whose typeId is not in the list\n        if (options.typeFilter && options.typeFilter.length > 0) {\n          if (!compassConfig.typeId || !options.typeFilter.includes(compassConfig.typeId)) {\n            console.log(\n              chalk.yellow(`\\nSkipping ${compassConfig.name} (type ${compassConfig.typeId || 'unknown'} not in typeFilter)`)\n            );\n            continue;\n          }\n        }\n\n        const serviceId = resolveServiceId(compassConfig, options.serviceIdStrategy, file.id);\n        if (compassConfig.id) {\n          serviceMap.set(compassConfig.id, { serviceId, name: compassConfig.name });\n        }\n        processableEntries.push({ config: compassConfig, serviceId, version: file.version || options.defaultVersion || '0.0.0' });\n      } catch (error) {\n        const errorMessage = error instanceof Error ? error.message : String(error);\n        console.error(chalk.red(`\\n✗ Failed to load ${file.path}: ${errorMessage}`));\n        loadFailureCount++;\n        loadFailures.push({ name: file.path, error: errorMessage });\n      }\n    }\n  }\n\n  // Second pass: write services with resolved dependencies\n  let successCount = 0;\n  let failureCount = loadFailureCount;\n  const failures: Array<{ name: string; error: string }> = [...loadFailures];\n\n  if (dryRun) {\n    console.log(chalk.yellow('\\n[DRY RUN] No changes will be written to the catalog.\\n'));\n  }\n\n  for (const { config: compassConfig, serviceId, version } of processableEntries) {\n    try {\n      console.log(chalk.blue(`\\nProcessing component: ${compassConfig.name} (type: ${compassConfig.typeId || 'unknown'})`));\n\n      const domain = await getDomainFor(compassConfig);\n      if (domain && !dryRun) {\n        // Add the service to the domain\n        await domain.addServiceToDomain(serviceId, version);\n      } else if (domain && dryRun) {\n        console.log(chalk.yellow(` - [DRY RUN] Would add service ${serviceId} to domain ${domain.id}`));\n      }\n\n      // Resolve DEPENDS_ON relationships\n      const dependencies: ResolvedDependency[] = [];\n      if (compassConfig.relationships?.DEPENDS_ON) {\n        for (const arn of compassConfig.relationships.DEPENDS_ON) {\n          const target = serviceMap.get(arn);\n          if (target) {\n            dependencies.push({ id: target.serviceId, name: target.name });\n          } else {\n            console.log(chalk.yellow(` - Dependency ${arn} not found in processed services, skipping`));\n          }\n        }\n      }\n\n      // Write team entity if ownerId is present and not yet written\n      if (compassConfig.ownerId) {\n        const rawTeamId = extractTeamId(compassConfig.ownerId);\n        if (rawTeamId) {\n          const teamId = sanitizeId(rawTeamId);\n          if (!teamsWritten.has(teamId)) {\n            // In API mode, try to fetch enriched team data from Compass\n            let teamData: TeamData | null = null;\n            if (options.api && !dryRun) {\n              try {\n                teamData = await fetchTeamById(options.api, rawTeamId);\n                if (!teamData?.displayName) {\n                  console.warn(chalk.yellow(` - Could not resolve team name for ${rawTeamId}, skipping team creation`));\n                  teamData = null;\n                }\n              } catch {\n                console.warn(chalk.yellow(` - Failed to fetch team name for ${rawTeamId}`));\n              }\n            } else if (!options.api) {\n              // YAML mode: use the UUID as name (no API to resolve)\n              teamData = { id: rawTeamId, displayName: teamId };\n            }\n            if (teamData && !dryRun) {\n              const teamName = sanitizeHtml(teamData.displayName);\n              const members = teamData.members?.length\n                ? teamData.members.map((m) => ({\n                    id: m.accountId,\n                    name: sanitizeHtml(m.name),\n                    avatarUrl: m.picture || '',\n                    markdown: '',\n                  }))\n                : undefined;\n\n              await writeTeam(\n                {\n                  id: teamId,\n                  name: teamName,\n                  markdown: '',\n                  ...(teamData.description && { summary: sanitizeHtml(teamData.description) }),\n                  ...(teamData.largeAvatarImageUrl && { avatarUrl: teamData.largeAvatarImageUrl }),\n                  ...(members && { members }),\n                },\n                { override: true }\n              );\n              console.log(chalk.cyan(` - Team ${teamId} (${teamName}) created`));\n            } else if (teamData && dryRun) {\n              console.log(chalk.yellow(` - [DRY RUN] Would create team ${teamId} (${sanitizeHtml(teamData.displayName)})`));\n            }\n            teamsWritten.add(teamId);\n          }\n        }\n      }\n\n      const compassService = loadService(\n        compassConfig,\n        options.compassUrl.replace(/\\/$/, ''),\n        version,\n        serviceId,\n        dependencies,\n        options.markdownTemplate,\n        options.badges ?? true\n      );\n\n      if (dryRun) {\n        console.log(\n          chalk.yellow(` - [DRY RUN] Would write service ${compassConfig.name} (id: ${serviceId}, version: ${version})`)\n        );\n        if (compassService.badges) {\n          console.log(chalk.yellow(`   Badges: ${compassService.badges.map((b) => b.content).join(', ')}`));\n        }\n        if (dependencies.length > 0) {\n          console.log(chalk.yellow(`   Dependencies: ${dependencies.map((d) => d.name).join(', ')}`));\n        }\n      } else {\n        // Incremental mode: skip writing if the service hasn't changed\n        const serviceHash = incremental ? computeServiceHash(compassService) : undefined;\n        if (incremental && serviceHash) {\n          newHashManifest[serviceId] = serviceHash;\n        }\n\n        if (incremental && serviceHash && hashManifest[serviceId] === serviceHash) {\n          console.log(chalk.gray(` - Service ${compassConfig.name} skipped (unchanged)`));\n          skippedCount++;\n        } else {\n          const existing = await getService(serviceId);\n\n          if (existing && options.overrideExisting !== false) {\n            await writeService(compassService, { override: true, format });\n            console.log(chalk.cyan(` - Service ${compassConfig.name} updated`));\n          } else if (!existing) {\n            await writeService(compassService, { format });\n            console.log(chalk.cyan(` - Service ${compassConfig.name} created`));\n          } else {\n            console.log(chalk.yellow(` - Service ${compassConfig.name} skipped (already exists)`));\n          }\n        }\n      }\n\n      successCount++;\n    } catch (error) {\n      failureCount++;\n      const errorMessage = error instanceof Error ? error.message : String(error);\n      failures.push({ name: compassConfig.name, error: errorMessage });\n      console.error(chalk.red(`\\n✗ Failed to process ${compassConfig.name}: ${errorMessage}`));\n    }\n  }\n\n  // Save hash manifest for incremental mode\n  if (incremental && !dryRun && Object.keys(newHashManifest).length > 0) {\n    await saveHashManifest(projectDir, newHashManifest);\n  }\n\n  // Summary\n  console.log(chalk.green(`\\nFinished generating event catalog for the Compass files provided!`));\n  console.log(chalk.green(`  Succeeded: ${successCount}, Failed: ${failureCount}`));\n  if (skippedCount > 0) {\n    console.log(chalk.gray(`  Skipped (unchanged): ${skippedCount}`));\n  }\n  if (failures.length > 0) {\n    console.log(chalk.red('  Failures:'));\n    for (const f of failures) {\n      console.log(chalk.red(`    - ${f.name}: ${f.error}`));\n    }\n  }\n  if (dryRun) {\n    console.log(chalk.yellow('  [DRY RUN] No changes were written.'));\n  }\n};\n","import yaml from 'js-yaml';\nimport fs from 'fs';\n\n//Object generated from the compass.yml file\n// reference in https://developer.atlassian.com/cloud/compass/config-as-code/structure-and-contents-of-a-compass-yml-file/\n\nenum TypeId {\n  APPLICATION = 'APPLICATION',\n  SERVICE = 'SERVICE',\n  CAPABILITY = 'CAPABILITY',\n  CLOUD_RESOURCE = 'CLOUD_RESOURCE',\n  DATA_PIPELINE = 'DATA_PIPELINE',\n  LIBRARY = 'LIBRARY',\n  MACHINE_LEARNING_MODEL = 'MACHINE_LEARNING_MODEL',\n  OTHER = 'OTHER',\n  UI_ELEMENT = 'UI_ELEMENT',\n  WEBSITE = 'WEBSITE',\n}\n\nenum Lifecycle {\n  PRERELEASE = 'Pre-release',\n  ACTIVE = 'Active',\n  DEPRECATED = 'Deprecated',\n}\n\nenum UrlType {\n  CHAT_CHANNEL = 'CHAT_CHANNEL',\n  DOCUMENT = 'DOCUMENT',\n  DASHBOARD = 'DASHBOARD',\n  ON_CALL = 'ON_CALL',\n  PROJECT = 'PROJECT',\n  REPOSITORY = 'REPOSITORY',\n  OTHER_LINK = 'OTHER_LINK',\n}\n\ntype Field = {\n  tier?: 1 | 2 | 3 | 4;\n  lifecycle: Lifecycle;\n};\n\ntype Link = {\n  type: UrlType;\n  url: string;\n  name?: string;\n};\n\nenum CustomFieldType {\n  TEXT = 'text',\n  BOOLEAN = 'boolean',\n  NUMBER = 'number',\n  USER = 'user',\n  SINGLE_SELECT = 'single_select',\n  MULTIPLE_SELECT = 'multi_select',\n}\n\ntype CustomField = {\n  type: CustomFieldType;\n  name: string;\n  value: string;\n};\n\nexport type ScorecardScore = {\n  name: string;\n  score: number;\n  maxScore: number;\n};\n\nexport type CompassConfig = {\n  configVersion?: number;\n  name: string;\n  id?: string;\n  description?: string;\n  typeId?: TypeId;\n  ownerId?: string;\n  fields?: Field;\n  links?: Link[];\n  relationships?: {\n    DEPENDS_ON?: string[];\n  };\n  customFields?: CustomField[];\n  labels?: string[];\n  scorecards?: ScorecardScore[];\n};\n\nexport function loadConfig(path: string): CompassConfig {\n  const raw = yaml.load(fs.readFileSync(path, 'utf8'));\n  if (!raw || typeof raw !== 'object' || !('name' in raw) || typeof (raw as Record<string, unknown>).name !== 'string') {\n    throw new Error(`Invalid Compass config in ${path}: missing required \"name\" field`);\n  }\n  return raw as CompassConfig;\n}\n","// Sanitize text to prevent HTML/markdown injection from untrusted sources.\n// Escapes HTML special characters: & < > \" '\nexport function sanitizeHtml(text: string): string {\n  return text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;').replace(/'/g, '&#39;');\n}\n\n// Sanitize text for safe markdown/MDX embedding: escape HTML special chars and markdown link syntax\nexport function sanitizeMarkdownText(text: string): string {\n  return sanitizeHtml(text).replace(/[[\\]()]/g, (char) => `\\\\${char}`);\n}\n\n// Sanitize URL for safe markdown link embedding: only allow http/https protocols\nexport function sanitizeUrl(url: string): string {\n  try {\n    const parsed = new URL(url);\n    if (parsed.protocol === 'http:' || parsed.protocol === 'https:') {\n      return url.replace(/[()]/g, (char) => encodeURIComponent(char));\n    }\n    return '';\n  } catch {\n    return '';\n  }\n}\n\n// Sanitize IDs to prevent path traversal from untrusted sources\nexport function sanitizeId(id: string): string {\n  return id.replace(/[^a-zA-Z0-9-_]/g, '-');\n}\n","import { CompassConfig } from './compass';\nimport { Service, Badge, ResolvedDependency, MarkdownTemplateFn, StructuredLink } from './types';\nimport { sanitizeHtml, sanitizeMarkdownText, sanitizeUrl } from './sanitize';\n\nenum UrlTypeToIcon {\n  CHAT_CHANNEL = '💬',\n  DOCUMENT = '📖',\n  DASHBOARD = '👀',\n  ON_CALL = '📲',\n  PROJECT = '🚀',\n  REPOSITORY = '🏡',\n  OTHER_LINK = '⭐',\n}\n\nconst UrlTypeToCategory: Record<string, string> = {\n  CHAT_CHANNEL: 'Chat Channel',\n  DOCUMENT: 'Document',\n  DASHBOARD: 'Dashboard',\n  ON_CALL: 'On-Call',\n  PROJECT: 'Project',\n  REPOSITORY: 'Repository',\n  OTHER_LINK: 'Other',\n};\n\nconst lifecycleColors: Record<string, { backgroundColor: string; textColor: string }> = {\n  Active: { backgroundColor: '#22c55e', textColor: '#fff' },\n  'Pre-release': { backgroundColor: '#f59e0b', textColor: '#fff' },\n  Deprecated: { backgroundColor: '#ef4444', textColor: '#fff' },\n};\n\nconst tierColors: Record<number, { backgroundColor: string; textColor: string }> = {\n  1: { backgroundColor: '#3b82f6', textColor: '#fff' },\n  2: { backgroundColor: '#6366f1', textColor: '#fff' },\n  3: { backgroundColor: '#8b5cf6', textColor: '#fff' },\n  4: { backgroundColor: '#a78bfa', textColor: '#fff' },\n};\n\nconst typeIdToIcon: Record<string, string> = {\n  APPLICATION: 'app-window',\n  SERVICE: 'server',\n  CAPABILITY: 'puzzle',\n  CLOUD_RESOURCE: 'cloud',\n  DATA_PIPELINE: 'workflow',\n  LIBRARY: 'library',\n  MACHINE_LEARNING_MODEL: 'brain',\n  OTHER: 'box',\n  UI_ELEMENT: 'layout',\n  WEBSITE: 'globe',\n};\n\nconst LINK_CATEGORIES: Array<{ label: string; types: string[] }> = [\n  { label: 'Development', types: ['REPOSITORY', 'PROJECT'] },\n  { label: 'Operations', types: ['DASHBOARD', 'ON_CALL', 'CHAT_CHANNEL'] },\n  { label: 'Documentation', types: ['DOCUMENT'] },\n  { label: 'Other', types: ['OTHER_LINK'] },\n];\n\nfunction buildBadges(config: CompassConfig): Badge[] {\n  const badges: Badge[] = [];\n\n  if (config.typeId) {\n    badges.push({\n      content: config.typeId,\n      backgroundColor: '#6366f1',\n      textColor: '#fff',\n    });\n  }\n\n  if (config.fields?.lifecycle) {\n    const colors = lifecycleColors[config.fields.lifecycle] || { backgroundColor: '#6b7280', textColor: '#fff' };\n    badges.push({\n      content: config.fields.lifecycle,\n      ...colors,\n    });\n  }\n\n  if (config.fields?.tier) {\n    const colors = tierColors[config.fields.tier] || { backgroundColor: '#6b7280', textColor: '#fff' };\n    badges.push({\n      content: `Tier ${config.fields.tier}`,\n      ...colors,\n    });\n  }\n\n  if (config.labels) {\n    for (const label of config.labels) {\n      badges.push({\n        content: label,\n        backgroundColor: '#e5e7eb',\n        textColor: '#374151',\n      });\n    }\n  }\n\n  return badges;\n}\n\nexport function buildStructuredLinks(\n  config: CompassConfig,\n  compassComponentUrl?: string,\n  compassTeamUrl?: string\n): StructuredLink[] {\n  const links: StructuredLink[] = [];\n\n  const safeComponentUrl = compassComponentUrl ? sanitizeUrl(compassComponentUrl) : '';\n  if (safeComponentUrl) {\n    links.push({ url: safeComponentUrl, title: 'Compass Component', type: 'Compass', icon: '🧭', rawType: 'COMPASS_COMPONENT' });\n  }\n\n  const safeTeamUrl = compassTeamUrl ? sanitizeUrl(compassTeamUrl) : '';\n  if (safeTeamUrl) {\n    links.push({ url: safeTeamUrl, title: 'Compass Team', type: 'Compass', icon: '🪂', rawType: 'COMPASS_TEAM' });\n  }\n\n  for (const link of config.links ?? []) {\n    const safeUrl = sanitizeUrl(link.url);\n    if (!safeUrl) continue;\n    const title = sanitizeHtml(link.name || new URL(safeUrl).hostname);\n    links.push({\n      url: safeUrl,\n      title,\n      type: UrlTypeToCategory[link.type] ?? 'Other',\n      icon: UrlTypeToIcon[link.type] ?? '🔗',\n      rawType: link.type,\n    });\n  }\n\n  return links;\n}\n\nfunction toTitleCase(text: string): string {\n  return text\n    .split(' ')\n    .map((word) => (word.length > 0 ? word[0].toUpperCase() + word.slice(1).toLowerCase() : ''))\n    .join(' ');\n}\n\nfunction buildCustomFieldsTable(config: CompassConfig): string {\n  if (!config.customFields || config.customFields.length === 0) return '';\n\n  const rows = config.customFields.map((field) => {\n    const safeName = sanitizeMarkdownText(toTitleCase(field.name)).replace(/\\\\/g, '\\\\\\\\').replace(/\\|/g, '\\\\|');\n    // js-yaml parses unquoted true/false as native booleans\n    const isBoolean = field.type === 'boolean' || typeof (field.value as unknown) === 'boolean';\n    const safeValue = isBoolean\n      ? (field.value as unknown) === true || field.value === 'true'\n        ? '✅'\n        : '❌'\n      : sanitizeMarkdownText(String(field.value)).replace(/\\\\/g, '\\\\\\\\').replace(/\\|/g, '\\\\|');\n    return `| ${safeName} | ${safeValue} |`;\n  });\n\n  return `## Custom Fields\n\n| Field Name | Value |\n|---|---|\n${rows.join('\\n')}`;\n}\n\nfunction getRepositoryUrl(config: CompassConfig): string | undefined {\n  return config.links?.find((link) => link.type === 'REPOSITORY')?.url;\n}\n\n// Extract team UUID from Compass ownerId ARN (e.g., ari:cloud:teams::team/UUID -> UUID)\nexport function extractTeamId(ownerId: string): string | undefined {\n  const parts = ownerId.split('/');\n  const teamId = parts[parts.length - 1];\n  return teamId || undefined;\n}\n\nfunction getOwners(config: CompassConfig): string[] {\n  if (!config.ownerId) return [];\n  const teamId = extractTeamId(config.ownerId);\n  return teamId ? [teamId] : [];\n}\n\nexport const defaultMarkdown = (\n  config: CompassConfig,\n  structuredLinks: StructuredLink[],\n  dependencies?: ResolvedDependency[]\n) => {\n  // Bucket structured links by type label\n  const compassLines: string[] = [];\n  const buckets = new Map<string, string[]>(LINK_CATEGORIES.map((c) => [c.label, []]));\n\n  for (const link of structuredLinks) {\n    // Title is already HTML-sanitized by buildStructuredLinks; only escape markdown brackets\n    const safeName = link.title.replace(/[[\\]()]/g, (char) => `\\\\${char}`);\n    const bullet = `* ${link.icon} [${safeName}](${link.url})`;\n\n    if (link.type === 'Compass') {\n      compassLines.push(bullet);\n    } else {\n      const category = LINK_CATEGORIES.find((c) => c.types.includes(link.rawType));\n      const bucketKey = category?.label ?? 'Other';\n      buckets.get(bucketKey)?.push(bullet);\n    }\n  }\n\n  // Build subsection blocks. \"Compass\" is always first.\n  const subsections: string[] = [];\n\n  if (compassLines.length > 0) {\n    subsections.push(`### Compass\\n\\n${compassLines.join('\\n')}`);\n  }\n\n  for (const { label } of LINK_CATEGORIES) {\n    const lines = buckets.get(label);\n    if (lines && lines.length > 0) {\n      subsections.push(`### ${label}\\n\\n${lines.join('\\n')}`);\n    }\n  }\n\n  const linksBlock = subsections.length > 0 ? subsections.join('\\n\\n') : '';\n\n  const customFieldsSection = buildCustomFieldsTable(config);\n\n  const dependencyLines =\n    dependencies && dependencies.length > 0\n      ? dependencies.map((dep) => `* [${sanitizeMarkdownText(dep.name)}](../../${dep.id}/)`).join('\\n')\n      : 'No known dependencies.';\n\n  return `\n\n## Links\n\n${linksBlock}\n${customFieldsSection ? '\\n' + customFieldsSection + '\\n' : ''}\n## Dependencies\n\n${dependencyLines}\n\n## Architecture diagram\n\n<NodeGraph />\n\n`;\n};\n\nconst getComponentUrl = (compassUrl: string, config: CompassConfig) => {\n  const parts = config?.id?.split('/');\n  let componentId = '/components';\n  if (parts) {\n    componentId = `/component/${parts[parts.length - 1]}`;\n  }\n  return `${compassUrl}${componentId}`;\n};\n\nconst getTeamUrl = (compassUrl: string, config: CompassConfig) => {\n  const parts = config?.ownerId?.split('/');\n  if (parts) {\n    return `${compassUrl}/people/team/${parts[parts.length - 1]}`;\n  }\n};\n\ntype SpecType = 'openapi' | 'asyncapi';\n\nfunction isRemoteUrl(path: string): boolean {\n  return path.startsWith('http://') || path.startsWith('https://');\n}\n\nfunction sanitizeLocalPath(path: string): string | null {\n  // Reject absolute paths and path traversal sequences\n  if (path.startsWith('/') || /(?:^|[\\\\/])\\.\\.(?:[\\\\/]|$)/.test(path)) return null;\n  return path;\n}\n\nfunction getSpecifications(config: CompassConfig): Array<{ type: SpecType; path: string; name?: string }> {\n  if (!config.links) return [];\n  const specs: Array<{ type: SpecType; path: string; name?: string }> = [];\n  for (const link of config.links) {\n    if (!link.name) continue;\n    // Skip remote URLs — EventCatalog expects local file paths for specifications.\n    // Remote links are already rendered in the markdown body.\n    if (isRemoteUrl(link.url)) continue;\n    const safePath = sanitizeLocalPath(link.url);\n    if (!safePath) continue;\n    const nameLower = link.name.toLowerCase();\n    if (nameLower.includes('openapi') || nameLower.includes('swagger')) {\n      specs.push({ type: 'openapi', path: safePath, name: link.name });\n    } else if (nameLower.includes('asyncapi')) {\n      specs.push({ type: 'asyncapi', path: safePath, name: link.name });\n    }\n  }\n  return specs;\n}\n\nexport function loadService(\n  config: CompassConfig,\n  compassUrl: string,\n  serviceVersion: string = '0.0.0',\n  serviceId: string = config.name,\n  dependencies?: ResolvedDependency[],\n  customMarkdownTemplate?: MarkdownTemplateFn,\n  badges: boolean = true\n): Service {\n  const componentUrl = getComponentUrl(compassUrl, config);\n  const teamUrl = getTeamUrl(compassUrl, config);\n  const structuredLinks = buildStructuredLinks(config, componentUrl, teamUrl);\n\n  const markdown = customMarkdownTemplate\n    ? customMarkdownTemplate(config, dependencies || [], structuredLinks)\n    : defaultMarkdown(config, structuredLinks, dependencies);\n  const serviceBadges = badges ? buildBadges(config) : [];\n  const repositoryUrl = getRepositoryUrl(config);\n  const owners = getOwners(config);\n  const specifications = getSpecifications(config);\n\n  const service: Service = {\n    id: serviceId,\n    name: config.name,\n    version: serviceVersion,\n    summary: config.description || '',\n    markdown,\n  };\n\n  if (serviceBadges.length > 0) {\n    service.badges = serviceBadges;\n  }\n\n  if (repositoryUrl) {\n    service.repository = { url: repositoryUrl };\n  }\n\n  if (owners.length > 0) {\n    service.owners = owners;\n  }\n\n  if (specifications.length > 0) {\n    service.specifications = specifications;\n  }\n\n  if (structuredLinks.length > 0) {\n    service.attachments = structuredLinks.map((link) => ({\n      url: link.url,\n      title: link.title,\n      type: link.type,\n      icon: link.icon,\n    }));\n  }\n\n  if (dependencies && dependencies.length > 0) {\n    service.sends = dependencies.map((dep) => ({ id: dep.id }));\n  }\n\n  if (config.typeId) {\n    const icon = typeIdToIcon[config.typeId];\n    if (icon) {\n      service.styles = { icon };\n    }\n  }\n\n  return service;\n}\n","import utils from '@eventcatalog/sdk';\nimport chalk from 'chalk';\nimport type { CompassConfig } from './compass';\nimport type { DomainOption, DomainSpec } from './types';\n\nfunction isDomainSpec(option: DomainOption): option is DomainSpec {\n  return 'id' in option && 'name' in option && 'version' in option;\n}\n\nexport function resolveDomain(config: CompassConfig, option: DomainOption): DomainSpec | null {\n  if (isDomainSpec(option)) {\n    return option;\n  }\n\n  if (option.from === 'label') {\n    if (config.labels) {\n      for (const label of config.labels) {\n        if (Object.prototype.hasOwnProperty.call(option.mapping, label)) {\n          return option.mapping[label];\n        }\n      }\n    }\n  } else if (option.from === 'customField' && option.key) {\n    const field = config.customFields?.find((f) => f.name === option.key);\n    if (field && typeof field.value === 'string' && Object.prototype.hasOwnProperty.call(option.mapping, field.value)) {\n      return option.mapping[field.value];\n    }\n  }\n\n  if (option.fallback && option.fallback !== 'skip') {\n    return option.fallback;\n  }\n  return null;\n}\n\nexport default class Domain {\n  id: string;\n  name: string;\n  version: string;\n  private sdk: ReturnType<typeof utils>;\n\n  constructor(id: string, name: string, version: string, projectDir: string) {\n    this.id = id;\n    this.name = name;\n    this.version = version;\n    this.sdk = utils(projectDir);\n  }\n\n  async processDomain() {\n    const { getDomain, writeDomain, versionDomain } = this.sdk;\n\n    // Try and get the domain\n    const domain = await getDomain(this.id, this.version || 'latest');\n    const currentDomain = await getDomain(this.id, 'latest');\n\n    console.log(chalk.blue(`\\nProcessing domain: ${this.name} (v${this.version})`));\n\n    // Found a domain, but the versions do not match\n    if (currentDomain && currentDomain.version !== this.version) {\n      await versionDomain(this.id);\n      console.log(chalk.cyan(` - Versioned previous domain (v${currentDomain.version})`));\n    }\n\n    // Do we need to create a new domain?\n    if (!domain || (domain && domain.version !== this.version)) {\n      await writeDomain({\n        id: this.id,\n        name: this.name,\n        version: this.version,\n        markdown: `## Architecture diagram\n  <NodeGraph />`,\n      });\n      console.log(chalk.cyan(` - Domain (v${this.version}) created`));\n    }\n\n    if (currentDomain && currentDomain.version === this.version) {\n      console.log(chalk.yellow(` - Domain (v${this.version}) already exists, skipped creation...`));\n    }\n  }\n\n  async addServiceToDomain(serviceId: string, serviceVersion: string = '0.0.0') {\n    const { addServiceToDomain } = this.sdk;\n\n    await addServiceToDomain(\n      this.id,\n      {\n        id: serviceId,\n        version: serviceVersion,\n      },\n      this.version\n    );\n    console.log(chalk.cyan(` - Service ID ${serviceId} version ${serviceVersion} added to domain ${this.id}!`));\n  }\n}\n","import { z } from 'zod';\n\nconst ServiceOptionsSchema = z.object({\n  id: z.string().optional(),\n  path: z.string().min(1, 'Service path is required'),\n  version: z.string().optional(),\n});\n\nconst DomainSpecSchema = z.object({\n  id: z.string().min(1),\n  name: z.string().min(1),\n  version: z.string().min(1),\n});\n\nconst DomainMappingSchema = z\n  .object({\n    from: z.enum(['label', 'customField']),\n    key: z.string().min(1).optional(),\n    mapping: z.record(z.string().min(1), DomainSpecSchema),\n    fallback: z.union([DomainSpecSchema, z.literal('skip')]).optional(),\n  })\n  .refine((data) => data.from !== 'customField' || !!data.key, {\n    message: '\"key\" is required when domain.from is \"customField\"',\n  });\n\nconst DomainOptionSchema = z.union([DomainSpecSchema, DomainMappingSchema]);\n\nconst ApiConfigSchema = z.object({\n  cloudId: z.string().min(1, 'cloudId is required'),\n  apiToken: z.string().min(1, 'apiToken is required'),\n  email: z.string().min(1, 'email is required'),\n  baseUrl: z\n    .string()\n    .url('baseUrl must be a valid URL')\n    .refine((url) => url.startsWith('https://'), { message: 'baseUrl must use HTTPS to protect API credentials' }),\n  typeFilter: z.array(z.string().min(1)).optional(),\n});\n\nconst ServiceIdStrategySchema = z.union([z.enum(['name', 'compass-id']), z.function()]);\n\nexport const GeneratorPropsSchema = z\n  .object({\n    services: z.array(ServiceOptionsSchema).min(1, 'At least one service is required').optional(),\n    api: ApiConfigSchema.optional(),\n    compassUrl: z.string().url('compassUrl must be a valid URL'),\n    domain: DomainOptionSchema.optional(),\n    debug: z.boolean().optional(),\n    overrideExisting: z.boolean().optional(),\n    typeFilter: z.array(z.string().min(1)).optional(),\n    nameFilter: z.array(z.string().min(1)).optional(),\n    nameMapping: z.record(z.string().min(1), z.string().min(1)).optional(),\n    markdownTemplate: z.function().optional(),\n    format: z.enum(['md', 'mdx']).optional(),\n    serviceIdStrategy: ServiceIdStrategySchema.optional(),\n    dryRun: z.boolean().optional(),\n    defaultVersion: z.string().min(1).optional(),\n    badges: z.boolean().optional(),\n    incremental: z.boolean().optional(),\n  })\n  .refine((data) => data.services || data.api, {\n    message: 'Either \"services\" (YAML mode) or \"api\" (API mode) must be provided',\n  })\n  .refine((data) => !(data.services && data.api), {\n    message: 'Cannot use both \"services\" and \"api\" — choose one mode',\n  });\n","import { CompassConfig } from './compass';\nimport { ApiConfig } from './types';\nimport { sanitizeHtml } from './sanitize';\n\n// Type-level extraction from CompassConfig to avoid importing internal enums\ntype LinkType = NonNullable<CompassConfig['links']>[number]['type'];\ntype FieldType = NonNullable<CompassConfig['fields']>;\ntype CustomFieldType = NonNullable<CompassConfig['customFields']>[number]['type'];\n\n// GraphQL response types — validated against Atlassian Compass API documentation\n// and community examples (see https://community.atlassian.com/forums/Compass-questions/\n// graphql-to-search-for-all-components/qaq-p/2472308)\ntype GraphQLField = {\n  definition: { name: string };\n  value?: string; // via ... on CompassEnumField { value }\n};\n\ntype GraphQLScorecardScore = {\n  scorecardId: string;\n  totalScore: number;\n  maxTotalScore: number;\n};\n\ntype GraphQLComponent = {\n  id: string;\n  name: string;\n  typeId: string;\n  description: string | null;\n  ownerId: string | null;\n  fields: GraphQLField[] | null;\n  links: Array<{\n    type: string;\n    url: string;\n    name: string | null;\n  }> | null;\n  relationships: {\n    nodes?: Array<{\n      relationshipType: string;\n      endNode: { id: string } | null;\n    }>;\n  } | null;\n  labels: Array<{ name: string }> | null;\n  customFields: Array<{\n    definition: { name: string };\n    textValue?: string;\n    booleanValue?: boolean;\n    numberValue?: number;\n  }> | null;\n  scorecardScores: GraphQLScorecardScore[] | null;\n};\n\ntype SearchComponentsResult = {\n  __typename: string;\n  nodes?: Array<{ component: GraphQLComponent }>;\n  pageInfo?: {\n    hasNextPage: boolean;\n    endCursor: string | null;\n  };\n  message?: string;\n  identifier?: string;\n};\n\ntype SearchComponentsResponse = {\n  data?: {\n    compass: {\n      searchComponents: SearchComponentsResult;\n    };\n  };\n  errors?: Array<{ message: string }>;\n};\n\n// Query validated against Compass GraphQL API docs. Key corrections from docs:\n// - Component type field is `typeId` (not `type`)\n// - Labels are objects: `labels { name }` (not plain strings)\n// - Lifecycle/tier use CompassEnumField fragment: `fields { definition { name } ... on CompassEnumField { value } }`\n// - Relationship nodes use `nodeId` (matching creation API input)\nconst SEARCH_COMPONENTS_QUERY = `\n  query searchComponents($cloudId: String!, $after: String) {\n    compass {\n      searchComponents(\n        cloudId: $cloudId\n        query: { after: $after, first: 50 }\n      ) {\n        __typename\n        ... on QueryError { message identifier }\n        ... on CompassSearchComponentConnection {\n          nodes {\n            component {\n              id\n              name\n              typeId\n              description\n              ownerId\n              fields {\n                definition { name }\n                ... on CompassEnumField { value }\n              }\n              links {\n                type\n                url\n                name\n              }\n              relationships {\n                ... on CompassRelationshipConnection {\n                  nodes {\n                    relationshipType\n                    endNode { id }\n                  }\n                }\n              }\n              labels { name }\n              customFields {\n                definition { name }\n                ... on CompassCustomTextField { textValue }\n                ... on CompassCustomBooleanField { booleanValue }\n                ... on CompassCustomNumberField { numberValue }\n              }\n              scorecardScores {\n                scorecardId\n                totalScore\n                maxTotalScore\n              }\n            }\n          }\n          pageInfo {\n            hasNextPage\n            endCursor\n          }\n        }\n      }\n    }\n  }\n`;\n\nconst FETCH_TIMEOUT_MS = 30_000;\n\nexport function resolveValue(value: string): string {\n  if (value.startsWith('$')) {\n    const envVar = value.slice(1);\n    const resolved = process.env[envVar];\n    if (!resolved) throw new Error(`Environment variable ${envVar} is not set`);\n    return resolved;\n  }\n  return value;\n}\n\nfunction buildAuthHeader(email: string, apiToken: string): string {\n  return `Basic ${Buffer.from(`${email}:${apiToken}`).toString('base64')}`;\n}\n\nconst sanitizeText = sanitizeHtml;\n\nfunction mapTier(value: unknown): 1 | 2 | 3 | 4 | undefined {\n  if (value == null) return undefined;\n  // Handle numeric values directly\n  if (typeof value === 'number') {\n    if (value >= 1 && value <= 4) return value as 1 | 2 | 3 | 4;\n    return undefined;\n  }\n  const str = String(value);\n  const match = str.match(/(\\d)/);\n  if (match) {\n    const num = parseInt(match[1], 10);\n    if (num >= 1 && num <= 4) return num as 1 | 2 | 3 | 4;\n  }\n  return undefined;\n}\n\nfunction mapLifecycle(value: unknown): string | undefined {\n  if (value == null) return undefined;\n  const str = String(value);\n  if (!str) return undefined;\n  // API may return uppercase (ACTIVE) or title case (Active) — normalize both\n  const normalized = str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();\n  const valid: Record<string, string> = {\n    Active: 'Active',\n    'Pre-release': 'Pre-release',\n    Prerelease: 'Pre-release',\n    Deprecated: 'Deprecated',\n  };\n  return valid[normalized] || valid[str];\n}\n\nfunction extractField(fields: GraphQLField[] | null, fieldName: string): string | undefined {\n  if (!fields) return undefined;\n  const field = fields.find((f) => f.definition.name.toLowerCase() === fieldName.toLowerCase());\n  return field?.value || undefined;\n}\n\n// Extract a readable name from a scorecard ARI (e.g., ari:cloud:compass:...:scorecard/.../UUID → UUID).\n// If the value is already a plain name (no colons), return it as-is.\nfunction extractScorecardName(scorecardId: string): string {\n  if (!scorecardId.includes(':')) return scorecardId;\n  const parts = scorecardId.split('/');\n  return parts[parts.length - 1] || scorecardId;\n}\n\nfunction mapComponent(component: GraphQLComponent, scorecardNames?: Map<string, string>): CompassConfig {\n  const config: CompassConfig = {\n    name: component.name,\n    id: component.id,\n    description: component.description || undefined,\n    typeId: component.typeId as CompassConfig['typeId'],\n  };\n\n  if (component.ownerId) {\n    config.ownerId = component.ownerId;\n  }\n\n  const lifecycle = mapLifecycle(extractField(component.fields, 'lifecycle'));\n  const tier = mapTier(extractField(component.fields, 'tier'));\n  if (lifecycle || tier) {\n    config.fields = { lifecycle: lifecycle as FieldType['lifecycle'], tier };\n  }\n\n  if (component.links && component.links.length > 0) {\n    config.links = component.links.map((link) => ({\n      type: link.type as LinkType,\n      url: link.url,\n      name: link.name || undefined,\n    }));\n  }\n\n  if (component.relationships?.nodes && component.relationships.nodes.length > 0) {\n    const dependsOn = component.relationships.nodes\n      .filter((r) => r.relationshipType === 'DEPENDS_ON' && r.endNode?.id)\n      .map((r) => r.endNode!.id);\n    if (dependsOn.length > 0) {\n      config.relationships = { DEPENDS_ON: dependsOn };\n    }\n  }\n\n  if (component.labels && component.labels.length > 0) {\n    config.labels = component.labels.map((l) => l.name);\n  }\n\n  if (component.customFields && component.customFields.length > 0) {\n    config.customFields = component.customFields.map((cf) => {\n      // Infer type from which value field is populated (API doesn't expose type on definition)\n      let type: CustomFieldType = 'text' as CustomFieldType;\n      if (cf.booleanValue !== undefined && cf.booleanValue !== null) type = 'boolean' as CustomFieldType;\n      else if (cf.numberValue !== undefined && cf.numberValue !== null) type = 'number' as CustomFieldType;\n      const rawValue = cf.textValue ?? String(cf.booleanValue ?? cf.numberValue ?? '');\n      return {\n        type,\n        name: cf.definition.name,\n        value: type === 'text' ? sanitizeText(rawValue) : rawValue,\n      };\n    });\n  }\n\n  if (component.scorecardScores && component.scorecardScores.length > 0) {\n    config.scorecards = component.scorecardScores.map((sc) => ({\n      name: scorecardNames?.get(sc.scorecardId) ?? extractScorecardName(sc.scorecardId),\n      score: sc.totalScore,\n      maxScore: sc.maxTotalScore,\n    }));\n  }\n\n  return config;\n}\n\n// Enriched team data returned by fetchTeamById\nexport type TeamData = {\n  id: string;\n  displayName: string;\n  description?: string;\n  largeAvatarImageUrl?: string;\n  members?: Array<{ accountId: string; name: string; picture?: string }>;\n};\n\n// GraphQL query to fetch enriched team data — uses Teams v2 API\nconst GET_TEAM_QUERY = `\n  query getTeam($teamId: ID!, $siteId: String!) {\n    team {\n      teamV2(id: $teamId, siteId: $siteId) {\n        id\n        displayName\n        description\n        largeAvatarImageUrl\n        members(first: 50) {\n          nodes {\n            member {\n              accountId\n              name\n              picture\n            }\n          }\n        }\n      }\n    }\n  }\n`;\n\ntype GetTeamMember = {\n  accountId: string;\n  name: string;\n  picture?: string;\n};\n\ntype GetTeamResponse = {\n  data?: {\n    team: {\n      teamV2: {\n        id: string;\n        displayName: string;\n        description?: string;\n        largeAvatarImageUrl?: string;\n        members?: {\n          nodes?: Array<{ member: GetTeamMember }>;\n        };\n      } | null;\n    };\n  };\n  errors?: Array<{ message: string }>;\n};\n\nexport async function fetchTeamById(\n  config: Pick<ApiConfig, 'apiToken' | 'email' | 'baseUrl' | 'cloudId'>,\n  teamId: string\n): Promise<TeamData | null> {\n  const resolvedToken = resolveValue(config.apiToken);\n  const resolvedEmail = resolveValue(config.email);\n  const endpoint = `${config.baseUrl.replace(/\\/$/, '')}/gateway/api/graphql`;\n  const authHeader = buildAuthHeader(resolvedEmail, resolvedToken);\n\n  // The Teams v2 API expects the full ARI as ID — construct it if we only have a UUID\n  const teamAri = teamId.startsWith('ari:') ? teamId : `ari:cloud:identity::team/${teamId}`;\n\n  const response = await fetch(endpoint, {\n    method: 'POST',\n    headers: {\n      'Content-Type': 'application/json',\n      Authorization: authHeader,\n      Accept: 'application/json',\n      'X-ExperimentalApi': 'teams-beta',\n    },\n    body: JSON.stringify({\n      query: GET_TEAM_QUERY,\n      variables: { teamId: teamAri, siteId: config.cloudId },\n    }),\n    signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),\n  });\n\n  if (!response.ok) {\n    console.warn(`Team API request failed for ${teamId} (HTTP ${response.status})`);\n    return null;\n  }\n\n  const result = (await response.json()) as GetTeamResponse;\n\n  if (result.errors) {\n    console.warn(`Team API GraphQL error for ${teamId}: ${result.errors[0]?.message}`);\n    return null;\n  }\n\n  if (!result.data) {\n    console.warn(`Team API returned no data for ${teamId}`);\n    return null;\n  }\n\n  const team = result.data.team?.teamV2;\n  if (!team) {\n    console.warn(`Team not found for ID ${teamId}`);\n    return null;\n  }\n\n  const members = team.members?.nodes?.length\n    ? team.members.nodes.map((n) => ({\n        accountId: n.member.accountId,\n        name: n.member.name,\n        picture: n.member.picture || undefined,\n      }))\n    : undefined;\n\n  return {\n    id: team.id,\n    displayName: team.displayName,\n    ...(team.description && { description: team.description }),\n    ...(team.largeAvatarImageUrl && { largeAvatarImageUrl: team.largeAvatarImageUrl }),\n    ...(members && { members }),\n  };\n}\n\n// GraphQL query to fetch all scorecards for the cloud instance\nconst GET_SCORECARDS_QUERY = `\n  query getScorecards($cloudId: ID!) {\n    compass {\n      scorecards(cloudId: $cloudId, query: { first: 100 }) {\n        __typename\n        ... on QueryError { message identifier }\n        ... on CompassScorecardConnection {\n          nodes {\n            id\n            name\n          }\n        }\n      }\n    }\n  }\n`;\n\ntype GetScorecardsResponse = {\n  data?: {\n    compass: {\n      scorecards: {\n        __typename: string;\n        nodes?: Array<{ id: string; name: string }>;\n        message?: string;\n      };\n    };\n  };\n  errors?: Array<{ message: string }>;\n};\n\nexport async function fetchScorecardNames(\n  config: Pick<ApiConfig, 'apiToken' | 'email' | 'baseUrl' | 'cloudId'>\n): Promise<Map<string, string>> {\n  const resolvedToken = resolveValue(config.apiToken);\n  const resolvedEmail = resolveValue(config.email);\n  const endpoint = `${config.baseUrl.replace(/\\/$/, '')}/gateway/api/graphql`;\n  const authHeader = buildAuthHeader(resolvedEmail, resolvedToken);\n\n  try {\n    const response = await fetch(endpoint, {\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/json',\n        Authorization: authHeader,\n        Accept: 'application/json',\n      },\n      body: JSON.stringify({\n        query: GET_SCORECARDS_QUERY,\n        variables: { cloudId: config.cloudId },\n      }),\n      signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),\n    });\n\n    if (!response.ok) {\n      console.warn(`Could not fetch scorecard names (HTTP ${response.status}), will use short IDs`);\n      return new Map();\n    }\n\n    const result = (await response.json()) as GetScorecardsResponse;\n    if (result.errors) {\n      console.warn(`Scorecard API GraphQL error: ${result.errors[0]?.message}, will use short IDs`);\n      return new Map();\n    }\n\n    const scorecards = result.data?.compass?.scorecards;\n    if (!scorecards?.nodes) {\n      const errorMsg = scorecards?.message || 'no data returned';\n      console.warn(`Could not fetch scorecard names (${errorMsg}), will use short IDs`);\n      return new Map();\n    }\n\n    const map = new Map<string, string>();\n    for (const sc of scorecards.nodes) {\n      map.set(sc.id, sc.name);\n    }\n    console.log(`Fetched ${map.size} scorecard name(s) from Compass API`);\n    return map;\n  } catch {\n    console.warn('Failed to fetch scorecard names, will use short IDs');\n    return new Map();\n  }\n}\n\nexport async function fetchComponents(config: ApiConfig, scorecardNames?: Map<string, string>): Promise<CompassConfig[]> {\n  const resolvedToken = resolveValue(config.apiToken);\n  const resolvedEmail = resolveValue(config.email);\n  const endpoint = `${config.baseUrl.replace(/\\/$/, '')}/gateway/api/graphql`;\n  const authHeader = buildAuthHeader(resolvedEmail, resolvedToken);\n\n  const components: CompassConfig[] = [];\n  let cursor: string | null = null;\n  let hasNextPage = true;\n\n  while (hasNextPage) {\n    const variables: Record<string, unknown> = {\n      cloudId: config.cloudId,\n      after: cursor,\n    };\n\n    const response = await fetch(endpoint, {\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/json',\n        Authorization: authHeader,\n        Accept: 'application/json',\n      },\n      body: JSON.stringify({\n        query: SEARCH_COMPONENTS_QUERY,\n        variables,\n      }),\n      signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),\n    });\n\n    if (!response.ok) {\n      if (response.status === 401) {\n        throw new Error('Compass API authentication failed: invalid email or API token');\n      }\n      if (response.status === 403) {\n        throw new Error('Compass API authorization failed: insufficient permissions');\n      }\n      if (response.status === 429) {\n        throw new Error('Compass API rate limit exceeded: too many requests');\n      }\n      throw new Error(`Compass API request failed with status ${response.status}`);\n    }\n\n    const result = (await response.json()) as SearchComponentsResponse;\n\n    if (result.errors && result.errors.length > 0) {\n      throw new Error(`Compass GraphQL error: ${result.errors[0].message}`);\n    }\n\n    if (!result.data) {\n      throw new Error('Compass API returned no data');\n    }\n\n    const searchResult = result.data.compass.searchComponents;\n\n    if (searchResult.__typename === 'QueryError') {\n      throw new Error(`Compass API error: ${searchResult.message || 'Unknown error'}`);\n    }\n\n    if (!searchResult.nodes || !searchResult.pageInfo) {\n      throw new Error('Compass API returned unexpected response structure');\n    }\n\n    for (const node of searchResult.nodes) {\n      components.push(mapComponent(node.component, scorecardNames));\n    }\n\n    hasNextPage = searchResult.pageInfo.hasNextPage;\n    cursor = searchResult.pageInfo.endCursor;\n  }\n\n  return components;\n}\n\nconst UPDATE_COMPONENT_MUTATION = `\n  mutation updateComponent($id: ID!, $ownerId: ID!) {\n    compass {\n      updateComponent(input: { id: $id, ownerId: $ownerId }) {\n        success\n        errors { message }\n        componentDetails { id ownerId }\n      }\n    }\n  }\n`;\n\ntype UpdateComponentResponse = {\n  data?: {\n    compass: {\n      updateComponent: {\n        success: boolean;\n        errors: Array<{ message: string }> | null;\n        componentDetails?: { id: string; ownerId: string | null };\n      };\n    };\n  };\n  errors?: Array<{ message: string }>;\n};\n\nexport async function updateComponentOwner(\n  config: Pick<ApiConfig, 'apiToken' | 'email' | 'baseUrl'>,\n  componentId: string,\n  ownerAri: string\n): Promise<void> {\n  const resolvedToken = resolveValue(config.apiToken);\n  const resolvedEmail = resolveValue(config.email);\n  const endpoint = `${config.baseUrl.replace(/\\/$/, '')}/gateway/api/graphql`;\n  const authHeader = buildAuthHeader(resolvedEmail, resolvedToken);\n\n  const response = await fetch(endpoint, {\n    method: 'POST',\n    headers: {\n      'Content-Type': 'application/json',\n      Authorization: authHeader,\n      Accept: 'application/json',\n    },\n    body: JSON.stringify({\n      query: UPDATE_COMPONENT_MUTATION,\n      variables: { id: componentId, ownerId: ownerAri },\n    }),\n    signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),\n  });\n\n  if (!response.ok) {\n    throw new Error(`Compass updateComponent request failed with status ${response.status}`);\n  }\n\n  const result = (await response.json()) as UpdateComponentResponse;\n\n  if (result.errors && result.errors.length > 0) {\n    throw new Error(result.errors[0].message);\n  }\n\n  const payload = result.data?.compass?.updateComponent;\n  if (payload?.errors && payload.errors.length > 0) {\n    throw new Error(`Compass update component error: ${payload.errors[0].message}`);\n  }\n}\n"],"mappings":"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","names":["utils","chalk","UrlTypeToIcon","chalk","utils"]}