Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 0 additions & 22 deletions .github/workflows/close_stale.yml

This file was deleted.

94 changes: 58 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,64 @@
</div>

ApexDocs is a non-opinionated documentation generator for Salesforce Apex classes.
It can output documentation in Markdown
format,
which allows you to use the Static Site Generator of your choice to create a documentation site that fits your needs,
hosted in any static web hosting service.
It can output documentation in Markdown format, which allows you to use the Static Site Generator of your choice to
create a documentation site that fits your needs, hosted in any static web hosting service.

## 👀 Examples

ApexDocs generates Markdown files, which can be integrated into any Static Site Generation (SSG) engine,
(e.g. Jekyll, Vitepress, Hugo, Docosaurus, etc.) to create a documentation site that fits your needs.

This gives you the flexibility to create beautiful leveraging your preferred SSG engine, which
usually provides a wide range of themes, dark mode support, and other features out of the box.

<div align="center">
<img src="imgs/vitepress-light.png" alt="Vitepress Light" width="45%" />
<img src="imgs/vitepress-dark.png" alt="Vitepress Dark" width="45%" />
</div>

*These are examples of documentation sites generated using Vitepress.
Head over to the `examples/vitepress` folder to see the code.*

The extra flexibility also lets you integrate the output documentation with your existing documentation site,
allowing you to match the look and feel of your existing site.

<div align="center">
<img src="imgs/integration.png" alt="Integration" width="70%" />
</div>

OpenApi REST definitions can be visualized using a tool like ReDoc, Swagger UI, or any other OpenApi viewer.

<div align="center">
<img src="imgs/redocly.png" alt="OpenApi" width="70%" />
</div>

This repo contains several other example implementations in the `examples` directory, showcasing how to integrate
with different tools.

* [Examples](./examples)

### In the wild

Here are some live projects using ApexDocs:

