diff --git a/.claude/skills/update-api-console-components/SKILL.md b/.claude/skills/update-api-console-components/SKILL.md new file mode 100644 index 000000000..c3f6ad148 --- /dev/null +++ b/.claude/skills/update-api-console-components/SKILL.md @@ -0,0 +1,527 @@ +--- +name: update-api-console-components +description: Complete release workflow for api-console v6 and anypoint-api-console wrapper +triggers: + - update api console components + - bump api console version + - release api console v6 + - update console components + - release anypoint api console + - update wrapper +--- + +# Update API Console v6 Components & Release Wrapper + +Automates the complete release workflow: +1. Update component dependencies in `api-console` v6 (mulesoft/api-console) +2. Bump version and publish to npm +3. Update `anypoint-api-console` wrapper (mulesoft-emu/anypoint-api-console) with new version + +## Prerequisites + +### For api-console (mulesoft/api-console) + +1. **Components must be already published to npm** (check with `npm view @api-components/ version`) +2. **Working directory must be clean** (no untracked files, ensure `.claude/` in gitignore) +3. **Must be in `mulesoft/api-console` repo**: `~/mulesoft/context/products/api-console/v6/api-console` +4. **CRITICAL**: This is a MuleSoft repo - requires GPG signing with `alexperez@mulesoft.com` +5. Have GUS ticket numbers for components being updated (to reference in commit) + +### For anypoint-api-console (mulesoft-emu/anypoint-api-console) + +1. **api-console must be published to npm** (wait ~5-10 min after merge for CI) +2. **Must be in wrapper repo**: `~/mulesoft/context/products/api-console/wrapper` +3. **CRITICAL**: This is a Salesforce EMU repo - requires GPG signing with `alexperez@salesforce.com` +4. Have GUS work item for wrapper release (e.g., "APIC Release" W-XXXXXXXX) + +### GUS Conventions + +- **Component version comments**: Always comment in GUS tickets: `Fixed in @api-components/component@X.Y.Z` +- **PR titles with work items**: Always use `@W-XXXXXXXX` format (with `@` prefix) +- **Wrapper work item**: Create or reuse "APIC Release" work item (Type: User Story, 1 point) + +## Input Required + +Ask user for: +- List of components to update (e.g., `api-navigation`, `api-summary`, `api-type-document`) +- Expected versions (or "latest") +- GUS ticket numbers (for commit message) + +## Steps + +### 1. Verify location and checkout main branch + +```bash +cd ~/mulesoft/context/products/api-console/v6/api-console +git status # Verify we're in correct repo +git checkout master # Main branch (currently named 'master' in api-console repo) +git pull +``` + +### 2. Create release branch + +Read current version from `package.json`, calculate next patch version. + +```bash +# If current is 6.6.60, next is 6.6.61 +git checkout -b build/ +``` + +**Branch pattern**: `build/X.X.X` where X.X.X is the next patch version. + +### 3. Update components + +For each component in the update list: + +```bash +npm update @api-components/ +``` + +**Common components**: +- `@api-components/api-navigation` +- `@api-components/api-summary` +- `@api-components/api-type-document` +- `@api-components/api-documentation` +- `@api-components/api-request` + +### 4. Verify each update + +For each updated component: + +```bash +npm ls @api-components/ +``` + +**Check for**: +- ✅ Version matches expected (from GUS ticket comments or npm registry) +- ✅ No warnings about overrides or conflicts +- ✅ "deduped" is OK for transitive dependencies + +**If overrides/conflicts detected**: +```bash +rm package-lock.json +rm -rf node_modules +npm install +npm ls @api-components/ # verify again +``` + +### 5. Configure GPG signing (CRITICAL - DO NOT SKIP) + +**BEFORE any commits**, configure Git for MuleSoft repos: + +```bash +# Option 1: If you have the alias (see docs/team/configs/git-gpg-setup.md) +mulesoft-git + +# Option 2: Manual configuration +git config user.email "yourname@mulesoft.com" +git config user.signingkey YOUR_GPG_KEY_ID +``` + +This ensures commits are signed with your @mulesoft.com email. + +**⚠️ Skipping this step will result in rejected commits and broken git history.** + +**Setup guide**: See `docs/team/configs/git-gpg-setup.md` for GPG configuration options. + +### 6. Bump package version + +```bash +npm version patch --no-git-tag-version +``` + +This updates `package.json` to next patch version without creating a git commit. + +**Why `--no-git-tag-version`**: Avoids "Git working directory not clean" errors. We'll commit manually. + +### 7. Commit changes + +Prepare commit message listing all updated components: + +```bash +git add package.json package-lock.json + +git commit -m "chore: bump version to + +Updated components: +- @api-components/component1: oldVer → newVer +- @api-components/component2: oldVer → newVer +- @api-components/component3: oldVer → newVer + +Related: W-XXXXXXX, W-YYYYYYY" +``` + +**Commit message format**: +- Type: `chore:` +- Subject: `bump version to X.X.X` +- Body: List each updated component with version change +- Footer: Reference GUS tickets + +### 8. Verify GPG signature + +```bash +git log --show-signature -1 +``` + +**Must show**: +- `Good signature from "Your Name "` +- Author: `Your Name ` + +**If signature is wrong or missing**: +```bash +# Reconfigure (see docs/team/configs/git-gpg-setup.md) +git config user.email "yourname@mulesoft.com" +git config user.signingkey YOUR_GPG_KEY_ID + +# Amend commit +git commit --amend --no-edit -S +git log --show-signature -1 # verify again +``` + +### 9. Push branch + +```bash +git push -u origin build/ +``` + +### 10. Create Pull Request + +**⚠️ Cannot use `gh pr create`**: EMU account restrictions prevent gh CLI from accessing mulesoft/* repos. + +**Use GitHub web UI instead**: +1. Go to https://github.com/mulesoft/api-console +2. Click "Compare & pull request" banner +3. **Title**: `Release v` +4. **Body**: + ```markdown + ## Updated Components + + - @api-components/api-navigation: 4.3.20 → 4.3.22 + - @api-components/api-summary: 4.6.16 → 4.6.18 + - @api-components/api-type-document: (transitive) → 4.2.41 + + ## Related Tickets + + - W-XXXXXXX: Description + - W-YYYYYYY: Description + + All tickets currently in "Pending Release" status. + ``` +5. Request review +6. Provide PR URL to user + +## Post-Merge: Update anypoint-api-console (Wrapper) + +After api-console PR is merged and new version is published to npm (automatic via CI, ~5-10 min): + +### Prerequisites + +- Verify api-console published: `npm view api-console version` (should show new version) +- Have GUS work item for wrapper release (or create one: "APIC Release") + +### Steps + +#### 1. Navigate to wrapper repo + +**Location**: `~/mulesoft/context/products/api-console/wrapper` (NOT `v6/anypoint-api-console`) + +```bash +cd ~/mulesoft/context/products/api-console/wrapper +git status # Verify we're in correct repo +git checkout master # Main branch (currently named 'master' in wrapper repo) +``` + +#### 2. Configure GPG signing (CRITICAL) + +**IMPORTANT**: This is a `mulesoft-emu/*` repo (Salesforce EMU), NOT `mulesoft/*`. + +```bash +# Option 1: If you have the alias (see docs/team/configs/git-gpg-setup.md) +salesforce-git + +# Option 2: Manual configuration +git config user.email "yourname@salesforce.com" +git config user.signingkey YOUR_GPG_KEY_ID +``` + +This ensures commits are signed with your @salesforce.com email (NOT @mulesoft.com). + +#### 3. Pull latest changes + +```bash +git pull +``` + +**Note**: If pull fails with "Repository not found", verify remote: +```bash +git remote -v # Should show: mulesoft-emu/anypoint-api-console +``` + +#### 4. Create release branch + +**Branch naming**: Use wrapper version number directly (e.g., `6.6.88`), NOT `build/` or `feat/` prefix. + +**Version calculation**: +- Read current wrapper version from root `package.json` or recent branches +- Wrapper versions are independent from api-console versions +- Example: api-console 6.6.61 → wrapper 6.6.88 + +```bash +git checkout -b 6.6.88 # Direct number, no prefix +``` + +#### 5. Update api-console dependency + +Edit `builder/package.json`: + +```bash +# Change from: +"api-console": "6.6.60" + +# To: +"api-console": "6.6.61" +``` + +#### 6. Install dependencies (CRITICAL - Always delete lock) + +**IMPORTANT**: Always delete `package-lock.json` and `node_modules`. This is NOT optional. + +```bash +cd builder +rm package-lock.json +rm -rf node_modules +npm install +``` + +**Why**: Ensures transitive component dependencies update correctly. Skipping this step causes component version mismatches. + +#### 7. Verify component versions + +Check all three gRPC-related components: + +```bash +npm ls @api-components/api-navigation @api-components/api-summary @api-components/api-type-document +``` + +**Expected output**: +``` +api-console-builder@0.0.1 /path/to/wrapper/builder +└─┬ api-console@6.6.61 + ├── @api-components/api-navigation@4.3.22 + ├── @api-components/api-summary@4.6.18 + └── @api-components/api-type-document@4.2.41 (deduped in tree) +``` + +**If versions don't match**: Something went wrong. Re-run step 6. + +#### 8. Commit changes + +Return to repo root and commit: + +```bash +cd .. # Back to repo root +git add builder/package.json builder/package-lock.json +git commit -m "chore: update api-console to 6.6.61 + +Includes gRPC-related component updates: +- @api-components/api-navigation: 4.3.20 → 4.3.22 +- @api-components/api-summary: 4.6.16 → 4.6.18 +- @api-components/api-type-document: → 4.2.41 + +Related: W-XXXXXXX, W-YYYYYYY" +``` + +**Commit message format**: +- Type: `chore:` +- List component updates (NOT wrapper version bump) +- Reference original GUS tickets from api-console release + +#### 9. Verify GPG signature + +```bash +git log --show-signature -1 +``` + +**Must show**: +``` +gpg: Good signature from "Your Name " +Author: Your Name +``` + +**If wrong**: Reconfigure and amend commit (see docs/team/configs/git-gpg-setup.md). + +#### 10. Push branch + +```bash +git push -u origin 6.6.88 +``` + +#### 11. Create Pull Request + +**✅ Can use `gh pr create`**: EMU account DOES work with `mulesoft-emu/*` repos. + +**PR Title Format**: `@W-XXXXXXXX: Release X.X.X` + +**IMPORTANT**: +- Always prefix GUS work item with `@` (e.g., `@W-21411326`) +- Use wrapper version in title (e.g., `6.6.88`), NOT api-console version + +```bash +gh pr create --title "@W-21411326: Release 6.6.88" --body "Updates api-console dependency to v6.6.61 + +## Updated Components + +- @api-components/api-navigation: 4.3.20 → 4.3.22 +- @api-components/api-summary: 4.6.16 → 4.6.18 +- @api-components/api-type-document: → 4.2.41 + +## Related + +- api-console release: https://github.com/mulesoft/api-console/releases/tag/v6.6.61 +- api-console PR: https://github.com/mulesoft/api-console/pull/XXX +- npm: https://www.npmjs.com/package/api-console/v/6.6.61 +- GUS: W-21315017, W-21315032" +``` + +**GUS Work Item**: +- Use existing "APIC Release" work item (e.g., W-21411326) +- OR create new work item: "APIC Release" (Type: User Story, 1 story point) + +#### 12. Announce in Slack (after merge) + +Post in `#api-console-cloud-sync`: + +``` +Hi team, We've released a new API Console version: +api-console@6.6.61 (@mulesoft/api-console-build@6.6.88) + +Release Notes: https://github.com/mulesoft/api-console/releases/tag/v6.6.61 +``` + +**Format**: +- First line: `api-console@X.X.X (@mulesoft/api-console-build@Y.Y.Y)` +- Second line: Link to GitHub release notes (contains full details) + +### Validation Checklist (anypoint-api-console) + +Before pushing: + +- [ ] Correct repo: `~/mulesoft/context/products/api-console/wrapper` +- [ ] GPG configured: @salesforce.com email (see docs/team/configs/git-gpg-setup.md) +- [ ] Branch name: Direct number (e.g., `6.6.88`), no `build/` or `feat/` prefix +- [ ] `builder/package.json` updated to new api-console version +- [ ] Lock file deleted + reinstalled (NOT optional) +- [ ] Component versions verified: `npm ls @api-components/...` +- [ ] All components at expected versions (no old versions) +- [ ] Commit signed with @salesforce.com GPG key +- [ ] PR title: `@W-XXXXXXXX: Release X.X.X` (with `@` prefix) +- [ ] GUS work item exists for wrapper release + +### Key Differences: api-console vs anypoint-api-console + +| Aspect | api-console | anypoint-api-console | +|--------|-------------|----------------------| +| **Repo org** | `mulesoft/*` | `mulesoft-emu/*` | +| **GPG email** | @mulesoft.com | @salesforce.com | +| **GPG setup** | See docs/team/configs/git-gpg-setup.md | See docs/team/configs/git-gpg-setup.md | +| **Branch naming** | `build/6.6.61` | `6.6.88` (no prefix) | +| **Version bump** | Yes (`npm version patch`) | No (only update dependency) | +| **gh pr create** | ❌ Fails (use web UI) | ✅ Works | +| **PR title** | `Release vX.X.X` | `@W-XXXXXXXX: Release X.X.X` | +| **Lock file delete** | Optional (if conflicts) | Mandatory (always) | + +## Validation Checklist + +Before pushing branch, verify: + +- [ ] All target components updated to expected versions (via `npm ls`) +- [ ] No npm overrides or conflicts +- [ ] Version bumped in `package.json` (e.g., 6.6.60 → 6.6.61) +- [ ] Commit signed with `alexperez@mulesoft.com` GPG key (verified with `git log --show-signature -1`) +- [ ] Commit message follows conventional commits format +- [ ] GUS tickets referenced in commit message +- [ ] Working directory clean (no uncommitted changes) + +## Common Issues & Solutions + +### Issue: "Git working directory not clean" + +**Cause**: Untracked files (e.g., `.claude/`) or staged changes. + +**Solution**: +```bash +git status --porcelain # Find untracked files +# Add .claude/ to .gitignore if not present +# OR: Use --no-git-tag-version flag (already in workflow) +``` + +### Issue: Wrong GPG signature + +**Cause**: Git not configured with correct email/GPG key for this repo. + +**Solution**: +```bash +# Reconfigure (see docs/team/configs/git-gpg-setup.md for setup) +git config user.email "yourname@mulesoft.com" # or @salesforce.com for EMU repos +git config user.signingkey YOUR_GPG_KEY_ID + +# Amend commit +git commit --amend --no-edit -S +git log --show-signature -1 +``` + +### Issue: Component not updating to expected version + +**Cause**: Version constraint in `package.json` doesn't allow new version, OR new version not published to npm. + +**Solution**: +```bash +# Check if version exists in npm +npm view @api-components/ version + +# If exists but not updating, check package.json constraint +# Example: "^4.3.20" allows 4.3.22 but not 5.0.0 + +# If constraint is blocking, manually update package.json +# Then run npm install + +# If still not working, delete lock file +rm package-lock.json +npm install +``` + +### Issue: `npm ls` shows overrides + +**Cause**: Multiple versions of same dependency in tree, npm forced resolution. + +**Solution**: +```bash +cd builder # If in anypoint-api-console +rm package-lock.json +rm -rf node_modules +npm install +npm ls @api-components/ +``` + +### Issue: `gh pr create` fails with "Enterprise Managed User" error + +**Cause**: EMU account cannot use GitHub API for `mulesoft/*` repos (only `mulesoft-emu/*` works). + +**Solution**: Use GitHub web UI to create PR. `git push/pull` work fine (use SSH/HTTPS, not API). + +## Notes + +- **Release cycle**: Every 3 weeks on Fridays (see API Designer release calendar) +- **Build number**: Optional, use semantic version instead (X.X.X) +- **Components are separate repos**: Under `advanced-rest-client` GitHub org, NOT `mulesoft` +- **AMF models**: Not affected by component updates (unless AMF version changes) +- **CI/CD**: GitHub Actions automatically publishes to npm after merge to main branch +- **Downstream consumers**: ACM, Exchange, API Designer will pick up new version on their next update cycle + +## Related Documentation + +- Onboarding doc: Quip (ACM team folder) + Google Drive (acm-aeh-team) +- api-console repo: https://github.com/mulesoft/api-console +- anypoint-api-console repo: https://github.com/mulesoft/anypoint-api-console +- Advanced REST Client (components): https://github.com/advanced-rest-client +- Release calendar: [API Designer release calendar link] diff --git a/.cursorignore b/.cursorignore new file mode 100644 index 000000000..25405c0c7 --- /dev/null +++ b/.cursorignore @@ -0,0 +1,47 @@ +# Cursor Ignore - Exclude from AI context for better performance + +# Build outputs +dist/ +coverage/ +demo/vendor.js + +# Dependencies +node_modules/ + +# Generated AMF models (except specific test models) +demo/models/*.json +demo/models/flattened/*.json +!demo/models/jldAsync26.json +!demo/models/avro.json +!demo/models/avro2.json +!demo/models/grpc-test.json +!demo/models/grpc-test-compact.json +!demo/models/product-order-deep-allof.json + +# IDE configs (keep lightweight) +.vscode/* +!.vscode/settings.json +.idea/ + +# OS files +.DS_Store +Thumbs.db +*.stackdump + +# Git internals +.git/ + +# Large log files +*.log +npm-debug.log* + +# Test screenshots (visual regression baselines - too many files) +test/visual/screenshots/ + +# Package lock files (too large, let Cursor use package.json) +package-lock.json + +# Temporary files +*.tmp +*.swp +*~ diff --git a/.cursorrules b/.cursorrules new file mode 100644 index 000000000..d822cc0b4 --- /dev/null +++ b/.cursorrules @@ -0,0 +1,63 @@ +# Cursor Rules for api-console v6 + +## Repository Context +- This is api-console v6, built with LitElement and Web Components +- Open source project (CPAL-1.0 license) +- Part of MuleSoft's API Console ecosystem + +## Git & Commit Rules +- NEVER commit directly to master/main (ALWAYS create feature branch first) +- ALWAYS configure GPG signing before committing (see docs/team/configs/git-gpg-setup.md) + - MuleSoft repos: Use @mulesoft.com email + - Commits must be GPG signed +- Use Conventional Commits format: `(): ` +- Valid types: feat, fix, docs, style, refactor, test, chore, perf, ci, build, revert + +## Branch Naming Conventions +- Component fixes: `fix/W-XXXXXXXX-description` +- Features: `feat/W-XXXXXXXX-description` or `feat/description` +- Releases: `build/X.X.X` (api-console only) +- Chores: `chore/description` + +## Code Style +- Use @web/test-runner for testing (NOT Jest - poor Shadow DOM support) +- Use AmfHelperMixin utilities for AMF queries (NOT direct JSON access) +- Custom events for component communication (NOT direct method calls) +- Shadow DOM with CSS custom properties for theming +- No `any` types in TypeScript +- Prefer Edit tool over Write for existing files + +## Testing +- Write tests immediately after implementing feature (TDD approach) +- Run `npm test` before creating PR (must pass) +- Update visual regression baselines when UI changes intentionally: `npm run test:visual:update` + +## Build & Verification +- DO NOT run build after every small change (saves tokens, avoids loops) +- Order: Implement → Tests → Build → Fix compilation errors +- Only build when: user asks explicitly, before PR, or after major type changes + +## AMF Model Architecture +- API Console does NOT parse API specs directly (requires AMF model) +- Models are JSON-LD format (AMF v4.0+) +- Generate models: `npm run build:models` +- Load via `amf` property or `modelLocation` (URL to JSON) + +## Common Pitfalls +- Don't parse API files directly (use AMF models) +- Don't import CodeMirror/crypto as ES modules (use vendor.js) +- Don't expose Entities in API responses (use DTOs) +- Don't put business logic in Controllers (use Service layer) +- Don't modify AMF model structure (external standard) + +## Quick Commands +- `npm run prepare` - Build vendor.js + generate AMF models (after clone) +- `npm start` - Dev server +- `npm test` - Run all tests +- `npm run build:vendor` - Rebuild non-ES6 dependencies + +## Related Documentation +- CLAUDE.md - Full project context +- docs/team/patterns/ - Architectural decisions +- docs/team/runbooks/ - Operational procedures +- docs/team/onboarding/ - New team member guide diff --git a/.gitignore b/.gitignore index a87a2540f..1831ad979 100644 --- a/.gitignore +++ b/.gitignore @@ -70,4 +70,13 @@ demo/models/flattened/*.json .idea/ .sfdx -.codegenie \ No newline at end of file +.codegenie +# Claude/Cursor working files +# Note: Skills are committed (team workflows), other .claude/ content is not +.claude/analyses/ +.claude/plans/ +.claude/investigations/ +.claude/context/ +.claude/temp/ +.claude/README.md +.cursor/ diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 000000000..a6f7b5986 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,567 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +**api-console v6** is MuleSoft's open-source API documentation tool used to generate interactive API documentation from RAML and OAS (OpenAPI Specification) files. This is the same console used in Anypoint Platform, distributed as both a standalone application and a web component. + +**Repository**: `mulesoft/api-console` +**Tech Stack**: LitElement 2.x, Web Components, AMF (API Modeling Framework), Polymer components +**License**: CPAL-1.0 + +## Essential Commands + +### Development +```bash +npm start # Start dev server at demo/index.html +npm run start:server # Start parsing server with debug +npm run prepare # Build vendor.js + generate AMF models (required after clone) +``` + +### Testing +```bash +npm test # Run all tests (Playwright: chromium + firefox) + visual regression +npm run test:watch # Watch mode (chromium only) +npm run test:visual # Visual regression tests only +npm run test:visual:update # Update visual regression baselines +``` + +### Building +```bash +npm run build # Production build to dist/ +npm run build:vendor # Build vendor.js (CodeMirror + crypto libs) +npm run build:models # Generate AMF models from demo/apis.json +``` + +### Code Quality +```bash +npm run lint # ESLint check +npm run format # ESLint auto-fix +``` + +## Architecture + +### Two Usage Modes + +**1. Standalone Application** (`ApiConsoleApp`) +- Full-featured application with routing, layout, and navigation drawer +- Entry point: `src/ApiConsoleApp.js` +- Includes: app-drawer, app-toolbar, history API routing +- Mobile-responsive: narrow view at <740px, wide layout at >1500px +- Includes OAuth1/OAuth2 authorization + xhr-simple-request components +- Demo: `demo/standalone/index.html` + +**2. Web Component** (`ApiConsole`) +- Lightweight, embeddable component +- Entry point: `src/ApiConsole.js` +- No layout or routing built-in (host app provides this) +- Navigation drawer hidden by default (controlled via `navigationOpened` property) +- Requires host app to include OAuth/request components separately +- Demo: `demo/element/index.html` + +### Component Hierarchy + +``` +ApiConsoleApp (extends ApiConsole) +└── ApiConsole (extends AmfHelperMixin(LitElement)) + ├── api-navigation (left drawer) + ├── api-documentation (main content) + ├── api-request-panel (try it panel) + └── Helper components: + ├── xhr-simple-request + ├── oauth1-authorization + └── oauth2-authorization +``` + +### AMF Model Architecture + +**CRITICAL**: This console does NOT parse API files directly. It requires a pre-generated AMF model. + +**AMF (API Modeling Framework)**: MuleSoft's unified model for RAML, OAS, AsyncAPI, and gRPC. +- Version compatibility: v6.0.0+ requires AMF v4.0.0+ (AMF model v2) +- Models are JSON-LD format +- Generated via `@api-components/api-model-generator` (see `demo/model.js`) + +**Model Generation**: +1. Define APIs in `demo/apis.json` with format: `{ "path/to/api.raml": "RAML 1.0" }` +2. Run `npm run build:models` to parse and generate `demo/models/*.json` +3. Load model via `amf` property or `modelLocation` property (URL to JSON) + +**Model Flow**: +``` +API Spec (RAML/OAS/AsyncAPI/gRPC) + → AMF Parser (amf-client-js) + → AMF Model (JSON-LD) + → api-console `amf` property + → AmfHelperMixin provides querying utilities + → Renders documentation/navigation/request panel +``` + +### Key Mixin: `AmfHelperMixin` + +From `@api-components/amf-helper-mixin`, provides: +- `_computeApi()`: Extract WebAPI shape from AMF model +- `_computeMethodModel()`: Get method details from selected shape +- `_getValue()`: Query AMF properties using namespaces (`ns.aml.vocabularies.*`) +- `_isWebAPI()`: Check if model is a Web API (vs AsyncAPI, etc.) +- `_isGrpcApi()`: Detect gRPC APIs to hide try-it panel + +### Event-Driven Communication + +**Key Events**: +- `api-navigation-selection-changed`: Fired when user navigates (detail: `{selected, type}`) +- `tryit-requested`: Fired when user clicks "Try it" button +- `apiserverchanged`: Server selection changed (detail: `{value, type}`) +- `api-console-ready`: Dispatched on connect for extension detection + +**Event Flow**: +``` +User clicks endpoint in api-navigation + → api-navigation-selection-changed event + → _apiNavigationOcurred() handler + → Updates selectedShape + selectedShapeType + → LitElement reactivity updates api-documentation +``` + +### Page State Management + +**Pages**: `docs` (default) | `request` (try it panel) + +**Selection State**: +- `selectedShape`: AMF @id of current selection (e.g., `file://demo/models/api.raml#/web-api/end-points/%2Ftest`) +- `selectedShapeType`: One of: `summary`, `documentation`, `type`, `security`, `endpoint`, `method` + +**Routing** (ApiConsoleApp only): +- URL format: `#docs/{type}/{selected}` or `#request/{type}/{selected}` +- History API for back/forward navigation +- `_onRoute()`: Handles popstate events +- `_selectionFromHash()`: Parses URL hash on load + +### gRPC and API Type Detection + +The console automatically detects API types and adjusts UI: + +**gRPC Detection**: +- `_isGrpcApi(amf)` checks if the API is gRPC protocol +- When detected: `_noTryItValue = true` (hides try-it button) +- gRPC APIs are read-only (no request execution) + +**Non-WebAPI Detection**: +- AsyncAPI, GraphQL, and other non-REST APIs also hide try-it +- `_isWebAPI(amf)` returns false for these types + +**Implementation** (ApiConsoleApp.js:206-210, ApiConsole.js:466-469): +```javascript +if (!this._isWebAPI(this.amf) || this._isGrpcApi(this.amf)) { + this._noTryItValue = true; // Hide try-it panel +} +``` + +### Non-ES6 Dependencies (vendor.js) + +**Problem**: CodeMirror and crypto libraries use AMD/CommonJS, incompatible with ES modules. + +**Solution**: `npm run build:vendor` bundles these into `demo/vendor.js`: +- CodeMirror (editor for request/response bodies) +- jsonlint (JSON validation) +- cryptojslib (OAuth1, Digest auth) +- jsrsasign (RSA signing) + +**Required in HTML**: +```html + + +``` + +**Files bundled** (see `tasks/prepare.js`): CodeMirror core + modes, jsonlint, crypto libraries for OAuth. + +### Styling and Theming + +**Shadow DOM**: All styles scoped to components via Shadow DOM + +**CSS Variables**: Each component exposes styling API via CSS custom properties +- No comprehensive documentation (use DevTools to discover variables) +- Examples: `demo/themed/anypoint-theme.css`, `demo/themed/dark-theme.css` + +**Anypoint Compatibility Mode**: +- `compatibility` property switches to Anypoint theme +- Affects: form controls, buttons, icon buttons, lists +- Not all components support this (requires manual CSS adjustments) + +**Navigation Width**: Control with `--app-drawer-width` CSS variable + +### Testing Strategy + +**Framework**: `@web/test-runner` with Playwright (NOT Jest) + +**Why not Jest**: Jest has poor Shadow DOM support. Use @web/test-runner for Web Components. + +**Test Structure**: +- Unit tests: `test/*.test.js` +- Visual regression: `test/visual/*.test.js` +- Test helpers: `test/testHelper.js` (AMF loading utilities) +- AMF loader: `test/amf-loader.js` (shared model loading) + +**Running Single Test**: +```bash +npx web-test-runner test/api-console.basic.test.js --node-resolve --watch --playwright --browsers chromium +``` + +**Visual Regression**: +- Uses `@web/test-runner-visual-regression` +- Baselines stored per browser (chromium/firefox) +- Update baselines: `npm run test:visual:update` +- Threshold: 1% difference allowed (web-test-runner.config.mjs:29) + +**Test Server** (test/server.js): +- Mock API server for integration tests +- Handles multipart uploads, OAuth redirects +- Runs on random port during tests + +## Common Patterns + +### Adding a New Property + +1. Define in `static get properties()`: +```javascript +static get properties() { + return { + myProperty: { type: String, reflect: true } // reflect: syncs to attribute + }; +} +``` + +2. Initialize in constructor: +```javascript +constructor() { + super(); + this.myProperty = 'default'; +} +``` + +3. Use in template: +```javascript +render() { + return html`
${this.myProperty}
`; +} +``` + +### Custom Setters for Side Effects + +When property changes need side effects: +```javascript +get myProperty() { + return this._myProperty; +} + +set myProperty(value) { + const old = this._myProperty; + if (old === value) return; + this._myProperty = value; + this._handleMyPropertyChange(value); + this.requestUpdate('myProperty', old); +} +``` + +### Querying AMF Model + +Use `AmfHelperMixin` utilities: +```javascript +const apiTitle = this._getValue(shape, this.ns.aml.vocabularies.core.name); +const method = this._getValue(methodShape, this.ns.aml.vocabularies.apiContract.method); +``` + +### Handling Navigation Events + +```javascript +_apiNavigationOcurred(e) { + const { selected, type, passive } = e.detail; + if (!passive && this.page !== 'docs') { + this.closeTryIt(); + } + this.selectedShape = selected; + this.selectedShapeType = type; +} +``` + +## Repository Structure + +``` +api-console/ +├── src/ +│ ├── ApiConsole.js # Base web component +│ ├── ApiConsoleApp.js # Standalone app (extends ApiConsole) +│ ├── ApiConsoleStyles.js # Styles for ApiConsole +│ ├── ApiConsoleAppStyles.js # Styles for ApiConsoleApp +│ └── attribution-template.js # "Powered by MuleSoft" footer +├── demo/ +│ ├── apis.json # API definitions for model generation +│ ├── models/ # Generated AMF models (gitignored) +│ ├── vendor.js # Bundled non-ES6 dependencies (generated) +│ ├── model.js # Script to generate AMF models +│ ├── standalone/index.html # ApiConsoleApp demo +│ ├── element/index.html # ApiConsole web component demo +│ └── themed/ # Theming examples +├── test/ +│ ├── *.test.js # Unit tests +│ ├── visual/ # Visual regression tests +│ ├── testHelper.js # Test utilities +│ ├── amf-loader.js # AMF model loader for tests +│ └── server.js # Mock API server +├── tasks/ +│ └── prepare.js # Builds vendor.js +├── rollup.config.js # Production build config +├── web-test-runner.config.mjs # Test runner config +└── package.json +``` + +## GPG Signing Requirements + +**CRITICAL**: This is a `mulesoft/*` repository and requires GPG signing with @mulesoft.com email. + +**Before committing**, configure Git: +```bash +# See docs/team/configs/git-gpg-setup.md for detailed setup + +# Quick config (manual) +git config user.email "yourname@mulesoft.com" +git config user.signingkey YOUR_GPG_KEY_ID +``` + +**Verify signature**: +```bash +git log --show-signature -1 +``` + +## Commit Message Format (commitlint) + +**This repository enforces Conventional Commits** via commitlint (`@commitlint/config-conventional`). + +**Configuration**: `commitlint.config.js` + +### Required Format + +``` +(): + +[optional body] + +[optional footer] +``` + +### Valid Types + +- `feat`: New feature +- `fix`: Bug fix +- `docs`: Documentation only +- `style`: Code formatting (no logic change) +- `refactor`: Code refactor +- `test`: Test changes +- `chore`: Maintenance (version bumps, deps) +- `perf`: Performance improvement +- `ci`: CI/CD changes +- `build`: Build system changes +- `revert`: Revert previous commit + +### Examples + +✅ **Good**: +```bash +fix(api-navigation): resolve deep allOf property collection +feat(api-request): add OAuth2 PKCE support +docs: update README with AMF examples +chore: bump version to 6.6.62 +``` + +❌ **Bad** (will fail validation): +```bash +Fixed bug # Missing type, past tense +Update code. # Ends with period +FEAT: Add feature # Uppercase +fix stuff # Too vague +``` + +### Subject Line Rules + +- ✅ Use imperative mood ("add" not "added") +- ✅ Start with lowercase +- ✅ No period at end +- ✅ Keep under 72 characters + +**Test locally**: +```bash +echo "fix(api-console): resolve issue" | npx commitlint +``` + +**More details**: `docs/team/patterns/branch-naming-conventions.md#commit-message-conventions` + +## CI/CD Pipeline + +**GitHub Actions**: `.github/workflows/deployment.yml` + +**Workflow**: +1. Runs on: push to `master`/`main`/`develop`, pull requests +2. Tests on: Ubuntu 22.04 + Windows (Node 18) +3. Installs Playwright browsers +4. Runs: `npm test` (unit + visual regression) +5. Auto-publishes to npm on version bump (if main branch) + +**Required Checks**: Both Linux and Windows tests must pass + +## Deployment and Publishing + +**Versioning**: Follows semantic versioning (major.minor.patch) + +**Release Process**: +1. Update `package.json` version +2. Update `CHANGELOG.md` +3. Commit with message: `chore: bump version to X.Y.Z` +4. Push to main branch (master in api-console repo) → triggers GitHub Action +5. GitHub Action publishes to npm if version changed + +**npm Package**: [`api-console`](https://www.npmjs.com/package/api-console) + +## Release Management + +### Development Cycle (GUS Workflow) + +**Component Fix → Release Process**: +1. PR with changes **must include version bump** in component's `package.json` +2. Once merged → auto-published to npm +3. Add comment to GUS ticket: `Fixed in @advanced-rest-client/authorization@0.1.8` +4. Update ticket status: `Pending Release` +5. After api-console release includes the component → Close ticket + +**Branch Naming**: +- Component fixes: feature branches (e.g., `feat/W-12345678-fix-auth`) +- api-console releases: `build/` + +**Note**: Some components use older branches: +- `advanced-rest-client/authorization` → use `support/0.1` branch (NOT main branch) + +### v6 Release Process + +**Schedule**: Every 3 weeks on Fridays +**Calendar**: [API Designer release calendar](https://salesforce.quip.com/link-to-calendar) + +**Steps**: +1. Checkout `api-console` main branch (master in api-console repo) +2. Create branch: `build/` +3. Check GUS build version for tickets with component+version comments +4. Update components: `npm update ` for each fix + - Find component updates: Search ticket number in `mulesoft/*` or `advanced-rest-client/*` orgs +5. Bump api-console version: `npm version patch` +6. Create PR → wait for approval → merge +7. Auto-published to npm +8. **Update anypoint-api-console wrapper**: + - Checkout `anypoint-api-console` main branch (master in wrapper repo) + - Update `builder/package.json` with new api-console version + - Verify component versions: `npm ls @api-components/api-type-document` + - **If component not updated**: Delete `package-lock.json` + `node_modules/` in `builder/`, run `npm i`, verify again + - Create PR → merge +9. Announce in `#api-console-cloud-sync` +10. Update [API Console releases list](https://salesforce.quip.com/link-to-releases) + +**Adopt in ACM** (downstream): +```bash +npm update api-console +npm run prepare:api-console +``` + +**Useful Tool**: Use `/update-api-console-components` skill for complete release workflow automation + +### Related Teams & Contacts + +API Console is embedded in multiple products. Escalate to these teams when needed: + +| Product | Developer | Manager | Notes | +|---------|-----------|---------|-------| +| **API Designer** | Leandro Bauret | Eduardo Cominguez | QA: Ignacio Americo | +| **Exchange** | Nicolas Escalante | Mariano Campo | - | +| **AMF** | Nicolas Schejtman | Martin Gutierrez | Parser/model issues | +| **Mocking Service** | Roberto Ciccone | Diego Macias | - | +| **APIkit** | - | Chakravarthy Parankusam | - | + +**Internal Slack**: `#api-console-cloud-sync` (release announcements, coordination) + +## Common Issues + +### NPM Registry Authentication + +**Error**: `Not Found - GET https://nexus3.build.msap.io/repository/npm-internal/@salesforce` + +**Solution**: Login to Salesforce Nexus registry: +```bash +npm login --registry=https://nexus3.build.msap.io/repository/npm-all/ --scope=@salesforce +``` + +**When this happens**: Installing dependencies in `acm-aeh-sfdx` or other Salesforce projects that depend on api-console-lwc + +### Component Version Mismatch + +**Problem**: After updating api-console, component is not updated to expected version + +**Solution**: +```bash +# In builder/ directory +rm -rf package-lock.json node_modules/ +npm i +npm ls @api-components/api-type-document # Verify component version +``` + +## Important Constraints + +### DO: +- Use `@web/test-runner` for testing (NOT Jest) +- Pre-generate AMF models with `npm run build:models` before development +- Run `npm run prepare` after cloning (builds vendor.js + models) +- Use `AmfHelperMixin` utilities for AMF querying +- Test in both chromium and firefox (visual differences exist) +- Check for gRPC API type and hide try-it panel accordingly +- Configure GPG signing before committing (see docs/team/configs/git-gpg-setup.md) + +### DON'T: +- Don't attempt to parse API files directly (requires AMF parser) +- Don't use Jest for testing Web Components +- Don't import CodeMirror/crypto libs as ES modules (use vendor.js) +- Don't modify AMF model structure (it's an external standard) +- Don't assume `amf` is always an array (can be single object) +- Don't commit without GPG signature (configure first) + +## Debugging Tips + +### Console not rendering +1. Check if `amf` property is set: `console.log(apiConsole.amf)` +2. Verify AMF model is v2 (AMF 4.0+): Look for `@context` with `http://a.ml/vocabularies/...` +3. Check `selectedShape` and `selectedShapeType` are set +4. Ensure `vendor.js` loaded before api-console (check DevTools console for CodeMirror errors) + +### Navigation not working +1. Check `navigationOpened` property (default false in web component mode) +2. Verify `api-navigation-selection-changed` event is firing +3. Ensure AMF model has WebAPI shape: `this._computeApi(amf)` returns valid object + +### Try-it panel not showing +1. Check `noTryIt` property is false +2. Verify `page` is set to `'request'` +3. Check if API is gRPC or non-WebAPI (try-it auto-hidden for these) +4. Ensure `selectedShapeType === 'method'` + +### Tests failing with timeout +1. Increase timeout in `web-test-runner.config.mjs` (default 800s) +2. Check if vendor.js is loading in test HTML +3. Verify AMF models exist in `demo/models/` (run `npm run build:models`) + +### Visual regression failures +1. Check if baseline images exist for both browsers +2. Update baselines: `npm run test:visual:update` +3. Review threshold setting (currently 1% diff allowed) +4. Compare screenshots in `test/visual/screenshots/` directory + +## Related Documentation + +- Full docs: https://docs.api-console.io +- AMF: https://github.com/aml-org/amf +- API Components: https://github.com/advanced-rest-client +- LitElement: https://lit.dev/docs/v1/ diff --git a/docs/team/README.md b/docs/team/README.md new file mode 100644 index 000000000..c245cf796 --- /dev/null +++ b/docs/team/README.md @@ -0,0 +1,38 @@ +# API Console Team Shared Documentation + +This directory contains **team-shared** documentation and configurations. +These files ARE committed to Git and shared with all team members and community contributors. + +## Structure + +- `patterns/` - Code patterns, architectural decisions (Web Components, LitElement) +- `configs/` - Team configuration files (IDE settings, linters, etc.) +- `runbooks/` - Operational guides (release process, debugging, common issues) + +## Usage + +### For AI Assistants (Claude/Cursor) +When starting work on this repo, read: +``` +Read docs/team/patterns/*.md +Read docs/team/runbooks/*.md +``` + +### For Team Members & Contributors +1. Add new patterns when making architectural decisions +2. Update runbooks when solving common issues +3. Share configs that improve team productivity + +## Difference vs `.claude/` +- `.claude/` = Personal, local, NOT committed (your drafts) +- `docs/team/` = Shared, committed, team knowledge base + +## Context + +**api-console** is an open-source project: +- LitElement/Polymer Web Components +- Distributed as separate npm packages +- Used by MuleSoft, Salesforce, and external developers +- Shadow DOM, custom events, AMF integration + +Document patterns that help new contributors understand how to work with this codebase. diff --git a/docs/team/configs/README.md b/docs/team/configs/README.md new file mode 100644 index 000000000..8f84d8bb8 --- /dev/null +++ b/docs/team/configs/README.md @@ -0,0 +1,98 @@ +# Team Configuration Files + +> Shared configuration files for development tools and team workflows + +--- + +## Purpose + +This folder contains team-wide configuration files that are: +- ✅ **Committed to Git** (shared with all team members) +- ✅ **IDE/tool agnostic** (or include examples for multiple tools) +- ✅ **Stable and tested** (not experimental) + +**Not for**: +- ❌ Personal preferences (use your own local configs) +- ❌ Sensitive data (credentials, tokens, etc.) +- ❌ Auto-generated files (build artifacts, etc.) + +--- + +## Structure + +``` +configs/ +├── README.md # This file +├── .editorconfig # Cross-IDE formatting (indent, EOL, etc.) +├── .eslintrc.example # Example ESLint config for new team members +└── prettier.example.json # Example Prettier config (if team uses it) +``` + +--- + +## How to Use + +### For New Team Members + +1. Review existing config files in this folder +2. Copy example files to your local workspace (if needed) +3. Customize for your personal workflow +4. **Do NOT commit personal customizations back here** + +### For Team Leads + +When adding a new config: +1. Verify it works across different environments (macOS, Linux, Windows) +2. Document what the config does and why it's needed +3. Get team consensus before committing (PR review) +4. Update this README if adding a new file type + +--- + +## Examples + +### ESLint Config + +If the team agrees on ESLint rules, add `.eslintrc.example`: +```json +{ + "extends": ["eslint:recommended"], + "rules": { + "no-console": "warn", + "semi": ["error", "always"] + } +} +``` + +Team members copy to `.eslintrc.json` (which is in `.gitignore`). + +### EditorConfig + +Cross-IDE formatting rules (works in VS Code, IntelliJ, etc.): +```ini +# .editorconfig +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +trim_trailing_whitespace = true +insert_final_newline = true +``` + +This file is committed as `.editorconfig` (no `.example` needed). + +--- + +## Related + +- **`.claude/`**: Personal AI assistant files (NOT committed, see `.gitignore`) +- **`docs/team/patterns/`**: Code patterns and architectural decisions +- **`docs/team/runbooks/`**: Operational procedures and debugging guides + +--- + +**Last Updated**: 2026-03-03 +**Owner**: ACM Team diff --git a/docs/team/configs/git-gpg-setup.md b/docs/team/configs/git-gpg-setup.md new file mode 100644 index 000000000..d95d4e774 --- /dev/null +++ b/docs/team/configs/git-gpg-setup.md @@ -0,0 +1,338 @@ +# Git & GPG Configuration for MuleSoft/Salesforce Repos + +> **Purpose**: Configure Git to sign commits with correct email and GPG key +> **Applies to**: All team members working on MuleSoft and Salesforce repositories +> **Last Updated**: 2026-03-04 + +--- + +## Why This Matters + +Different repository organizations require different Git configurations: + +| Repo Organization | Example Repos | Required Email | GPG Required | +|-------------------|---------------|----------------|--------------| +| `mulesoft/*` | api-console, api-console-lwc | `yourname@mulesoft.com` | ✅ Yes | +| `mulesoft-emu/*` | anypoint-api-console | `yourname@salesforce.com` | ✅ Yes | +| `advanced-rest-client/*` | api-navigation, api-type-document | `yourname@mulesoft.com` | ✅ Yes | +| `anypoint-web-components/*` | anypoint-button, anypoint-input | `yourname@mulesoft.com` | ✅ Yes | + +**Consequences of wrong configuration**: +- ❌ Commits rejected by GitHub (wrong email) +- ❌ GPG verification fails +- ❌ Git history shows incorrect author +- ❌ Can't push to protected branches + +--- + +## Option 1: Manual Configuration (Per Repo) + +### For MuleSoft Repos (`mulesoft/*`, `advanced-rest-client/*`, `anypoint-web-components/*`) + +```bash +cd /path/to/mulesoft/repo + +# Set email +git config user.email "yourname@mulesoft.com" + +# Set GPG signing key (replace with YOUR key ID) +git config user.signingkey YOUR_GPG_KEY_ID + +# Enable signing +git config commit.gpgsign true +``` + +**Find your GPG key ID**: +```bash +gpg --list-secret-keys --keyid-format=long +# Look for something like: sec rsa4096/ABCD1234EFGH5678 +# The key ID is: ABCD1234EFGH5678 +``` + +--- + +### For Salesforce EMU Repos (`mulesoft-emu/*`) + +```bash +cd /path/to/mulesoft-emu/repo + +# Set email +git config user.email "yourname@salesforce.com" + +# Set GPG signing key (may be same or different from MuleSoft key) +git config user.signingkey YOUR_GPG_KEY_ID + +# Enable signing +git config commit.gpgsign true +``` + +--- + +## Option 2: Shell Aliases (Recommended for Frequent Switching) + +If you frequently switch between MuleSoft and Salesforce repos, create aliases: + +### Setup + +Add to your `~/.zshrc` or `~/.bashrc`: + +```bash +# MuleSoft repos configuration +alias mulesoft-git='git config user.email "yourname@mulesoft.com" && git config user.signingkey YOUR_MULESOFT_GPG_KEY && echo "✅ Configured for MuleSoft repos"' + +# Salesforce EMU repos configuration +alias salesforce-git='git config user.email "yourname@salesforce.com" && git config user.signingkey YOUR_SALESFORCE_GPG_KEY && echo "✅ Configured for Salesforce EMU repos"' +``` + +**Replace**: +- `yourname@mulesoft.com` → Your MuleSoft email +- `yourname@salesforce.com` → Your Salesforce email +- `YOUR_MULESOFT_GPG_KEY` → Your GPG key ID (from `gpg --list-keys`) +- `YOUR_SALESFORCE_GPG_KEY` → Same or different GPG key + +**Reload shell**: +```bash +source ~/.zshrc # or source ~/.bashrc +``` + +### Usage + +Before committing in any repo: + +```bash +# In mulesoft/* repos +cd ~/mulesoft/context/products/api-console/v6/api-console +mulesoft-git +git commit -m "fix: something" + +# In mulesoft-emu/* repos +cd ~/mulesoft/context/products/api-console/wrapper +salesforce-git +git commit -m "chore: update dependency" +``` + +--- + +## Option 3: Directory-Based Configuration (Advanced) + +Use `.gitconfig` includes to automatically apply config based on directory: + +### Setup + +Edit `~/.gitconfig`: + +```ini +[includeIf "gitdir:~/mulesoft/"] + path = ~/.gitconfig-mulesoft + +[includeIf "gitdir:~/salesforce/"] + path = ~/.gitconfig-salesforce +``` + +Create `~/.gitconfig-mulesoft`: + +```ini +[user] + email = yourname@mulesoft.com + signingkey = YOUR_MULESOFT_GPG_KEY + +[commit] + gpgsign = true +``` + +Create `~/.gitconfig-salesforce`: + +```ini +[user] + email = yourname@salesforce.com + signingkey = YOUR_SALESFORCE_GPG_KEY + +[commit] + gpgsign = true +``` + +**Benefit**: No manual switching! Git automatically uses correct config based on repo location. + +--- + +## Verification + +### Check Current Configuration + +```bash +# Show current email +git config user.email + +# Show current signing key +git config user.signingkey + +# Show if signing is enabled +git config commit.gpgsign +``` + +### Verify Last Commit Signature + +```bash +git log --show-signature -1 +``` + +**Expected output**: +``` +gpg: Signature made [date] +gpg: Good signature from "Your Name " [ultimate] +commit abc123def456... +Author: Your Name +``` + +**If signature is wrong**: +```bash +# Fix config +mulesoft-git # or salesforce-git + +# Amend last commit with new signature +git commit --amend --no-edit -S + +# Verify again +git log --show-signature -1 +``` + +--- + +## GPG Setup (First Time Only) + +If you don't have a GPG key yet: + +### 1. Generate GPG Key + +```bash +gpg --full-generate-key +``` + +**Prompts**: +- Key type: RSA (default) +- Key size: 4096 +- Expiration: 0 (no expiration, or set to 2 years) +- Real name: Your Name +- Email: `yourname@mulesoft.com` (or `yourname@salesforce.com`) + +### 2. List Keys + +```bash +gpg --list-secret-keys --keyid-format=long +``` + +**Output**: +``` +sec rsa4096/ABCD1234EFGH5678 2024-01-01 [SC] +uid [ultimate] Your Name +``` + +**Your key ID**: `ABCD1234EFGH5678` + +### 3. Export Public Key + +```bash +gpg --armor --export ABCD1234EFGH5678 +``` + +Copy the output (including `-----BEGIN PGP PUBLIC KEY BLOCK-----` and `-----END PGP PUBLIC KEY BLOCK-----`) + +### 4. Add to GitHub + +1. Go to GitHub → Settings → SSH and GPG keys +2. Click "New GPG key" +3. Paste your public key +4. Save + +### 5. Configure Git + +```bash +git config --global user.signingkey ABCD1234EFGH5678 +git config --global commit.gpgsign true +``` + +--- + +## Common Issues + +### Issue: "failed to sign the data" + +**Cause**: GPG agent not running or key not found. + +**Solution**: +```bash +# Test GPG signing +echo "test" | gpg --clearsign + +# If fails, restart GPG agent +gpgconf --kill gpg-agent +gpgconf --launch gpg-agent + +# Try commit again +``` + +--- + +### Issue: Commit shows wrong author email + +**Cause**: Global Git config overrides repo config. + +**Solution**: +```bash +# Check what's configured +git config --list --show-origin | grep user.email + +# If global is wrong, fix with alias +mulesoft-git # or salesforce-git + +# OR set per-repo +git config user.email "yourname@mulesoft.com" +``` + +--- + +### Issue: "no secret key" error + +**Cause**: Git is configured with a key ID that doesn't exist in your GPG keyring. + +**Solution**: +```bash +# List your available keys +gpg --list-secret-keys --keyid-format=long + +# Configure with correct key ID +git config user.signingkey CORRECT_KEY_ID +``` + +--- + +## Quick Reference + +| Action | Command | +|--------|---------| +| Check current email | `git config user.email` | +| Check signing key | `git config user.signingkey` | +| List GPG keys | `gpg --list-secret-keys --keyid-format=long` | +| Verify last commit | `git log --show-signature -1` | +| Amend commit signature | `git commit --amend --no-edit -S` | +| Configure for MuleSoft | `mulesoft-git` (if alias exists) | +| Configure for Salesforce | `salesforce-git` (if alias exists) | + +--- + +## Team Members: Share Your Config + +If you've set up aliases or directory-based config, consider sharing your approach in #api-console-cloud-sync or #acm-team to help others! + +--- + +## Related Documentation + +- **GitHub GPG Setup**: https://docs.github.com/en/authentication/managing-commit-signature-verification +- **GPG Cheat Sheet**: https://github.com/NicoHood/gpg-key +- **.gitconfig Examples**: See `docs/team/configs/gitconfig-examples/` + +--- + +**Last Updated**: 2026-03-04 +**Maintainer**: ACM Team diff --git a/docs/team/onboarding/api-console-v6.md b/docs/team/onboarding/api-console-v6.md new file mode 100644 index 000000000..c9a7c0dd0 --- /dev/null +++ b/docs/team/onboarding/api-console-v6.md @@ -0,0 +1,334 @@ +# API Console v6 - Onboarding + +> **Last Updated**: 2026-03-02 +> **Maintainer**: ACM Team (API Community Manager) +> **Version**: 6.6.x + +--- + +## What is API Console? + +API Console is an interactive documentation tool that automatically generates API documentation from RAML, OAS (OpenAPI), AsyncAPI, and gRPC specifications. It's similar to Postman but embedded directly in web applications. + +**Key Features**: +- **API Navigation**: Tree view of endpoints, methods, types +- **API Documentation**: Detailed docs for each endpoint/method +- **API Request Panel**: "Try it" functionality to test endpoints +- **Multi-spec support**: RAML, OAS 2/3, AsyncAPI, gRPC (read-only) + +**Used by**: +- Anypoint Platform (Exchange, API Designer) +- API Community Manager (ACM) +- APIKit +- Multiple MuleSoft + Salesforce products + +--- + +## Architecture Overview + +### Two Versions + +| Version | Tech Stack | Purpose | Repo | +|---------|-----------|---------|------| +| **v6** | LitElement, Web Components | Open source, used in most products | `mulesoft/api-console` | +| **v7** | Lightning Web Components (LWC) | Salesforce Experience Cloud only | `mulesoft/api-console-lwc` | + +This document focuses on **v6**. + +### Two Usage Modes + +**1. Standalone Application** (`ApiConsoleApp`) +- Full app with routing, layout, navigation drawer +- Entry point: `src/ApiConsoleApp.js` +- Demo: `demo/standalone/index.html` + +**2. Web Component** (`ApiConsole`) +- Embeddable component (no routing/layout) +- Entry point: `src/ApiConsole.js` +- Host app provides layout and navigation +- Demo: `demo/element/index.html` + +### Component Hierarchy + +``` +ApiConsoleApp (extends ApiConsole) +└── ApiConsole (extends AmfHelperMixin(LitElement)) + ├── api-navigation (left drawer) + ├── api-documentation (main content) + ├── api-request-panel (try it panel) + └── Helper components: + ├── xhr-simple-request + ├── oauth1-authorization + └── oauth2-authorization +``` + +--- + +## AMF Model Architecture + +**CRITICAL**: API Console does NOT parse API specs directly. It requires a pre-generated **AMF model**. + +### What is AMF? + +**AMF (AML Modeling Framework)**: MuleSoft's unified model for RAML, OAS, AsyncAPI, and gRPC. +- **Format**: JSON-LD +- **Version**: v6.0.0+ requires AMF v4.0.0+ (AMF model v2) +- **Generator**: `@api-components/api-model-generator` + +### AMF Concepts + +**Declares**: Types, components, schemas +**Endpoints**: API paths +**Operations**: HTTP methods (GET, POST, PUT, DELETE, etc.) + +### Model Flow + +``` +API Spec (RAML/OAS/AsyncAPI/gRPC) + → AMF Parser (amf-client-js) + → AMF Model (JSON-LD) + → api-console `amf` property + → AmfHelperMixin provides querying utilities + → Renders documentation/navigation/request panel +``` + +**More info**: https://a.ml/docs/ + +--- + +## Repository Structure + +### Main Repos + +**1. `mulesoft/api-console`** (this repo) +- Main integrator component +- Version: 6.6.x +- Depends on: Individual components from `advanced-rest-client` org +- Release cycle: Every 3 weeks on Fridays + +**2. `mulesoft/anypoint-api-console`** +- Builder for Anypoint Platform-specific bundle +- Wraps `api-console` with custom configurations +- Location: `builder/package.json` references `api-console` version + +**3. `advanced-rest-client/*` (GitHub org)** +- Individual Web Components used by api-console +- Examples: + - `api-navigation` + - `api-summary` + - `api-type-document` + - `api-documentation` + - `api-request` +- Each is a separate npm package (`@api-components/`) + +### Monorepo Structure (api-console) + +``` +api-console/ +├── src/ +│ ├── ApiConsole.js # Base web component +│ ├── ApiConsoleApp.js # Standalone app +│ └── styles/ # Component styles +├── demo/ +│ ├── apis.json # API definitions for demos +│ ├── models/ # Generated AMF models (gitignored) +│ ├── vendor.js # Non-ES6 dependencies (generated) +│ └── model.js # Script to generate AMF models +├── test/ +│ ├── *.test.js # Unit tests +│ └── visual/ # Visual regression tests +├── docs/team/ # Team documentation +│ ├── onboarding/ # Onboarding docs (this file) +│ ├── runbooks/ # Operational procedures +│ └── patterns/ # Architectural decisions +└── .claude/ # Claude Code working files (gitignored) + ├── skills/ # Automation skills + └── investigations/ # Bug analysis files +``` + +--- + +## Tech Stack + +### Core Technologies + +- **LitElement 2.x**: Base class for Web Components +- **Web Components**: Custom elements with Shadow DOM +- **AMF**: API modeling framework +- **Polymer**: Legacy components (being phased out) +- **CodeMirror**: Code editor (bundled in vendor.js) + +### Testing + +- **@web/test-runner**: Test framework (NOT Jest - Jest has poor Shadow DOM support) +- **Playwright**: Browser automation (chromium + firefox) +- **Visual regression**: `@web/test-runner-visual-regression` + +### Build & Dev + +- **Rollup**: Production bundler +- **web-dev-server**: Development server +- **npm workspaces**: Monorepo (v6 only, not for individual components) + +--- + +## API Specification Support + +| Spec | Version | Support Level | Try It Panel | +|------|---------|---------------|--------------| +| **RAML** | 0.8, 1.0 | ✅ Full | ✅ Yes | +| **OAS** | 2.0, 3.0 | ✅ Full | ✅ Yes | +| **AsyncAPI** | 2.x | ✅ Read-only | ❌ No (not REST) | +| **gRPC** | Proto3 | ✅ Read-only | ❌ No (RPC protocol) | + +**Note**: gRPC and AsyncAPI are auto-detected and hide the "Try it" panel. + +--- + +## Related Teams & Contacts + +| Team | Point of Contact | Responsibility | +|------|------------------|----------------| +| **API Designer** | Leandro Bauret (Dev)
Eduardo Cominguez (Manager) | Consumes api-console in Designer | +| **Exchange** | Nicolas Escalante (Dev)
Mariano Campo (Manager) | API documentation display | +| **AMF** | Nicolas Schejtman (Dev)
Martin Gutierrez (Manager) | AMF parser and model | +| **APIkit** | Chakravarthy Parankusam (Manager) | Runtime API implementation | +| **Mocking Service** | Roberto Ciccone (Dev)
Diego Macias (Manager) | API mocking | +| **ACM Team** | #acm-team (Slack) | Maintains v6 and v7 | + +--- + +## Essential Commands + +### First-time Setup + +```bash +git clone git@github.com:mulesoft/api-console.git +cd api-console +npm install +npm run prepare # Build vendor.js + generate AMF models +``` + +**⚠️ Important**: Always run `npm run prepare` after cloning. It builds non-ES6 dependencies (vendor.js) and generates demo models. + +### Development + +```bash +npm start # Dev server at demo/index.html +npm run start:server # Parsing server with debug +npm run build:models # Generate AMF models from demo/apis.json +``` + +### Testing + +```bash +npm test # All tests (unit + visual regression) +npm run test:watch # Watch mode (chromium only) +npm run test:visual # Visual regression only +npm run test:visual:update # Update visual baselines +``` + +### Building + +```bash +npm run build # Production build to dist/ +npm run build:vendor # Build vendor.js (CodeMirror + crypto) +``` + +--- + +## Learning Resources + +### Documentation + +- **Full docs**: https://docs.api-console.io +- **AMF**: https://a.ml/docs/ +- **AMF GitHub**: https://github.com/aml-org/amf +- **API Components**: https://github.com/advanced-rest-client +- **LitElement**: https://lit.dev/docs/v1/ + +### Specifications + +- **RAML**: https://raml.org/ +- **OAS**: https://swagger.io/specification/ +- **AsyncAPI**: https://www.asyncapi.com/docs/reference/specification + +### Internal Resources + +- **Onboarding meetings**: + - Part 1: APIC basics + - Part 2: Troubleshooting example +- **Figma designs**: Authorization migration +- **Slack**: #api-console-cloud-sync (releases), #api-line (general) + +--- + +## Development Workflow + +### Typical Development Flow + +1. **Clone repo** + run `npm run prepare` +2. **Create feature branch** (NEVER commit to master directly) +3. **Make changes** to components +4. **Test locally**: `npm start` + manual testing +5. **Run tests**: `npm test` (must pass) +6. **Create PR** via GitHub web UI (gh CLI doesn't work with EMU) +7. **Wait for review** + CI checks (Linux + Windows) +8. **Merge** → Auto-publishes to npm (if version bumped) + +### Git & GPG Requirements + +**⚠️ CRITICAL**: This is a `mulesoft/*` repository. Before committing: + +```bash +mulesoft-git # Configure GPG signing with alexperez@mulesoft.com +``` + +**Verify signature**: +```bash +git log --show-signature -1 +``` + +**Must show**: `Good signature from "alexp mule "` + +--- + +## Common Pitfalls + +### DON'T: +- ❌ Commit directly to master/main (always create branch) +- ❌ Forget to run `mulesoft-git` before committing +- ❌ Use Jest for testing (use @web/test-runner) +- ❌ Parse API files directly (use AMF model) +- ❌ Modify AMF model structure (it's an external standard) +- ❌ Import CodeMirror/crypto as ES modules (use vendor.js) +- ❌ Use `gh pr create` (EMU account doesn't work with mulesoft/* repos) + +### DO: +- ✅ Run `npm run prepare` after cloning +- ✅ Run `mulesoft-git` before committing +- ✅ Test in both chromium and firefox (visual differences exist) +- ✅ Use `AmfHelperMixin` utilities for AMF querying +- ✅ Create PR via GitHub web UI +- ✅ Update visual regression baselines when UI changes intentionally + +--- + +## Next Steps + +After reading this onboarding: + +1. **Read**: `docs/team/runbooks/api-console-v6-release.md` - Learn release process +2. **Read**: `docs/team/runbooks/api-console-v6-troubleshooting.md` - Common issues +3. **Read**: `docs/team/patterns/api-console-architecture.md` - Technical decisions +4. **Clone repo** + run through essential commands +5. **Join Slack**: #api-console-cloud-sync, #api-line +6. **Ask questions**: Tag @alexperez or team in Slack + +--- + +## Questions? + +- **Slack**: #api-line (general), #acm-team (internal) +- **GitHub Issues**: https://github.com/mulesoft/api-console/issues +- **Email**: arc@mulesoft.com diff --git a/docs/team/patterns/00-web-component-communication.md b/docs/team/patterns/00-web-component-communication.md new file mode 100644 index 000000000..13bf03280 --- /dev/null +++ b/docs/team/patterns/00-web-component-communication.md @@ -0,0 +1,191 @@ +# Pattern: Web Component Communication + +**Date**: 2026-02-26 +**Author**: ACM Team +**Status**: Accepted +**Applies to**: All Web Components in api-console + +--- + +## Problem + +Web Components in api-console need to communicate with each other: +- Parent → Child: Pass data down +- Child → Parent: Notify of events +- Sibling → Sibling: Share state + +Without clear patterns, components become tightly coupled and hard to test. + +--- + +## Solution + +Use **Properties + Custom Events** pattern: + +``` +┌─────────────────────────────────────┐ +│ Parent Component │ +│ - Sets properties on children │ +│ - Listens to custom events │ +└──────────────┬──────────────────────┘ + │ + │ properties (down) + ▼ +┌─────────────────────────────────────┐ +│ Child Component │ +│ - Receives data via @property │ +│ - Emits custom events (up) │ +└─────────────────────────────────────┘ +``` + +--- + +## Implementation + +### Parent → Child (Properties) + +**Parent sets property**: +```javascript +// parent-component.js +import { LitElement, html } from 'lit-element'; + +class ParentComponent extends LitElement { + render() { + return html` + + + `; + } +} +``` + +**Child receives property**: +```javascript +// api-navigation.js +import { LitElement, html } from 'lit-element'; + +class ApiNavigation extends LitElement { + static get properties() { + return { + amf: { type: Object }, + selected: { type: String } + }; + } + + updated(changedProps) { + if (changedProps.has('amf')) { + this._processAmf(this.amf); + } + } +} +``` + +### Child → Parent (Custom Events) + +**Child dispatches event**: +```javascript +// api-navigation.js +_handleSelection(endpointId) { + this.dispatchEvent(new CustomEvent('api-navigation-selection-changed', { + bubbles: true, + composed: true, + detail: { selected: endpointId } + })); +} +``` + +**Parent listens to event**: +```javascript +// parent-component.js +render() { + return html` + + + `; +} + +_onSelectionChanged(e) { + this.selectedId = e.detail.selected; +} +``` + +### Sibling → Sibling (Shared State) + +**Option 1: State in parent** (preferred for simple cases): +```javascript +// parent manages state, passes to both children +class ParentComponent extends LitElement { + render() { + return html` + + + + + + `; + } +} +``` + +**Option 2: Event bus** (for complex cases): +```javascript +// Avoid unless absolutely necessary - harder to debug +``` + +--- + +## Rules + +### ✅ DO +- Use `.property` syntax for Object/Array properties (not attributes) +- Use `bubbles: true, composed: true` for events that cross shadow DOM +- Prefix event names with component name (`api-navigation-*`) +- Document event details in JSDoc +- Keep event payloads simple (primitives, plain objects) + +### ❌ DON'T +- Don't access child component methods directly (`this.querySelector('api-nav').selectEndpoint()`) +- Don't use global variables for component communication +- Don't mutate objects passed as properties (create new objects instead) +- Don't listen to events on `window` unless truly global + +--- + +## Example from Codebase + +See `api-console/src/ApiConsole.js` for complete parent-child pattern: +- Properties: `amf`, `selected`, `baseUri` +- Events: `api-navigation-selection-changed`, `api-request-send` + +--- + +## Testing + +```javascript +import { fixture, html } from '@open-wc/testing'; + +it('emits selection event when item clicked', async () => { + const el = await fixture(html``); + + setTimeout(() => el._handleSelection('endpoint-1')); + const event = await oneEvent(el, 'api-navigation-selection-changed'); + + expect(event.detail.selected).to.equal('endpoint-1'); +}); +``` + +--- + +## Related +- [Shadow DOM Styling Pattern](./01-shadow-dom-styling.md) +- [AMF Integration Pattern](./02-amf-integration.md) + +--- + +**Last Updated**: 2026-02-26 diff --git a/docs/team/patterns/api-console-architecture.md b/docs/team/patterns/api-console-architecture.md new file mode 100644 index 000000000..0d8f4ba38 --- /dev/null +++ b/docs/team/patterns/api-console-architecture.md @@ -0,0 +1,448 @@ +# API Console v6 - Architecture Patterns + +> **Last Updated**: 2026-03-02 +> **Purpose**: Document key architectural decisions and technical patterns + +--- + +## Architectural Decisions + +### ADR-001: Why AMF Instead of Direct Parsing? + +**Decision**: API Console consumes pre-generated AMF models instead of parsing API specs directly. + +**Context**: +- API specs can be complex (RAML, OAS 2/3, AsyncAPI, gRPC) +- Parsing logic is non-trivial (includes, fragments, inheritance) +- Parsing performance can be slow for large APIs + +**Decision**: +- Use AMF (API Modeling Framework) as unified model +- Require pre-generated JSON-LD models +- Console only renders, doesn't parse + +**Consequences**: + +**Pros**: +- ✅ Single model format for all spec types +- ✅ Faster console load (no parse time) +- ✅ Parsing logic maintained by AMF team +- ✅ Consistent rendering across spec types + +**Cons**: +- ❌ Extra step required (generate AMF model first) +- ❌ Tight coupling to AMF version +- ❌ Cannot handle spec updates without regenerating model + +**Status**: ✅ Active + +--- + +### ADR-002: Monorepo vs Separate Component Repos + +**Decision**: Console integrator (`api-console`) and individual components (`@api-components/*`) are in separate repos. + +**Context**: +- Console uses 18+ components (navigation, docs, request, etc.) +- Components reused across multiple products (Exchange, Designer, ACM) +- Different release cycles for console vs components + +**Decision**: +- Console repo (`mulesoft/api-console`): Integrator only +- Component repos (`advanced-rest-client/*`): Individual Web Components +- Each component is separate npm package + +**Consequences**: + +**Pros**: +- ✅ Components reusable across products +- ✅ Independent versioning and releases +- ✅ Smaller bundle sizes (consumers pick what they need) +- ✅ Easier testing (components isolated) + +**Cons**: +- ❌ Complex dependency management +- ❌ Version conflicts possible +- ❌ Release coordination required +- ❌ More repos to maintain + +**Status**: ✅ Active + +--- + +### ADR-003: LitElement (v6) vs LWC (v7) + +**Decision**: Maintain two parallel versions: v6 (LitElement) and v7 (LWC). + +**Context**: +- v6 used by open-source products and Anypoint Platform +- Salesforce products require LWC (no Shadow DOM piercing allowed) +- ACM embedded in Salesforce Experience Cloud + +**Decision**: +- **v6**: LitElement + Web Components (open source) +- **v7**: Lightning Web Components (Salesforce-specific) +- Manual porting of features between versions + +**Consequences**: + +**Pros**: +- ✅ v6: Full Shadow DOM support, flexible styling +- ✅ v7: Salesforce platform integration (LMS, wire adapters, SLDS) +- ✅ Each optimized for its platform + +**Cons**: +- ❌ Double maintenance burden +- ❌ Feature parity difficult to maintain +- ❌ Manual porting (no automation) +- ❌ Different constraints (v7 has governor limits) + +**Status**: ✅ Active + +**Feature parity tracking**: See `products/api-console/feature-parity/` folder + +--- + +### ADR-004: Shadow DOM Scoping + +**Decision**: Use Shadow DOM for all Web Components in v6. + +**Context**: +- Web Components can use Shadow DOM (scoped styles) or Light DOM (global styles) +- Shadow DOM prevents style leakage but limits customization + +**Decision**: Use Shadow DOM with CSS custom properties for theming. + +**Consequences**: + +**Pros**: +- ✅ Styles scoped to component (no global conflicts) +- ✅ Encapsulation (internals hidden from host) +- ✅ Consistent rendering across different hosts + +**Cons**: +- ❌ Hard to override styles from outside +- ❌ CSS custom properties required for theming +- ❌ DevTools inspection harder +- ❌ Testing requires Shadow DOM support (@web/test-runner, NOT Jest) + +**Status**: ✅ Active + +--- + +### ADR-005: vendor.js for Non-ES6 Dependencies + +**Decision**: Bundle CodeMirror and crypto libraries into `vendor.js`. + +**Context**: +- CodeMirror uses AMD/CommonJS modules (incompatible with ES6) +- Crypto libraries (for OAuth1, Digest auth) also non-ES6 +- Rollup cannot bundle mixed module systems + +**Decision**: +- Pre-bundle non-ES6 deps into `demo/vendor.js` +- Load via `` +- Generate via `npm run build:vendor` (not committed to git) + +**Consequences**: + +**Pros**: +- ✅ Works around module system incompatibility +- ✅ Single bundle for all non-ES6 code +- ✅ Smaller main bundle (ES6 only) + +**Cons**: +- ❌ Extra build step required after clone +- ❌ Not obvious for new developers (causes "missing vendor.js" errors) +- ❌ Pollutes global scope (CodeMirror, CryptoJS) + +**Status**: ✅ Active (until CodeMirror v6 migration) + +--- + +## Component Patterns + +### Pattern: Event-Driven Communication + +**Context**: Components need to communicate (e.g., navigation → documentation). + +**Pattern**: Use custom events, not direct method calls. + +**Example**: + +```javascript +// api-navigation fires event +this.dispatchEvent(new CustomEvent('api-navigation-selection-changed', { + detail: { selected: 'method-id', type: 'method' }, + bubbles: true, + composed: true // Crosses Shadow DOM boundary +})); + +// api-console listens +this.addEventListener('api-navigation-selection-changed', (e) => { + this.selectedShape = e.detail.selected; + this.selectedShapeType = e.detail.type; +}); +``` + +**Why**: +- ✅ Loose coupling (components don't know about each other) +- ✅ Works across Shadow DOM boundaries (`composed: true`) +- ✅ Easy to test (mock events) + +--- + +### Pattern: AmfHelperMixin for AMF Queries + +**Context**: Querying AMF JSON-LD is complex (namespaced properties, nested structure). + +**Pattern**: Use `AmfHelperMixin` utilities, not direct JSON queries. + +**Example**: + +```javascript +// ❌ Bad: Direct JSON query +const name = model['http://www.w3.org/ns/shacl#name'][0]['@value']; + +// ✅ Good: Use AmfHelperMixin +const name = this._getValue(model, this.ns.aml.vocabularies.core.name); +``` + +**Why**: +- ✅ Abstracts namespace complexity +- ✅ Handles array vs single value +- ✅ Forwards-compatible (AMF model changes isolated) + +--- + +### Pattern: Reactive Properties with Custom Setters + +**Context**: Property changes need side effects (e.g., update UI, fetch data). + +**Pattern**: Define custom setter, call `requestUpdate()`. + +**Example**: + +```javascript +static get properties() { + return { + selectedShape: { type: String } + }; +} + +get selectedShape() { + return this._selectedShape; +} + +set selectedShape(value) { + const old = this._selectedShape; + if (old === value) return; // Avoid redundant updates + this._selectedShape = value; + this._handleShapeChange(value); // Side effect + this.requestUpdate('selectedShape', old); // Trigger re-render +} + +_handleShapeChange(shape) { + // Fetch method details, update documentation, etc. +} +``` + +**Why**: +- ✅ LitElement reactive system aware of change +- ✅ Side effects controlled +- ✅ Avoids redundant renders (check `old === value`) + +--- + +## API Detection Patterns + +### Pattern: gRPC Auto-Detection + +**Context**: gRPC APIs shouldn't show "Try it" panel (RPC protocol, not REST). + +**Pattern**: Detect API type in AMF model, hide try-it accordingly. + +**Implementation**: + +```javascript +// ApiConsoleApp.js:206-210, ApiConsole.js:466-469 +if (!this._isWebAPI(this.amf) || this._isGrpcApi(this.amf)) { + this._noTryItValue = true; // Hide try-it panel +} + +_isWebAPI(amf) { + // Check if AMF model has WebAPI shape +} + +_isGrpcApi(amf) { + // Check if protocol is gRPC +} +``` + +**Why**: +- ✅ Automatic (no manual configuration) +- ✅ Works for gRPC, AsyncAPI, GraphQL +- ✅ Prevents user confusion (can't send gRPC requests from browser) + +--- + +## Release Patterns + +### Pattern: Semantic Versioning + +**Policy**: Follow semver strictly. + +- **Patch** (X.X.Y): Bug fixes, component updates +- **Minor** (X.Y.0): New features, backwards-compatible +- **Major** (X.0.0): Breaking changes, AMF version updates + +**Example**: +- `6.6.60` → `6.6.61`: Component updates (patch) +- `6.6.61` → `6.7.0`: New feature (e.g., AsyncAPI support) +- `6.7.0` → `7.0.0`: LWC rewrite (major) + +--- + +### Pattern: Component Version Comments in GUS + +**Policy**: Always comment component+version in GUS tickets. + +**Format**: `Fixed in @api-components/api-navigation@4.3.22` + +**Why**: +- ✅ Traceability (know which version fixed issue) +- ✅ Release notes (auto-generate from comments) +- ✅ Rollback guidance (if regression, revert to previous version) + +--- + +### Pattern: Branch Naming + +**Policy**: +- **Features**: `feat/` or `feat/W-XXXXXXX` +- **Fixes**: `fix/` or `fix/W-XXXXXXX` +- **Releases**: `build/` (e.g., `build/6.6.61`) +- **Chores**: `chore/` + +**Why**: Consistent, easy to understand, supports automation. + +--- + +## Testing Patterns + +### Pattern: @web/test-runner over Jest + +**Decision**: Use `@web/test-runner` with Playwright, NOT Jest. + +**Why**: +- ✅ @web/test-runner: Built for Web Components, real browser, Shadow DOM support +- ❌ Jest: JSDOM (not real browser), poor Shadow DOM support + +**Example**: + +```javascript +// test/api-console.basic.test.js +import { fixture, expect } from '@open-wc/testing'; +import '../src/ApiConsole.js'; + +describe('ApiConsole', () => { + it('renders navigation when navigationOpened', async () => { + const el = await fixture(''); + const nav = el.shadowRoot.querySelector('api-navigation'); + expect(nav).to.exist; + }); +}); +``` + +--- + +### Pattern: Visual Regression Testing + +**Decision**: Use `@web/test-runner-visual-regression` for UI changes. + +**Why**: Catch unintended visual regressions (CSS changes, layout shifts). + +**Example**: + +```javascript +import { visualDiff } from '@web/test-runner-visual-regression'; + +it('matches screenshot', async () => { + const el = await fixture(''); + await visualDiff(el, 'api-console-default'); + // Compares with baseline in test/visual/screenshots/ +}); +``` + +**Threshold**: 1% pixel difference allowed (accounts for font rendering). + +--- + +## Deployment Patterns + +### Pattern: Automatic npm Publication + +**Decision**: GitHub Actions auto-publishes to npm on version bump. + +**Workflow**: +1. PR merged to master with version bump in `package.json` +2. CI detects version change +3. Runs tests (Linux + Windows) +4. If tests pass → `npm publish` +5. Downstream consumers get new version + +**Why**: +- ✅ No manual `npm publish` (reduces errors) +- ✅ Tests always run before publish +- ✅ Audit trail (git commit linked to npm version) + +--- + +## Future Considerations + +### CodeMirror v6 Migration + +**Status**: Planned (no timeline) + +**Why**: CodeMirror 6 is ES6 native (no vendor.js needed). + +**Blocker**: Breaking API changes, effort required for migration. + +--- + +### AMF v5 Support + +**Status**: Monitoring + +**Impact**: May require major version bump (7.0.0). + +**Plan**: Wait for AMF v5 stable release, then evaluate migration path. + +--- + +### TypeScript Migration + +**Status**: Under consideration + +**Pros**: Better IDE support, catch errors early + +**Cons**: Migration effort, build complexity + +--- + +## Questions or Proposals? + +Want to propose a new pattern or change an existing one? + +1. Create ADR document: `docs/team/patterns/adr-NNN-title.md` +2. Follow ADR template (Context, Decision, Consequences) +3. Discuss in #api-line or team meeting +4. Update this document after approval + +--- + +## See Also + +- [Onboarding](../onboarding/api-console-v6.md) - Architecture overview +- [Release Runbook](../runbooks/api-console-v6-release.md) - Release process +- [Troubleshooting](../runbooks/api-console-v6-troubleshooting.md) - Common issues diff --git a/docs/team/patterns/branch-naming-conventions.md b/docs/team/patterns/branch-naming-conventions.md new file mode 100644 index 000000000..de949140c --- /dev/null +++ b/docs/team/patterns/branch-naming-conventions.md @@ -0,0 +1,465 @@ +# Branch Naming Conventions for API Console v6 + +> **Last Updated**: 2026-03-03 +> **Owner**: ACM Team +> **Purpose**: Standardize branch naming across api-console ecosystem + +--- + +## Overview + +The API Console v6 ecosystem consists of: +1. **Individual components** (e.g., api-example-generator, api-type-document, api-navigation) +2. **api-console** (main package that bundles components) +3. **anypoint-api-console** (wrapper for Salesforce) + +Different branch naming patterns are used depending on the type of change and repository. + +--- + +## Commit Message Conventions (Enforced by commitlint) + +### Overview + +**This repository uses commitlint** with `@commitlint/config-conventional` to enforce standardized commit messages. + +**Configuration**: `commitlint.config.js` + +**What commitlint validates**: +- ✅ Commit message **format** (type, scope, subject) +- ❌ **NOT** branch names (branch names are flexible) + +### Conventional Commits Format + +``` +(): + +[optional body] + +[optional footer] +``` + +**Example**: +``` +fix(api-navigation): resolve deep allOf property collection + +Added recursive traversal for nested allOf chains. + +Related: W-21368901 +``` + +### Valid Commit Types + +| Type | Use When | Example | +|------|----------|---------| +| `feat` | New feature | `feat(api-request): add OAuth2 PKCE support` | +| `fix` | Bug fix | `fix(api-documentation): resolve markdown rendering issue` | +| `docs` | Documentation only | `docs: update README with new examples` | +| `style` | Code formatting (no logic change) | `style: fix indentation in ApiConsole.js` | +| `refactor` | Code refactor (no bug fix or feature) | `refactor: extract AMF helper into separate file` | +| `test` | Test changes | `test: add regression test for deep allOf` | +| `chore` | Maintenance tasks | `chore: bump version to 6.6.62` | +| `perf` | Performance improvement | `perf: optimize AMF model traversal` | +| `ci` | CI/CD changes | `ci: update GitHub Actions workflow` | +| `build` | Build system changes | `build: update rollup config` | +| `revert` | Revert previous commit | `revert: revert "feat: add feature X"` | + +### Scope (Optional but Recommended) + +Scope indicates what part of the codebase is affected: + +**Examples**: +- `fix(api-navigation):` - Navigation component +- `feat(api-request):` - Request panel +- `docs(README):` - README file +- `chore(deps):` - Dependencies + +**When to omit scope**: +- Changes affect entire codebase +- Documentation updates at root level +- Version bumps + +### Subject Line Rules + +✅ **DO**: +- Use imperative mood ("add" not "added" or "adds") +- Start with lowercase +- No period at the end +- Keep under 72 characters + +❌ **DON'T**: +- Start with uppercase +- End with period +- Use past tense +- Be vague ("fix stuff", "update things") + +### Examples: Good vs Bad + +#### ✅ Good Commits + +```bash +fix(api-navigation): resolve deep allOf property collection +feat(api-request): add OAuth2 PKCE support +docs: add branch naming conventions pattern +chore: bump version to 6.6.62 +test: add regression test for deep allOf schemas +refactor(api-console): extract AMF helper utilities +``` + +#### ❌ Bad Commits (will fail commitlint) + +```bash +Fixed bug # Missing type/scope, past tense +Update code. # Vague, ends with period +FEAT: Add feature # Uppercase type, uppercase subject +fix stuff # Too vague +Added new feature to navigation # Past tense +``` + +### Body and Footer (Optional) + +**Body**: Detailed explanation of WHAT changed and WHY (not HOW - code shows that) + +**Footer**: Reference tickets, breaking changes, etc. + +**Example**: +``` +fix(api-example-generator): add recursive property collection for deep allOf + +Single-pass iteration through allOf shapes didn't recursively expand +nested shacl:and arrays beyond 3 levels. This caused properties in +4+ level allOf chains to be missing from generated examples. + +Added _collectPropertiesRecursive() method with: +- Depth limiting (max 10 levels) +- Circular reference detection +- Backward compatibility + +Related: W-21368901 +Closes: #123 +``` + +### Validation + +**commitlint runs automatically**: +- On `git commit` (via husky pre-commit hook, if configured) +- In CI/CD pipeline + +**Test commit message locally**: +```bash +echo "fix(api-console): resolve issue" | npx commitlint +``` + +**If validation fails**: +```bash +⧗ input: update code +✖ subject may not be empty [subject-empty] +✖ type may not be empty [type-empty] +✖ found 2 problems, 0 warnings +``` + +Fix the commit message: +```bash +git commit --amend -m "fix(api-console): resolve navigation issue" +``` + +--- + +## Branch Naming Patterns + +### 1. `fix/W-XXXXX-description` - Component Bug Fixes + +**Use when**: Fixing a bug in an individual component repository + +**Applies to**: +- `@api-components/api-example-generator` +- `@api-components/api-type-document` +- `@api-components/api-navigation` +- `@api-components/api-summary` +- `@api-components/api-documentation` +- `@api-components/api-request` +- All other `@api-components/*` packages + +**Format**: `fix/W-XXXXXXXX-short-description` + +**Examples**: +```bash +fix/W-21368901-deep-allof +fix/W-12345678-grpc-schema-parsing +fix/W-87654321-nullable-union-types +``` + +**Workflow**: +1. Create `fix/W-XXXXX-description` branch +2. Implement fix + tests +3. **DO NOT** run `npm version patch` in the branch +4. Commit changes with conventional commit message +5. Push branch +6. Create PR +7. **After merge**: GitHub Actions auto-publishes new version (e.g., 4.4.36) + +**Why no version bump in branch**: Allows multiple fixes to be in progress simultaneously without version conflicts. GitHub Actions handles version bumping after merge. + +--- + +### 2. `build/X.X.X` - API Console Releases + +**Use when**: Creating a new api-console release that bundles multiple component updates + +**Applies to**: +- `mulesoft/api-console` (main repo) + +**Format**: `build/X.X.X` where X.X.X is the **next** patch version + +**Examples**: +```bash +build/6.6.62 +build/6.6.63 +build/6.7.0 # Minor version bump +``` + +**Workflow**: +1. Component fixes are already published (e.g., api-example-generator@4.4.36, api-type-document@4.2.42) +2. Create `build/X.X.X` branch (calculate next version from package.json) +3. Run `npm update @api-components/component-name` for each updated component +4. Run `npm version patch` (bumps version in package.json) +5. Commit all changes (package.json, package-lock.json) +6. Push branch +7. Create PR with title: `Release vX.X.X` +8. **After merge**: GitHub Actions publishes api-console@X.X.X to npm + +**Why `build/` not `fix/`**: +- A release typically includes **multiple** component updates (3-5 components) +- Each component may have different GUS work items +- `build/` signals "this is a bundled release", not a single fix +- Prevents confusion when multiple releases are prepared in parallel + +**Version calculation**: +- Read current version from `package.json` +- Increment patch: `6.6.61` → `6.6.62` +- Use incremented version in branch name + +--- + +### 3. `X.X.X` - Wrapper Releases (No Prefix) + +**Use when**: Updating anypoint-api-console wrapper with new api-console version + +**Applies to**: +- `mulesoft-emu/anypoint-api-console` (wrapper repo) + +**Format**: `X.X.X` (direct number, **no prefix**) + +**Examples**: +```bash +6.6.88 +6.6.89 +6.7.0 +``` + +**Workflow**: +1. Wait for api-console@X.X.X to be published to npm (~5-10 min after merge) +2. Create branch with wrapper version number (independent from api-console version) +3. Update `builder/package.json` with new api-console dependency +4. Delete `builder/package-lock.json` and `builder/node_modules` (mandatory) +5. Run `npm install` in `builder/` +6. Commit changes (NO version bump in root package.json) +7. Push branch +8. Create PR with title: `@W-XXXXXXXX: Release X.X.X` +9. After merge: Manual or automated deployment + +**Why no prefix**: +- Historical convention in this repo +- Wrapper versions are independent from api-console versions +- Example: api-console 6.6.62 → wrapper 6.6.88 + +--- + +## Comparison Table + +| Scenario | Branch Pattern | Repo | Version Bump in Branch? | Commit Message Format | Example | +|----------|----------------|------|-------------------------|-----------------------|---------| +| Fix bug in component | `fix/W-XXXXX-desc` | `@api-components/*` | ❌ No | ✅ Conventional Commits | `fix/W-21368901-deep-allof` | +| Release api-console | `build/X.X.X` | `mulesoft/api-console` | ✅ Yes (`npm version patch`) | ✅ Conventional Commits | `build/6.6.62` | +| Update wrapper | `X.X.X` | `mulesoft-emu/anypoint-api-console` | ❌ No | ✅ Conventional Commits | `6.6.88` | + +**Note**: Commit messages are validated by commitlint in ALL repos, regardless of branch naming pattern. + +--- + +## Why This Pattern? + +### Problem: Version Conflicts +If we used `fix/` branches in api-console and ran `npm version patch` in each: +- Developer A: `fix/bug-1` → bumps to 6.6.62 +- Developer B: `fix/bug-2` → also bumps to 6.6.62 +- **Conflict**: Both branches claim the same version + +### Solution: Separate Concerns +- **Components**: `fix/` branches focus on code changes, version bump happens after merge +- **api-console**: `build/` branches bundle multiple components, explicit version in branch name prevents conflicts +- **Wrapper**: Direct version number, independent versioning + +### Note on commitlint + +**commitlint validates commit messages, NOT branch names.** + +- ✅ Branch names: `fix/W-12345-bug`, `build/6.6.62`, `feat/my-feature` - **ALL valid** +- ✅ Commit messages: **MUST** follow Conventional Commits format (enforced) + +**Why this matters**: +- Branch names are flexible and team-specific +- Commit messages are standardized across projects (tooling compatibility) +- Git history benefits from consistent commit message format +- Branch names are temporary (deleted after merge), commit messages are permanent + +--- + +## Related GUS Work Items + +### Components +- Each fix has its own GUS work item +- Format: `W-XXXXXXXX` (no prefix in branch name) +- Example: `fix/W-21368901-deep-allof` → W-21368901 + +### api-console +- Release may reference multiple GUS work items (from bundled components) +- Commit message lists all related work items +- PR body includes all component updates with their GUS tickets + +### Wrapper +- Typically has one "APIC Release" work item (reused across releases) +- Example: W-21411326 (Type: User Story, 1 story point) +- PR title always prefixed with `@W-XXXXXXXX:` + +--- + +## Examples from Recent Work + +### Scenario: Fix deeply nested allOf bug (W-21368901) + +**Step 1: Fix in api-example-generator** +```bash +cd ~/mulesoft/context/products/api-console/v6/api-example-generator +git checkout -b fix/W-21368901-deep-allof +# Implement fix + tests +git add src/ test/ +git commit -m "fix(W-21368901): add recursive property collection for deep allOf" +# NO npm version patch here +git push -u origin fix/W-21368901-deep-allof +# Create PR → Merge → GitHub Actions publishes 4.4.36 +``` + +**Step 2: Fix in api-type-document** +```bash +cd ~/mulesoft/context/products/api-console/v6/api-type-document +git checkout -b fix/W-21368901-deep-allof +# Implement parallel fix +git commit -m "fix(W-21368901): add recursive property collection" +# NO npm version patch here +git push -u origin fix/W-21368901-deep-allof +# Create PR → Merge → GitHub Actions publishes 4.2.42 +``` + +**Step 3: Release api-console** +```bash +cd ~/mulesoft/context/products/api-console/v6/api-console +git checkout -b build/6.6.62 +npm update @api-components/api-example-generator @api-components/api-type-document +npm version patch # Bumps to 6.6.62 +git add package.json package-lock.json +git commit -m "chore: bump version to 6.6.62 + +Updated components: +- @api-components/api-example-generator: 4.4.35 → 4.4.36 +- @api-components/api-type-document: 4.2.41 → 4.2.42 + +Related: W-21368901" +git push -u origin build/6.6.62 +# Create PR → Merge → GitHub Actions publishes 6.6.62 +``` + +**Step 4: Update wrapper** +```bash +cd ~/mulesoft/context/products/api-console/wrapper +git checkout -b 6.6.88 +# Edit builder/package.json: "api-console": "6.6.62" +cd builder +rm package-lock.json && rm -rf node_modules && npm install +cd .. +git add builder/package.json builder/package-lock.json +git commit -m "chore: update api-console to 6.6.62 + +Includes component updates: +- @api-components/api-example-generator: 4.4.36 +- @api-components/api-type-document: 4.2.42 + +Related: W-21368901" +git push -u origin 6.6.88 +gh pr create --title "@W-21411326: Release 6.6.88" --body "..." +``` + +--- + +## Validation Checklist + +Before creating branch: +- [ ] Identified correct pattern (`fix/`, `build/`, or direct number) +- [ ] For `build/`: Calculated next version from current package.json +- [ ] For wrapper: Determined independent wrapper version +- [ ] Have GUS work item numbers ready for commit messages + +Before pushing: +- [ ] Branch name follows convention +- [ ] Version bump only in `build/` branches (not `fix/`) +- [ ] Commit message references GUS work items +- [ ] GPG signature correct (mulesoft-git or salesforce-git) + +--- + +## Common Mistakes + +### ❌ Wrong: Using `fix/` in api-console for releases +```bash +# DON'T DO THIS +git checkout -b fix/W-21368901-deep-allof # Wrong for api-console +npm version patch # Creates version conflict risk +``` + +### ✅ Correct: Using `build/` in api-console +```bash +# DO THIS +git checkout -b build/6.6.62 # Clear version intent +npm version patch # Safe, version is in branch name +``` + +### ❌ Wrong: Running `npm version patch` in component `fix/` branch +```bash +cd api-example-generator +git checkout -b fix/W-12345-bug +# ... make changes ... +npm version patch # DON'T DO THIS - let CI handle it +``` + +### ✅ Correct: Let CI handle component versioning +```bash +cd api-example-generator +git checkout -b fix/W-12345-bug +# ... make changes ... +git commit -m "fix(W-12345): description" +# Merge PR → CI auto-publishes with version bump +``` + +--- + +## Questions? + +Contact: +- **API Console**: ACM Team (#api-console-cloud-sync) +- **Pattern clarification**: Alex Pérez +- **Documentation updates**: Submit PR to this file + +--- + +**Last Updated**: 2026-03-03 +**Version**: 1.0 diff --git a/docs/team/runbooks/00-debugging-common-issues.md b/docs/team/runbooks/00-debugging-common-issues.md new file mode 100644 index 000000000..02b71572e --- /dev/null +++ b/docs/team/runbooks/00-debugging-common-issues.md @@ -0,0 +1,278 @@ +# Runbook: Debugging Common Issues + +**Project**: api-console (Open Source) +**Last Updated**: 2026-02-26 + +--- + +## Quick Links + +- **Demo**: `npm start` → http://localhost:8080 +- **Tests**: `npm test` +- **Repo**: https://github.com/mulesoft/api-console +- **Issues**: https://github.com/mulesoft/api-console/issues + +--- + +## Common Issues + +### Issue 1: Component Not Rendering + +**Symptoms**: Component shows nothing, or only skeleton + +**Diagnosis**: +1. Check browser console for errors +2. Check if `amf` property is set +3. Check if component is registered (`customElements.get('api-console')`) +4. Inspect Shadow DOM in DevTools + +**Common Causes**: +- AMF not loaded or invalid +- Async rendering not complete +- CSS not loaded (check for `