# velkugan/apim-dependency-explorer architecture

> Architecture diagram of the GitHub repository velkugan/apim-dependency-explorer, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-08-12). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/velkugan/apim-dependency-explorer
- Repository: https://github.com/velkugan/apim-dependency-explorer

## Overview

#### Purpose and Extension Entry Points
APIM Dependency Explorer is a Chrome/Edge MV3 side-panel extension for discovering Azure API Management (APIM) API dependencies. Its runtime starts from `manifest.json`; the service worker in `src/background.js` configures side-panel behavior and optionally captures ARM bearer tokens. The interactive application is `src/sidepanel.html` and `src/sidepanel.js`.

#### Side-Panel Control Flow
`src/sidepanel.js` owns user interaction, token entry/session restoration, APIM service selection, API listing, expansion state, and report rendering. Initial API listing is lightweight. Expanding an API triggers dependency resolution; a service-wide catalog is lazily fetched once and retained for subsequent expansions. `src/sidepanel.css` provides the panel presentation and dependency fingerprint UI.

#### Azure Resource Manager Boundary
All Azure access is direct browser-side ARM REST traffic to `https://management.azure.com`, enabled by extension host permissions. `src/lib/arm.js` is the transport boundary: ARM paging, response caching, concurrency control, and retry/backoff behavior for throttling. `src/lib/apim.js` maps APIM concepts to ARM endpoints, parses resource IDs, and discovers APIM services/resources. Tokens are either user-provided or observed from portal ARM traffic by `src/background.js`; session tokens remain in `chrome.storage.session`.

#### Catalog and Per-API Resolution
`src/lib/resolver.js` is the orchestration layer. It builds reusable service-wide lookup tables for named values, backends, policy fragments, certificates, and loggers, then resolves an expanded API’s policy graph and associated APIM resources. Resolution covers API and optional operation policies, applicable product policies, recursively included fragments with cycle detection, and global policy only where `<base />` semantics require it. It also joins discovered references to backend credentials, Key Vault metadata, diagnostics, identities, caches, OAuth/OpenID resources, and outbound URLs.

#### Policy Dependency Analysis
`src/lib/policy-analyzer.js` parses policy XML and classifies references rather than regexing raw policy text. It distinguishes actual named values from Liquid variables, C# expression content, and APIM policy variables. Its output separates valid dependencies from unresolved links, variable lookalikes, and excluded moustaches. This classification is a critical correctness boundary consumed by `src/lib/resolver.js` when turning policy text into resolvable ARM resources.

#### Data Shaping and Comparison
`src/lib/compare.js` supports dependency comparison/fingerprinting used by the UI to summarize dependency classes and identify broken references. `src/lib/util.js` supplies shared infrastructure such as JWT decoding and bounded async work pools. The UI receives resolved, categorized dependency data rather than issuing policy/resource calls itself.

#### Reporting and Non-Extension Execution
`src/report.html`, `src/report.js`, and `src/report.css` provide a separate report-oriented rendering surface for dependency results. The policy classifier can also run outside Chrome: `tools/test-analyzer.mjs` exercises `src/lib/policy-analyzer.js` in Node using `linkedom`, isolating XML/classification behavior from browser extension and ARM runtime concerns.