- [Trailhead Apex Recipes](https://github.com/trailheadapps/apex-recipes)
- [Salesforce Commerce Apex Reference](https://developer.salesforce.com/docs/commerce/salesforce-commerce/references/comm-apex-reference/cart-reference.html)
- [Expression (API)](https://cesarparra.github.io/expression/)
- [Nimble AMS Docs](https://nimbleuser.github.io/nams-api-docs/#/api-reference/)

## 🚀 Features

* Generate documentation for Salesforce Apex classes as Markdown files
* Generate an OpenApi REST specification based on `@RestResource` classes
* Generate a changelog based on the differences between two versions of your Salesforce Apex classes
* Support for grouping blocks of related code within a class
* Support for ignoring files and members from being documented
* Namespace support
* Configuration file support
* Single line ApexDoc Blocks
* Custom tag support
* And much, much more!

## 💿 Installation

Expand Down Expand Up @@ -49,38 +103,6 @@ Run the following command to generate a changelog for your Salesforce Apex class
apexdocs changelog --previousVersionDir force-app-previous --currentVersionDir force-app
```

## 🚀 Features

* Generate documentation for Salesforce Apex classes as Markdown files
* Generate an OpenApi REST specification based on `@RestResource` classes
* Generate a changelog based on the differences between two versions of your Salesforce Apex classes
* Support for grouping blocks of related code within a class
* Support for ignoring files and members from being documented
* Namespace support
* Configuration file support
* Single line ApexDoc Blocks
* Custom tag support
* And much, much more!

## 👀 Demo

ApexDocs generates Markdown files, which can be integrated into any Static Site Generation engine,
(e.g. Jekyll, Vitepress, Hugo, Docosaurus, etc.) to create a documentation site that fits your needs.

This repo contains several example implementations in the `examples` directory, showcasing how to integrate
with some of these tools.

* [Examples](./examples)

### In the wild

Here are some live projects using ApexDocs:

- [Trailhead Apex Recipes](https://github.com/trailheadapps/apex-recipes)
- [Salesforce Commerce Apex Reference](https://developer.salesforce.com/docs/commerce/salesforce-commerce/references/comm-apex-reference/cart-reference.html)
- [Expression (API)](https://cesarparra.github.io/expression/)
- [Nimble AMS Docs](https://nimbleuser.github.io/nams-api-docs/#/api-reference/)

## ▶️ Available Commands

### Markdown
Expand Down
6 changes: 3 additions & 3 deletions examples/open-api/docs/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
}
],
"paths": {
"AccountService/": {
"/AccountService/": {
"description": "Account related operations",
"get": {
"tags": [
Expand Down Expand Up @@ -338,7 +338,7 @@
}
}
},
"Contact/": {
"/Contact/": {
"description": "Contact related operations",
"get": {
"tags": [
Expand All @@ -359,7 +359,7 @@
}
}
},
"Order/": {
"/Order/": {
"description": "Order related operations",
"get": {
"tags": [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>62.0</apiVersion>
<status>Active</status>
</ApexClass>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>62.0</apiVersion>
<status>Active</status>
</ApexClass>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>62.0</apiVersion>
<status>Active</status>
</ApexClass>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>62.0</apiVersion>
<status>Active</status>
</ApexClass>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>62.0</apiVersion>
<status>Active</status>
</ApexClass>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>62.0</apiVersion>
<status>Active</status>
</ApexClass>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>62.0</apiVersion>
<status>Active</status>
</ApexClass>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>62.0</apiVersion>
<status>Active</status>
</ApexClass>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>62.0</apiVersion>
<status>Active</status>
</ApexClass>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>62.0</apiVersion>
<status>Active</status>
</ApexClass>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>62.0</apiVersion>
<status>Active</status>
</ApexClass>
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* @description Contact related operations
*/
@RestResource(urlMapping='/Contact/*')
@RestResource(UrlMapping='/Contact/*')
global with sharing class SampleRestResourceWithInnerClass {
/**
* @description This is a sample HTTP Get method
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>62.0</apiVersion>
<status>Active</status>
</ApexClass>
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* @description Order related operations
*/
@RestResource(urlMapping='/Order/*')
@RestResource(UrlMapping='/Order/*')
global with sharing class SampleRestResourceWithoutApexDocs {
@HttpGet
global static String doGet(String param1, Reference1 param2) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>62.0</apiVersion>
<status>Active</status>
</ApexClass>
Binary file added imgs/integration.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added imgs/redocly.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added imgs/vitepress-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added imgs/vitepress-light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@cparra/apexdocs",
"version": "3.3.1",
"version": "3.3.2",
"description": "Library with CLI capabilities to generate documentation for Salesforce Apex classes.",
"keywords": [
"apex",
Expand Down
8 changes: 4 additions & 4 deletions src/core/openapi/__tests__/open-api-docs-processor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ it('should add a path based on the @UrlResource annotation on the class', functi
const processor = new OpenApiDocsProcessor(noLogger);
processor.onProcess(classMirror);

expect(processor.openApiModel.paths).toHaveProperty('Account/');
expect(processor.openApiModel.paths).toHaveProperty('/Account/');
});

it('should respect slashes', function () {
const annotationElementValue = {
key: 'urlMapping',
value: "'v1/Account/*'",
value: "'/v1/Account/*'",
};
const classMirror = new ClassMirrorBuilder()
.addAnnotation(new AnnotationBuilder().addElementValue(annotationElementValue).build())
Expand All @@ -39,7 +39,7 @@ it('should respect slashes', function () {
const processor = new OpenApiDocsProcessor(noLogger);
processor.onProcess(classMirror);

expect(processor.openApiModel.paths).toHaveProperty('v1/Account/');
expect(processor.openApiModel.paths).toHaveProperty('/v1/Account/');
});

it('should contain a path with a description when the class has an ApexDoc comment', function () {
Expand All @@ -55,5 +55,5 @@ it('should contain a path with a description when the class has an ApexDoc comme
const processor = new OpenApiDocsProcessor(noLogger);
processor.onProcess(classMirror);

expect(processor.openApiModel.paths['Account/'].description).toBe('My Description');
expect(processor.openApiModel.paths['/Account/'].description).toBe('My Description');
});
10 changes: 5 additions & 5 deletions src/core/openapi/open-api-docs-processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,10 @@ export class OpenApiDocsProcessor {
return null;
}

let endpointPath = urlMapping.value.replaceAll('"', '').replaceAll("'", '').replaceAll('/*', '/');
if (endpointPath.startsWith('/')) {
endpointPath = endpointPath.substring(1);
}
return endpointPath;
// The OpenApi path needs to start with a leading slash, but
// Salesforce @RestResource annotations already require a leading slash,
// so no need to check for it.
// See URL Guidelines: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_annotation_rest_resource.htm
return urlMapping.value.replaceAll('"', '').replaceAll("'", '').replaceAll('/*', '/');
}
}
Loading