## Registry Crosswalk Documentation
This document describes the mapping between each registry's API and our YAMLFrontmatter type. Each registry section includes the API URL(s) used and a detailed crosswalk table showing how API fields map to our internal data structure.
### YAMLFrontmatter Structure
Our internal data structure (`YAMLFrontmatter`) has the following properties:
```typescript
interface YAMLFrontmatter {
type: string; // Type of resource (e.g., 'software')
id: string; // Unique identifier
title: string; // Display name
aliases: string[]; // Alternative names
author: string[]; // Authors/creators (formatted as [[Name]])
description: string; // Description text
source_url: string; // Primary URL
github_url: string; // GitHub repository URL
image_url: string; // Image/avatar URL
platform: string[]; // Platforms (formatted as [[Platform]])
dependencies: string[]; // Dependencies (formatted as [[Dependency]])
subtype: string; // Subtype (e.g., 'npm', 'gem', 'CLI', 'extension')
tags: string[]; // Tags/keywords
}
```
---
### NPM
#### API URLs
- **Search**: `https://registry.npmjs.org/-/v1/search?text={{query}}&size=10`
- **Details**: `https://registry.npmjs.org/{{packageName}}`
#### Crosswalk
| YAMLFrontmatter Property | NPM API Mapping | Notes |
| ------------------------ | ------------------------------------------------------ | --------------------------------------------- |
| type | `'software'` | Hardcoded |
| id | `.name` | Package name |
| title | `.name` | Package name |
| aliases | `[]` | Always empty array |
| author | `.author.name` | Formatted as `[[Name]]`, defaults to `[]` |
| description | `.description` or `.versions[latest].description` | Defaults to `''` |
| source_url | `.homepage` or `https://www.npmjs.com/package/${name}` | Uses homepage if available |
| github_url | `.repository.url` or `.repository` | Normalized GitHub URL, defaults to `''` |
| image_url | `''` | Always empty string |
| platform | `[]` | Always empty array |
| dependencies | `Object.keys(.versions[latest].dependencies)` | Each formatted as `[[dep]]`, defaults to `[]` |
| subtype | `'npm'` | Hardcoded |
| tags | `.keywords` | Defaults to `[]` |
#### Search Result Mapping
| SearchResult Property | NPM API Mapping |
| --------------------- | ----------------------------- |
| id | `.package.name` |
| name | `.package.name` |
| description | `.package.description` |
| author | `.package.publisher.username` |
| version | `.package.version` |
| --- | --- |
### RubyGems
#### API URLs
- **Search**: `https://rubygems.org/api/v1/search.json?query={{query}}`
- **Direct Lookup**: `https://rubygems.org/api/v1/gems/{{gemName}}.json`
- **Dependencies**: `https://rubygems.org/api/v1/versions/{{gemName}}/latest.json`
#### Crosswalk
| YAMLFrontmatter Property | RubyGems API Mapping | Notes |
| ------------------------ | ------------------------------------------------------------------------ | ----------------------------------------------------------------- |
| type | `'software'` | Hardcoded |
| id | `.name` | Gem name |
| title | `.name` | Gem name |
| aliases | `[]` | Always empty array |
| author | `.authors` | Parsed as CSV or array, each formatted as `[[Name]]` |
| description | `.info` | Defaults to `''` |
| source_url | `.homepage_uri` or `.project_uri` or `https://rubygems.org/gems/${name}` | Falls back through options |
| github_url | `.source_code_uri` | Normalized GitHub URL, defaults to `''` |
| image_url | `''` | Always empty string |
| platform | `['[[Ruby]]']` | Hardcoded |
| dependencies | `.dependencies.runtime[].name` | From versions API, each formatted as `[[name]]`, defaults to `[]` |
| subtype | `'gem'` | Hardcoded |
| tags | `[]` | Always empty array |
#### Search Result Mapping
| SearchResult Property | RubyGems API Mapping |
| --------------------- | -------------------- |
| id | `.name` |
| name | `.name` |
| description | `.info` |
| author | `.authors` |
| version | `.version` |
| --- | --- |
### GitHub
#### API URLs
- **Search**: `https://api.github.com/search/repositories?q={{query}}&sort=stars&per_page=10`
- **Details**: `https://api.github.com/repos/{{owner}}/{{repo}}`
#### Crosswalk
| YAMLFrontmatter Property | GitHub API Mapping | Notes |
| ------------------------ | -------------------------- | -------------------------------------------------- |
| type | `'software'` | Hardcoded |
| id | `.name` | Repository name (not full_name) |
| title | `.name` | Repository name (not full_name) |
| aliases | `[]` | Always empty array |
| author | `.owner.login` | Formatted as `[[Login]]`, defaults to `[]` |
| description | `.description` | Defaults to `''` |
| source_url | `.homepage` or `.html_url` | Uses homepage if available, falls back to repo URL |
| github_url | `.html_url` | Normalized GitHub URL, defaults to `''` |
| image_url | `.owner.avatar_url` | Defaults to `''` |
| platform | `[]` | Always empty array |
| dependencies | `[]` | Always empty array |
| subtype | `'CLI'` | Hardcoded |
| tags | `.topics` | Defaults to `[]` |
#### Search Result Mapping
| SearchResult Property | GitHub API Mapping |
| --------------------- | ------------------ |
| id | `.full_name` |
| name | `.full_name` |
| description | `.description` |
| author | `.owner.login` |
| version | `''` |
| --- | --- |
### Homebrew
#### API URLs
- **Search**: `https://formulae.brew.sh/api/formula.json` (client-side filtered)
- **Details**: `https://formulae.brew.sh/api/formula/{{formulaName}}.json`
#### Crosswalk
| YAMLFrontmatter Property | Homebrew API Mapping | Notes |
| ------------------------ | -------------------- | --------------------------------------------- |
| type | `'software'` | Hardcoded |
| id | `.name` | Formula name |
| title | `.name` | Formula name |
| aliases | `.aliases` | Defaults to `[]` |
| author | `[]` | Always empty array |
| description | `.desc` | Defaults to `''` |
| source_url | `.homepage` | Defaults to `''` |
| github_url | `''` | Always empty string |
| image_url | `''` | Always empty string |
| platform | `['[[macOS]]']` | Hardcoded |
| dependencies | `.dependencies` | Each formatted as `[[dep]]`, defaults to `[]` |
| subtype | `'CLI'` | Hardcoded |
| tags | `[]` | Always empty array |
#### Search Result Mapping
| SearchResult Property | Homebrew API Mapping |
| --------------------- | -------------------- |
| id | `.name` |
| name | `.name` |
| description | `.desc` |
| author | `''` |
| version | `.versions.stable` |
| --- | --- |
### VS Code Extensions
#### API URLs
- **Search & Details**: `https://marketplace.visualstudio.com/_apis/public/gallery/extensionquery` (POST)
#### Request Body
```json
{
"filters": [{
"criteria": [
{ "filterType": 8, "value": "Microsoft.VisualStudio.Code" },
{ "filterType": 10, "value": "{{query}}" } // Search
// OR
{ "filterType": 7, "value": "{{publisherName}}.{{extensionName}}" } // Details
],
"pageSize": 10
}],
"flags": 914
}
```
#### Crosswalk
| YAMLFrontmatter Property | VS Code API Mapping | Notes |
| ------------------------ | -------------------------------------------------------------------- | --------------------------------------------------------- |
| type | `'software'` | Hardcoded |
| id | `.displayName` or `.extensionName` | Defaults to `''` |
| title | `.displayName` or `.extensionName` | Defaults to `''` |
| aliases | `[extensionId]` | Format: `publisherName.extensionName` |
| author | `.publisher.displayName` | Formatted as `[[Name]]`, defaults to `[]` |
| description | `.shortDescription` | Defaults to `''` |
| source_url | `https://marketplace.visualstudio.com/items?itemName=${extensionId}` | Constructed |
| github_url | `''` | Always empty string |
| image_url | `.publisher.domain` | Constructed as `https://${domain}/icon`, defaults to `''` |
| platform | `['[[VS Code]]']` | Hardcoded |
| dependencies | `[]` | Always empty array |
| subtype | `'extension'` | Hardcoded |
| tags | `.tags` | Defaults to `[]` |
#### Search Result Mapping
| SearchResult Property | VS Code API Mapping |
| --------------------- | --------------------------------------------- |
| id | `${publisher.publisherName}.${extensionName}` |
| name | `.displayName` or `.extensionName` |
| description | `.shortDescription` |
| author | `.publisher.displayName` |
| version | `.versions[0].version` |
| --- | --- |
### Obsidian Plugins
#### API URLs
- **Plugin List**: `https://raw.githubusercontent.com/obsidianmd/obsidian-releases/master/community-plugins.json`
- **Manifest**: `https://raw.githubusercontent.com/${repo}/master/manifest.json`
- **Repository**: `https://api.github.com/repos/${repo}`
#### Crosswalk
| YAMLFrontmatter Property | Obsidian API Mapping | Notes |
| ------------------------ | -------------------------------------------------------------- | -------------------------------------------- |
| type | `'software'` | Hardcoded |
| id | `.name` or `.id` | From plugin list |
| title | `.name` or `.id` | From plugin list |
| aliases | `[pluginId]` if different from name | Conditional |
| author | `.author` | Formatted as `[[Author]]`, defaults to `[]` |
| description | `manifest.description` or `.description` or `repo.description` | Falls back through sources, defaults to `''` |
| source_url | `obsidian://show-plugin?id=${pluginId}` | Obsidian protocol URL |
| github_url | `https://github.com/${repo}` | Normalized, from plugin list |
| image_url | `repo.owner.avatar_url` | From GitHub API, defaults to `''` |
| platform | `['[[Obsidian]]']` | Hardcoded |
| dependencies | `[]` | Always empty array |
| subtype | `'extension'` | Hardcoded |
| tags | `repo.topics` | From GitHub API, defaults to `[]` |
#### Search Result Mapping
| SearchResult Property | Obsidian API Mapping |
| --------------------- | -------------------- |
| id | `.id` |
| name | `.name` |
| description | `.description` |
| author | `.author` |
| version | `''` |
**Note**: Obsidian plugins are distributed via GitHub, so the search uses the community plugins list, and additional details are fetched from both the plugin's manifest and its GitHub repository.
---
### Implementation Details
#### Utility Functions
- **`normalizeGitHubUrl(url: string)`**: Normalizes various GitHub URL formats to a consistent format
- Error handling: All API calls are wrapped in try-catch blocks with console error logging
#### Data Formatting Conventions
- **Author/Registry/Platform**: Formatted as wikilinks: `[[Name]]`
- **Dependencies**: Each dependency is formatted as a wikilink: `[[dependency-name]]`
- **Empty values**: Use empty strings `''` for strings, empty arrays `[]` for arrays
- **Fallback strategy**: Many properties have fallback chains to ensure data is populated when possible
#### API Rate Limits & Considerations
- **GitHub**: Subject to rate limiting (60 requests/hour unauthenticated)
- **NPM**: No authentication required, generous rate limits
- **RubyGems**: No authentication required
- **Homebrew**: Static JSON file, no rate limiting
- **VS Code**: Requires specific headers and POST requests
- **Obsidian**: Uses GitHub raw content and API (subject to GitHub rate limits)