Main entry points: [`src/lib/resolver.js`](https://github.com/velkugan/apim-dependency-explorer/blob/main/src/lib/resolver.js) (Dependency Resolver), [`src/background.js`](https://github.com/velkugan/apim-dependency-explorer/blob/main/src/background.js) (Service Worker), [`src/sidepanel.js`](https://github.com/velkugan/apim-dependency-explorer/blob/main/src/sidepanel.js) (Side Panel App), [`manifest.json`](https://github.com/velkugan/apim-dependency-explorer/blob/main/manifest.json) (MV3 Manifest)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_extension["Extension Runtime"]
  node_manifest["MV3 Manifest<br/>extension entrypoint<br/>[manifest.json]"]
  node_background["Service Worker<br/>background runtime<br/>[background.js]"]
  node_session[("Session Token Store<br/>chrome storage")]
end

subgraph group_ui["Rendering Surfaces"]
  node_sidepanel["Side Panel App<br/>interactive UI<br/>[sidepanel.js]"]
  node_sidepanel_view["Side Panel View<br/>HTML/CSS view<br/>[sidepanel.html]"]
  node_report["Report Renderer<br/>report UI<br/>[report.js]"]
  node_report_view["Report View<br/>HTML/CSS view<br/>[report.html]"]
end

subgraph group_resolution["Dependency Resolution"]
  node_resolver["Dependency Resolver<br/>resolution orchestrator<br/>[resolver.js]"]
  node_catalog[("Service Lookup Catalog<br/>cached lookup tables")]
  node_policy_analyzer["Policy Analyzer<br/>XML dependency classifier<br/>[policy-analyzer.js]"]
  node_compare["Dependency Comparison<br/>fingerprinting<br/>[compare.js]"]
  node_analyzer_tool["Node Policy Analyzer Tool<br/>standalone runner<br/>[test-analyzer.mjs]"]
end

subgraph group_azure["Azure Boundary"]
  node_apim["APIM Resource Adapter<br/>APIM endpoint mapping<br/>[apim.js]"]
  node_arm["ARM Transport<br/>REST client<br/>[arm.js]"]
  node_azure_arm{{"Azure Resource Manager<br/>external API"}}
end

node_manifest -->|"starts"| node_background
node_manifest -->|"opens"| node_sidepanel_view
node_sidepanel_view -->|"hosts"| node_sidepanel
node_background -->|"stores observed token"| node_session
node_sidepanel -->|"restores or saves token"| node_session
node_sidepanel -->|"resolves expanded API"| node_resolver
node_resolver -->|"builds and reuses"| node_catalog
node_resolver -->|"classifies policy XML"| node_policy_analyzer
node_resolver -->|"produces categorized data"| node_compare
node_resolver -->|"discovers APIM resources"| node_apim
node_apim -->|"uses"| node_arm
node_arm -->|"ARM REST"| node_azure_arm
node_background -.->|"observes portal token traffic"| node_azure_arm
node_report_view -->|"hosts"| node_report
node_report -->|"renders dependency summaries"| node_compare
node_analyzer_tool -->|"runs in Node"| node_policy_analyzer

click node_manifest "https://github.com/velkugan/apim-dependency-explorer/blob/main/manifest.json"
click node_background "https://github.com/velkugan/apim-dependency-explorer/blob/main/src/background.js"
click node_sidepanel "https://github.com/velkugan/apim-dependency-explorer/blob/main/src/sidepanel.js"
click node_sidepanel_view "https://github.com/velkugan/apim-dependency-explorer/blob/main/src/sidepanel.html"
click node_report "https://github.com/velkugan/apim-dependency-explorer/blob/main/src/report.js"
click node_report_view "https://github.com/velkugan/apim-dependency-explorer/blob/main/src/report.html"
click node_resolver "https://github.com/velkugan/apim-dependency-explorer/blob/main/src/lib/resolver.js"
click node_policy_analyzer "https://github.com/velkugan/apim-dependency-explorer/blob/main/src/lib/policy-analyzer.js"
click node_compare "https://github.com/velkugan/apim-dependency-explorer/blob/main/src/lib/compare.js"
click node_apim "https://github.com/velkugan/apim-dependency-explorer/blob/main/src/lib/apim.js"
click node_arm "https://github.com/velkugan/apim-dependency-explorer/blob/main/src/lib/arm.js"
click node_analyzer_tool "https://github.com/velkugan/apim-dependency-explorer/blob/main/tools/test-analyzer.mjs"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_manifest,node_background,node_session toneBlue
class node_sidepanel,node_sidepanel_view,node_report,node_report_view toneAmber
class node_resolver,node_catalog,node_policy_analyzer,node_compare,node_analyzer_tool toneMint
class node_apim,node_arm,node_azure_arm toneRose
```

## Components

### Extension Runtime

- [MV3 Manifest](https://github.com/velkugan/apim-dependency-explorer/blob/main/manifest.json): extension entrypoint · Declares extension runtime and ARM host access. · `manifest.json`
- [Service Worker](https://github.com/velkugan/apim-dependency-explorer/blob/main/src/background.js): background runtime · Configures the side panel and may capture portal ARM tokens. · `src/background.js`
- **Session Token Store**: chrome storage · Stores tokens only for the browser session.

### Rendering Surfaces

- [Side Panel App](https://github.com/velkugan/apim-dependency-explorer/blob/main/src/sidepanel.js): interactive UI · Controls service/API selection, expansion, and dependency rendering. · `src/sidepanel.js`
- [Side Panel View](https://github.com/velkugan/apim-dependency-explorer/blob/main/src/sidepanel.html): HTML/CSS view · `src/sidepanel.html`
- [Report Renderer](https://github.com/velkugan/apim-dependency-explorer/blob/main/src/report.js): report UI · Separate rendering surface for dependency results. · `src/report.js`
- [Report View](https://github.com/velkugan/apim-dependency-explorer/blob/main/src/report.html): HTML/CSS view · `src/report.html`

### Dependency Resolution

- [Dependency Resolver](https://github.com/velkugan/apim-dependency-explorer/blob/main/src/lib/resolver.js): resolution orchestrator · Resolves expanded APIs, policy graphs, and linked APIM resources. · `src/lib/resolver.js`
- **Service Lookup Catalog**: cached lookup tables · Lazy reusable catalog of named values, backends, fragments, certificates, and loggers.
- [Policy Analyzer](https://github.com/velkugan/apim-dependency-explorer/blob/main/src/lib/policy-analyzer.js): XML dependency classifier · Classifies real policy references and excludes variable lookalikes. · `src/lib/policy-analyzer.js`
- [Dependency Comparison](https://github.com/velkugan/apim-dependency-explorer/blob/main/src/lib/compare.js): fingerprinting · Summarizes dependency classes and broken references. · `src/lib/compare.js`
- [Node Policy Analyzer Tool](https://github.com/velkugan/apim-dependency-explorer/blob/main/tools/test-analyzer.mjs): standalone runner · Runs policy classification outside Chrome using linkedom. · `tools/test-analyzer.mjs`

### Azure Boundary

- [APIM Resource Adapter](https://github.com/velkugan/apim-dependency-explorer/blob/main/src/lib/apim.js): APIM endpoint mapping · Maps APIM concepts to ARM resources and parses resource IDs. · `src/lib/apim.js`
- [ARM Transport](https://github.com/velkugan/apim-dependency-explorer/blob/main/src/lib/arm.js): REST client · Provides paging, caching, concurrency limits, and throttling retries. · `src/lib/arm.js`
- **Azure Resource Manager**: external API

## Connections

- MV3 Manifest → Service Worker: starts
- MV3 Manifest → Side Panel View: opens
- Side Panel View → Side Panel App: hosts
- Service Worker → Session Token Store: stores observed token
- Side Panel App → Session Token Store: restores or saves token
- Side Panel App → Dependency Resolver: resolves expanded API
- Dependency Resolver → Service Lookup Catalog: builds and reuses
- Dependency Resolver → Policy Analyzer: classifies policy XML
- Dependency Resolver → Dependency Comparison: produces categorized data
- Dependency Resolver → APIM Resource Adapter: discovers APIM resources
- APIM Resource Adapter → ARM Transport: uses
- ARM Transport → Azure Resource Manager: ARM REST
- Service Worker → Azure Resource Manager: observes portal token traffic
- Report View → Report Renderer: hosts
- Report Renderer → Dependency Comparison: renders dependency summaries
- Node Policy Analyzer Tool → Policy Analyzer: runs in Node
