Giter Site home page Giter Site logo

cesarparra / apexdocs Goto Github PK

View Code? Open in Web Editor NEW
102.0 102.0 18.0 1.79 MB

Node.js tool to generate documentation for your Salesforce Apex Classes.

Home Page: https://www.npmjs.com/package/@cparra/apexdocs

License: MIT License

JavaScript 3.34% TypeScript 96.66%
apex apex-class apex-framework docs documentation npm salesforce

apexdocs's People

Contributors

cesarparra avatar dependabot[bot] avatar nicolasgach avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

apexdocs's Issues

Possibility to provide the documentation root folder

I'm using docsify for documentation. My docs folder structure is the following:

docs/
  | - examples/
  | - types/
         | - Classes/      # <-- This is the `Classes` group folder
         | - README.md      # <-- This is the documentation generated by `apexdocs` package
  | - README.md
  | - index.html      # <-- This is the `docsify` index.html file 

So, the problem I'm facing is that Apex classes documentation is not located in the root folder but when I generate it, the links are referencing relatively to the Apex classes README files in group folders:

## Classes

### [SomeService](/Classes/SomeService.md)

Some description

This doesn't work for docsify, as my index.html file is located one level above. It means that when I try to check the Apex Classes documentation from docsify page, clicking on a particular class link, it tries to direct me to /Classes/SomeService.md. But the actual URL in my case should be /types/Classes/SomeService.md.

My current workaround is manually replacing links in the docs folder with a sed bash command but I was wondering what you think about this case and if this could be addressed with an additional option like rootFolder or something.
Thanks in advance

No docGenerator function in export

Good afternoon. Just installed from npm @ v2.2.2 and tried importing into my nodejs script. The documentation indicates there's a docGenerator function that should be part of the export but I wasn't able to find it anywhere:

If you are just interested in the documentation parsing capabilities, you can import ApexDocs into your own project.

Use the docGenerator function to create a list of ClassModel that includes all the parsed information from your .cls files [...]

Feature request: accept single source file as CLI input

First of all, thanks for this great tool. We're using it several project including the Apex Recipes sample app.

As part of our dev workflows we use lint-staged to automatically run some pre-commit scripts on files that are staged (not the entire repo):

  • formatting with Prettier
  • linting with ESLint
  • LWC tests with Jest.

It would be great if we could add apexdocs to this workflow. However, in order to achieve this and make apexdocs work with lint-staged, we need the apexdocs CLI to accept an individual source file instead of an entire source directory.
Is this a feature that you would consider?

Remove Group name from markdown

When generating docs with a group, apexdocs automatically adds the Markdown Group to all the files. Is there a way to turn this off?

Option to customize the result README title for non openApi generators

Would it be possible to have an option to customize the current # Classes title in the result README.md file?
The use case is that I want to group all of my package classes into: Classes/Interfaces/Enums. But this standard Classes title in the beginning doesn't seem to make sense in this case as it's the main header.

Expected result:

# My Custom Title
## Classes

### [Service](/Classes/Service.md)

Some service description

## Interfaces

### [IService](/Interfaces/IService.md)

Actual result:

# Classes
## Classes

### [Service](/Classes/Service.md)

Some service description

## Interfaces

### [IService](/Interfaces/IService.md)

Method Return Types not documented correctly

If we add a space in the method return type (space between , and Object here). The space breaks the documentation. the return type in the Markdown file only contains Object>

public static Map<String, Object> getActiveSurveySettings(String surveyType){ ... }
image

If we remove the space it works as expected.

public static Map<String,Object> getActiveSurveySettings(String surveyType){ ... }
image

@start-group doesn't like quotes

This works perfectly:

public class ApexUtil {

    // @start-group allOrNothing param values DML Operations
    public static final Boolean ALLOW_PARTIAL_SUCCESS = false;
    public static final Boolean ALL_OR_NOTHING = true;
    // @end-group

    // @start-group caseSensitive param values for ApexUtil.getPattern()
...

But if I add backticks (or single- or double-quotes) around the first word of the group description, it does not:

public class ApexUtil {

    // @start-group 'allOrNothing' param values DML Operations
    public static final Boolean ALLOW_PARTIAL_SUCCESS = false;
    public static final Boolean ALL_OR_NOTHING = true;
    // @end-group

    // @start-group caseSensitive param values for ApexUtil.getPattern()
...

Resulting in:

7/8/2022, 9:15:47 AM: ApexUtil.cls - Parsing error Exception: Error parsing Apex Body. Line 14:4 - extraneous input '// @end-group' expecting {'abstract', 'after', 'before', 'class', 'enum', 'final', 'get', 'global', 'inherited', 'instanceof', 'interface', 'override', 'private', 'protected', 'public', 'set', 'sharing', 'static', 'switch', 'testmethod', 'transient', 'trigger', 'virtual', 'void', 'webservice', 'when', 'with', 'without', 'list', 'map', 'select', 'count', 'from', 'as', 'using', 'scope', 'where', 'order', 'by', 'limit', 'and', 'or', 'not', 'avg', 'count_distinct', 'min', 'max', 'sum', 'typeof', 'end', 'then', 'like', 'in', 'includes', 'excludes', 'asc', 'desc', 'nulls', 'first', 'last', 'group', 'all', 'rows', 'view', 'having', 'rollup', 'tolabel', 'offset', 'data', 'category', 'at', 'above', 'below', 'above_or_below', 'security_enforced', 'reference', 'cube', 'format', 'tracking', 'viewstat', 'custom', 'standard', 'calendar_month', 'calendar_quarter', 'calendar_year', 'day_in_month', 'day_in_week', 'day_in_year', 'day_only', 'fiscal_month', 'fiscal_quarter', 'fiscal_year', 'hour_in_day', 'week_in_month', 'week_in_year', 'converttimezone', 'yesterday', 'today', 'tomorrow', 'last_week', 'this_week', 'next_week', 'last_month', 'this_month', 'next_month', 'last_90_days', 'next_90_days', 'last_n_days', 'next_n_days', 'next_n_weeks', 'last_n_weeks', 'next_n_months', 'last_n_months', 'this_quarter', 'last_quarted', 'next_quarter', 'next_n_quarters', 'last_n_quarters', 'this_year', 'last_year', 'next_year', 'next_n_years', 'last_n_years', 'this_fiscal_quarter', 'last_fiscal_quarter', 'next_fiscal_quarter', 'next_n_fiscal_quarters', 'last_n_fiscal_quarters', 'this_fiscal_year', 'last_fiscal_year', 'next_fiscal_year', 'next_n_fiscal_years', 'last_n_fiscal_years',

If I insert any text before the quoted word, it's fine... I can even use backticks to get monospaced text as intended. It just seems to be the first non-space character after @start-group that matters.

zsh: command not found: apexdocs-generate

Hi,

after install using instructions I can't launch apexdocs-generate and show this error:
zsh: command not found: apexdocs-generate

Thanks in advance

Version: 1.55.2
Commit: 3c4e3df9e89829dce27b7b5c24508306b151f30d
Date: 2021-04-13T09:36:32.643Z (1 day ago)
Electron: 11.3.0
Chrome: 87.0.4280.141
Node.js: 12.18.3
V8: 8.7.220.31-electron.0
OS: Darwin x64 20.3.0

Example blocks with URLS are truncated after //

This Doc block

/**
     * @description @HttpGet exposes a method to a GET request when the custom REST endpoint is called. A GET request allows us to return
     * data from Salesforce. In this example, we're going to query a list of Accounts that were created and return them to the application that
     * called the endpoint. When creating a response we can use the RestResponse class to specify certain fields of the payload that is
     * sent. We are manually setting the statusCode as 200 for a successful get and 400 on error. In any other case, Salesforce will supply the error code.
     *
     * Note: This method has a false-positive PMD warning. Our Query
     * includes the keyword 'WITH SECURITY_ENFORCED' which prevents this
     * Query from accessing fields and objects that they don't have permission
     * to access. This is a form of inline CRUD/FLS Check.
     *
     * The return statement is atomically serialized and returned in the responseBody.
     * @return RestResponse  A list of Accounts or the exception message
     * @example
     * curl -H "Authorization: Bearer <SessionID>" "https://<Org Base URL>/services/apexrest/IntegrationService"
     */

Results in the following Markdown:

@HttpGet exposes a method to a GET request when the custom REST endpoint is called. A GET request allows us to return data from Salesforce. In this example, we're going to query a list of Accounts that were created and return them to the application that called the endpoint. When creating a response we can use the RestResponse class to specify certain fields of the payload that is sent. We are manually setting the statusCode as 200 for a successful get and 400 on error. In any other case, Salesforce will supply the error code. Note: This method has a false-positive PMD warning. Our Query includes the keyword 'WITH SECURITY_ENFORCED' which prevents this Query from accessing fields and objects that they don't have permission to access. This is a form of inline CRUD/FLS Check. The return statement is atomically serialized and returned in the responseBody.

#### Example
```java
curl -H "Authorization: Bearer <SessionID>" "https:

Add return type to method signatures

Methods do not display with the return type. Even though the return type appears when specified in the apex doc, the signature itself should have it to clarify what the method returns even when a doc comment is not present

image

@start-group/@end-group directives ignored (2.2.1)

Running @cparra/[email protected], I'm trying to use the new @start-group/@end-group directives added in v2.1.0 (and thanks for that!), but they don't seem to work. Here's the start of my class:

public with sharing class CodeControl {

    // @start-group Picklist constant for Code_Control__mdt.Logging__c
    public static final String LOGGING_CONTROL_NONE = 'None';
    public static final String LOGGING_CONTROL_DEBUG = 'Debug';
    public static final String LOGGING_CONTROL_ERROR = 'Error';
    // @end-group

    // @start-group Picklist constants for Code_Control__mdt.Enabled__c
    public static final String TRIGGER_CONTROL_ENABLED = 'Yes';
    public static final String TRIGGER_CONTROL_DISABLED = 'No';
    public static final String FEATURE_CONTROL_ENABLED = 'Yes';
    public static final String FEATURE_CONTROL_DISABLED = 'No';
    // @end-group

    /* Special MDT values */
    public static final String WILDCARD_SOURCE = 'CodeControl_Default';
    public static final String SYSTEM_WIDE_SOURCE = 'CodeControl_Override';

And here's the output:

---
## Properties

### `FEATURE_CONTROL_DISABLED` → `String`

### `FEATURE_CONTROL_ENABLED` → `String`

### `LOGGING_CONTROL_DEBUG` → `String`

### `LOGGING_CONTROL_ERROR` → `String`

### `LOGGING_CONTROL_NONE` → `String`

### `SYSTEM_WIDE_SOURCE` → `String`

### `TRIGGER_CONTROL_DISABLED` → `String`

### `TRIGGER_CONTROL_ENABLED` → `String`

### `WILDCARD_SOURCE` → `String`

---
## Methods

I tried wrapping the last two constants in a group just in case, but it had no effect.

Option to filter out certain files

Add an option to filter out files, especially useful for managed packages that only have a (hidden) content.

Add option to ignore files without comments or with a certain annotation

Generated Links Point to Invalid Target

Hey there, this may be a user issue but I don't really see a way to modify this behavior. When I generate markdown files the links that get created point to an invalid path. It seems to be trying to use the root path instead of a relative path. Example when viewing a file located at

file:///C:/ApexDoc/markdown/Forfeitures/BatchForfeitureEmailNotification.md

the link for the test class mentioned in the @see param pointed at

file:///C:/Forfeitures/BatchForfeitureEmailNotificationTest.md

When it really just needed to point to

../Forfeitures/BatchForfeitureEmailNotificationTest.md

I am using a Chrome extension for my markdown viewer so it's possible that is causing a problem, but then also using another utility to convert the generated markdown files to PDFs the link is also bad there so I think its just being generated using that incorrect path. Again this is probably on me somehow but I'm not quite sure how to fix. Thanks in advance!

Open API examples

Is there an example to show the array reference for a custom class? The documentation reference shows custom schemas or is the parser automatically generates the array type?

global AddressDTO {
    public String streetAddress { get; set; }
    public String city { get; set; }
}
global class CustomerDTO {
    /**
     * @description Customer addressed
     * @http-schema
     *   type: array
     *   items:
     *      $ref: "#/components/schemas/AddressDTO"
     */
    public List<AddressDTO> addresses { get; set; }
}

Issue with test class parsing

Hey there. I just updated to the new version and now I'm having issues when generating documentation for test classes. It seems to be choking on the @istest annotation.

Running command: apexdocs-generate -s input -t temp\markdown\

5/17/2022, 2:55:43 PM: Parsing error Exception: Error parsing Apex Body. Line 2:0 - no viable alternative at input '@isTest\n/** \n* @Name StripeIntegrationWrapperTest\n* \n* @Date 2/28/2022\n* @Group Stripe Integration\n* @See StripeIntegrationWrapper\n* @Description Test class for StripeIntegrationWrapper\n**/'
5/17/2022, 2:55:44 PM: Parsing error Exception: Error parsing Apex Body. Line 2:0 - no viable alternative at input '@isTest\n/** \n* @Name StripeRESTServiceTest\n* \n* @Date 3/2/2022\n* @Group Stripe Integration\n* @See StripeRESTService\n* @Description Test class for StripeRESTService. Ensures all methos in the class work as expected.\n**/'
5/17/2022, 2:55:44 PM: Parsed 1 files
StripeRESTService - Doc comment parsing error. Level: Type
Comment:
 /**
* @Name StripeRESTService
* @Date 3/2/2022
* @Group Stripe Integration
* @See StripeRESTServiceTest
* @Description Apex class that creates and exposes a REST endpoint by the name of 'Stripe'. [ORG_URL]/services/apexrest/Stripe (case sensitive!)
* 
*

Failed to parse .cls files on MacOS

Seems not working on MacOS:

npm run apexdocs-generate

> [email protected] apexdocs-generate
> apexdocs-generate -s ./force-app/main/promoengine/selectors -r true -t ./docs

5/17/2022, 9:38:44 AM: Parsed 0 files
5/17/2022, 9:38:44 AM: index processed.

% ls ./force-app/main/promoengine/selectors
WebCartSelector.cls		WebCartSelector.cls-meta.xml

Bit more multi-line weirdness

Cesar,

Again, thank you for your work on this and your responsiveness.

I've hit upon another bit of wonky parsing, and I'm not sure what to make of it. Here's the Apex method causing troubles

/**
     * @description - Demonstrates how to use the Database.insert() method to persist a net-new
     *  record to the database.
     * @param  name         name Passed through to the account created
     * @param  allOrNothing allOrNothing determines whether or not all accounts to be inserted must insert successfully
     */
    public static void insertAccountsViaDatabaseMethod(
        String name,
        Boolean allOrNothing
    ) {
        Account acct = new Account(name = name);
        Account acct2 = new Account();

        try {
            if (CanTheUser.create(acct)) {
                Database.insert(new List<Account>{ acct, acct2 }, allOrNothing);
            }
        } catch (DMLException DMLe) {
            throw new CustomDMLException('Failed');
        }
    }

It's generating this markdown

---
## Methods
### `)` → ``

- Demonstrates how to use the Database.insert() method to persist a net-new record to the database.
#### Parameters
|Param|Description|
|-----|-----------|
|`name` |          name Passed through to the account created |
|`allOrNothing` |  allOrNothing determines whether or not all accounts to be inserted must insert successfully |

Specifically, it's not properly parsing the method name, and I'm not sure why. 4 methods in this file (I gave one example above) fail to parse, but the other ~5-6 work fine.

Jekyll output: front matter configuration

It would be nice to have a feature where you could configure the output for jekyll to not just include the layout in the front matter, but also add the title.

For example, I'd like to be able to add the "title" to all the files with their filenames.
---
title: filename.cls
---

Allow for empty @argument, @return, and other tags

Currently the parser for docs complains about empty @argument, @return, and possible other tags where it expects some kind of body. Maybe we can allow for this without the parser complaining and simply not have a description for those that are empty

Missing @return parsing ?

Hello Cesar,
First of all thanks for sharing this plugin, what a very useful work ! I've stumbled upon what I believe to be an issue with the parsing of @return statements in the javadoc like structure. Here's the simple dummy class I wrote, and below the generate markdown. No configuration file is used. Happy to help solve this if you'd like, although I'm not sure where to start in the implementation you propose.

public class dummyTest {
    /**
     * @description Some description for the class.
     * @param myParam Some input parameter
     * @return a return value
     */
    public String dummyMethod(Integer myParam) {
        return '';
    }
}

And the generated markdown :

---
layout: default
---
# dummyTest class
---
## Methods
### `dummyMethod(Integer myParam)` → `String`

Some description for the class.

#### Parameters
|Param|Description|
|-----|-----------|
|`myParam` |  Some input parameter |

---

Thanks again for your work, I can definitely see this plugin gaining a lot of traction and interest seeing the void around proper Javadoc like support for Apex !

MODULE_NOT_FOUND when installed globally

When installing with -g to make it available system-wide, the command fails with MODULE_NOT_FOUND.

internal/modules/cjs/loader.js:985
  throw err;
  ^

Error: Cannot find module '../command/Generate'
Require stack:
- /usr/local/lib/node_modules/@cparra/apexdocs/lib/cli/generate.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:982:15)
    at Function.Module._load (internal/modules/cjs/loader.js:864:27)
    at Module.require (internal/modules/cjs/loader.js:1044:19)
    at require (internal/modules/cjs/helpers.js:77:18)
    at Object.<anonymous> (/usr/local/lib/node_modules/@cparra/apexdocs/lib/cli/generate.js:5:20)
    at Module._compile (internal/modules/cjs/loader.js:1158:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10)
    at Module.load (internal/modules/cjs/loader.js:1002:32)
    at Function.Module._load (internal/modules/cjs/loader.js:901:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/usr/local/lib/node_modules/@cparra/apexdocs/lib/cli/generate.js'
  ]
}

OS: Linux
Node Version: 12.16.1
NPM Version: 6.14.2

I suspect it may be due to case sensitivity on this OS. The actual Command folder has a capital C with the stracktrace showing it's trying to load a lowercase c.

Feature Request: Better support for constants

I'm using @description to label my constants, which works, but they are treated as properties, so they are all sorted by name. I'd like the ability to group them together with a single description for a group of constants, with sorting only within each group, or even disabled altogether within a group.

As an example, here is an excerpt of the constants from a utility class I am documenting. While I understand that @description is intended to label only the item below it, I'm using it here as a "group description" just to illustrate what I'm looking for; I'm guessing a slightly different syntax would be needed. I'm ambivalent about the actual doc format, as long as the rendered output is what I need.

    /** @description Picklist constants for Code_Control__mdt.Logging__c */
    public static final String LOGGING_CONTROL_NONE = 'None';
    public static final String LOGGING_CONTROL_DEBUG = 'Debug';
    public static final String LOGGING_CONTROL_ERROR = 'Error';

    /** @description Picklist constants for Code_Control__mdt.Enabled__c */
    public static final String TRIGGER_CONTROL_ENABLED = 'Yes';
    public static final String TRIGGER_CONTROL_DISABLED = 'No';
    public static final String FEATURE_CONTROL_ENABLED = 'Yes';
    public static final String FEATURE_CONTROL_DISABLED = 'No';

    /** @description Wildcard and Override settings are only used for Logging and Trigger control.
     *               They are not used for feature control; the developer should create group-level
     *               defaults/overrides as separate features.
     */
    public static final String WILDCARD_SOURCE = 'CodeControl_Default';
    public static final String SYSTEM_WIDE_SOURCE = 'CodeControl_Override';

And here is what is output by apexdocs-generate:

---
## Properties

### `FEATURE_CONTROL_DISABLED` → `String`

### `FEATURE_CONTROL_ENABLED` → `String`

### `LOGGING_CONTROL_DEBUG` → `String`

### `LOGGING_CONTROL_ERROR` → `String`

### `LOGGING_CONTROL_NONE` → `String`

Picklist constants for Code_Control__mdt.Logging__c

### `SYSTEM_WIDE_SOURCE` → `String`

### `TRIGGER_CONTROL_DISABLED` → `String`

### `TRIGGER_CONTROL_ENABLED` → `String`

Picklist constants for Code_Control__mdt.Enabled__c

### `WILDCARD_SOURCE` → `String`

Wildcard and Override settings are only used for Logging and Trigger control. They are not used for feature control; the developer should create group-level defaults/overrides as separate features.

---

As expected, the "group-level" descriptions have become single-constant descriptions. I could almost live with that by positioning the descriptions appropriately, but the sorting has re-arranged all of the constants, separating related constants such as SYSTEM_WIDE_SOURCE and WILDCARD_SOURCE

Here's one idea for a new syntax, that allows for group-level and per-constant comments when needed:

    /** @constants Picklist constants for Code_Control__mdt.Logging__c */
    /** @description Record only Exceptions */
    public static final String LOGGING_CONTROL_NONE = 'None';
    /** @description Record debug, error, and exception level logging */
    public static final String LOGGING_CONTROL_DEBUG = 'Debug';
    /** @description Record error, and exception level logging */
    public static final String LOGGING_CONTROL_ERROR = 'Error';
    /** @end-constants **/

    /** @constants Picklist constants for Code_Control__mdt.Enabled__c 
     *   @description The `TRIGGER_CONTROL*` and `FEATURE_CONTROL*` constants are interchangeable; both names are provided for semantic purposes */
     */
    public static final String TRIGGER_CONTROL_ENABLED = 'Yes';
    public static final String TRIGGER_CONTROL_DISABLED = 'No';
    public static final String FEATURE_CONTROL_ENABLED = 'Yes';
    public static final String FEATURE_CONTROL_DISABLED = 'No';
    /** @end-constants **/

With potential output:

## Constants

### Picklist constants for Code_Control__mdt.Logging__c
* `LOGGING_CONTROL_NONE` - Record only Exceptions
* `LOGGING_CONTROL_DEBUG` -  Record debug, error, and exception level logging
* `LOGGING_CONTROL_ERROR` -  Record error, and exception level logging

### Picklist constants for Code_Control__mdt.Enabled__c
The `TRIGGER_CONTROL*` and `FEATURE_CONTROL*` constants are interchangeable; both names are provided for semantic purposes
* `TRIGGER_CONTROL_ENABLED`
* `TRIGGER_CONTROL_DISABLED`
* `FEATURE_CONTROL_ENABLED`
* `FEATURE_CONTROL_DISABLED`

"Maximum call stack size exceeded" error with 2.0.0-alpha.14

Decided to give the alpha I try (I could use the additional scope and annotation support), but I cannot get anything but an error:

> $ npm exec -- apexdocs-generate -s force-app/                                                            
node:internal/fs/utils:530
function getStatsFromBinding(stats, offset = 0) {
                            ^

RangeError: Maximum call stack size exceeded
    at getStatsFromBinding (node:internal/fs/utils:530:29)
    at Object.statSync (node:fs:1537:10)
    at DefaultFileSystem.isDirectory (/Users/jclark/Documents/dev/axia-core-utils/node_modules/@cparra/apexdocs/lib/service/file-system.js:7:19)
    at /Users/jclark/Documents/dev/axia-core-utils/node_modules/@cparra/apexdocs/lib/service/apex-file-reader.js:17:52
    at Array.forEach (<anonymous>)
    at Function.processFiles (/Users/jclark/Documents/dev/axia-core-utils/node_modules/@cparra/apexdocs/lib/service/apex-file-reader.js:15:27)
    at /Users/jclark/Documents/dev/axia-core-utils/node_modules/@cparra/apexdocs/lib/service/apex-file-reader.js:18:45
    at Array.forEach (<anonymous>)
    at Function.processFiles (/Users/jclark/Documents/dev/axia-core-utils/node_modules/@cparra/apexdocs/lib/service/apex-file-reader.js:15:27)
    at /Users/jclark/Documents/dev/axia-core-utils/node_modules/@cparra/apexdocs/lib/service/apex-file-reader.js:18:45

Node.js v17.2.0

I tried it in an empty project with a single apex class, with a single method (see below), and I get the same error. Should I try with a different version of Node.js?

/**********************************************************
@group          core-utils
@description    Core apex utilities for use in all projects
@author         Jason Clark
@date           11/10/20
***********************************************************/
public class ApexUtil {

    /**
     * @Description Given a list of sObjects, return a set of IDs of the objects.
     * @param objs List of SObjects
     * @return Set of Ids for all sObjects
     * @example Set<Id> accountIds = ApexUtil.getIds(accounts);
     */
    public static Set<Id> getIds(List<SObject> objs) {
        Map<Id,SObject> tmpMap = new Map<Id,SObject>(objs);
        return tmpMap.keySet().clone();
    }
}

Nothing being generated

It's me again, go figure haha. So since the most recent update I'm not able to get any output. It will iterate through the input files, say it's parsing, then say 0 files parsed. I don't know if its erroring on the files silently or for some reason considering them invalid? Not sure if there is a debug log or verbose mode that isn't documented but I'm not really sure how to debug this. I can send you my files that I'm trying to parse if that helps. It does generate the index.md file but it seems to be corrupt/incomplete. Let me know if there is any other info I can provide to help. Thanks!

image

image

Specify full list/set/map type in method return type

I saw that the latest version of apexdocs adds return types to method signatures and it would be nice if the lists/sets/maps were "fully" typed.

Screenshot 2023-10-04 at 16 58 40

For example, the return type in this specific example should be List<Account> instead of just List.

Feature Request: allow multiple source directories to be specified on command line

We are using sfdx unlocked packages to install some of our utility classes, and we recently started using the unpackaged metadata feature to move all of our test classes and test-only metadata out of the installed package. This results in a structure like this:

/package-root
  + /force-app
    + /main
      + /default
        + /classes
          | ApexClass.cls
  + /unpackaged-test-metadata 
    + /classes
      | ApexClassTest.cls

I'd like to run apexdocs once for both force-app/main/default/classes/ and unpackaged-test-metadata/classes, since I'm using @see in the class to reference the test class, and vice versa. I tried using the top-level project directory with recursion:

npm exec -- apexdocs-generate --s .  

But that missed unpackaged-test-metadata and picked up things in node_modules. Then I tried specifying two directories:

npm exec -- apexdocs-generate -s force-app/ -s unpackaged-test-metadata

But that resulted in an (unsurprising) error:

node:internal/fs/utils:670
    throw new ERR_INVALID_ARG_TYPE(propName, ['string', 'Buffer', 'URL'], path);
    ^

TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string or an instance of Buffer or URL. Received an instance of Array
    at Object.readdirSync (node:fs:1385:10)
    at getClassesFromDirectory (/Users/jclark/Documents/dev/axia-core-utils/node_modules/@cparra/apexdocs/lib/Command/Generate.js:37:34)
    at Object.generate (/Users/jclark/Documents/dev/axia-core-utils/node_modules/@cparra/apexdocs/lib/Command/Generate.js:29:21)
    at Object.<anonymous> (/Users/jclark/Documents/dev/axia-core-utils/node_modules/@cparra/apexdocs/lib/cli/generate.js:52:41)
    at Module._compile (node:internal/modules/cjs/loader:1097:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1149:10)
    at Module.load (node:internal/modules/cjs/loader:975:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
    at node:internal/main/run_main_module:17:47 {
  code: 'ERR_INVALID_ARG_TYPE'
}

Node.js v17.2.0

Note: You could argue that we don't need to document test classes, and I might agree - I'm still trying to decide best practices for apexdocs. However, the same issues will apply for any project which includes multiple packages. See for example this sample sfdx-project.json in the sfdx docs, which contains 4 packages with dependencies.

Docusaurus support

Was wondering what would it take for this to generate Docusaurus site? I love how Docusaurus works, but never understood how to implement myself.
Fuzzy search looks particularly useful!

Cheers

Don't parse annotations within comments

First of all thanks for the great work that you do around this tool, this is really helpful.

When running apexdocs on the following code, the parser breaks the class description.

/**
 * @description Demonstrates the @future syntax and usage
 */
public with sharing class AtFutureRecipes {
}

This generate the following doc:

---
layout: default
---
# AtFutureRecipes

Demonstrates the


**Future** syntax and usage

The problem is due to the fact that it attempts to parse the @future annotation within the description.
Could we prevent nested annotations parsing?

EINVAL: invalid argument, mkdir 'docs\:'

Hi,

I wanted to make it work, but there is something I really don't understand.
When I'm executing the command, it throw this error.

In the end, in my project, I see that a new folder has been created "docs" (default), and a readme.md. But there is nothing inside the readme.md.

I'm not able to make it work, do you have any idea ? Below, the code where you can see the error.

Thanks a lot !

$ apexdocs-generate -s force-app/main/default/classes/
Processed 1 files
internal/fs/utils.js:314
    throw err;
    ^

Error: EINVAL: invalid argument, mkdir 'docs\:'
    at Object.mkdirSync (fs.js:1009:3)
    at JekyllDocsProcessor.process (C:\Users\fabie\AppData\Roaming\npm\node_modules\@cparra\apexdocs\lib\MarkdownDocsProcessor.js:80:20)
    at C:\Users\fabie\AppData\Roaming\npm\node_modules\@cparra\apexdocs\lib\FileManager.js:24:27
    at Array.forEach (<anonymous>)
    at FileManager.generate (C:\Users\fabie\AppData\Roaming\npm\node_modules\@cparra\apexdocs\lib\FileManager.js:23:23)
    at Object.<anonymous> (C:\Users\fabie\AppData\Roaming\npm\node_modules\@cparra\apexdocs\lib\cli\generate.js:53:49)
    at Module._compile (internal/modules/cjs/loader.js:1085:14)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
    at Module.load (internal/modules/cjs/loader.js:950:32)
    at Function.Module._load (internal/modules/cjs/loader.js:790:14) {
  errno: -4071,
  syscall: 'mkdir',
  code: 'EINVAL',
  path: 'docs\\:'
}

Allow multiple @author and @date tags

Sometimes a method can have multiple @author and @date tags to show original and subsequent authors. Currently, the generated site only shows the last one.

Inconsistent link behavior

Me again :P
I am noticing an issue where the link generation from one document to another seems to be a little inconsistent or inaccurate. I've noticed two specific kinds of failures.

Issue 1

An @see tag is resolving the link to contain the folder name when both files are in the same folder. EX the source code for the file StripeAgreement.cls contains this tag.
@See StripeRESTService

Which when processed becomes a link
<a href="/Misc/StripeRESTService.md">StripeRESTService</a>

Which is incorrect as both StripeAgreement and StripeRestService are in the same folder (additionally they are being placed in a 'Misc' folder when they are both in the '@group Stripe_Integration', not sure why that is.

Issue 2

I'm unsure if this is intentional but when links are generated they prepended with a '/' which at least on my windows 10 machine with Chrome makes it want to resolve to absolute file path. EX
@See StripeRestServiceTest

Becomes
<a href="/Misc/StripeRESTServiceTest.md">StripeRESTServiceTest</a>

Which my browser then interprets as
file:///C:/Misc/StripeRESTServiceTest.md

When the actual path would be
file:///C:/Users/Kenji/Documents/SFDX%20Projects/ClientName/ApexDoc/docs/markdown/Misc/StripeRESTServiceTest.md

Maybe adding a flag to the command to either include or exclude that beginning slash? I know system file paths get weird and different OS handle them differently and probably even different browsers so I'm not sure if there is a one size fits all fix there but just thought you should know.

"Miscellaneous" vs "Misc"

Hi,
In the apexdocs/README.md, under the configuration section for "defaultGroupName", it says:

defaultGroupName

Default: Miscellaneous

Defines the @group name to be used when a file does not specify it.

The generated output directories seems to actually be labelled "Misc" - not "Miscellaneous".

I notice in your source file: class-file-generatorHelper.ts , that is shows
return groupAnnotation?.body ?? 'Misc';

We had previously received result files in a sub-directory "Miscellaneous". Should we update to "Misc" or is this a bug?

Thanks!

{@link ... } at the start of the comment line is showing as error

When I have the following ApexDoc, I get the error below if the {@link ... } is at the start of the comment:

/**
 * A formatter which formats phone numbers as they are entered.
 *
 * <p>An AsYouTypeFormatter can be created by invoking
 * {@link PhoneNumberUtil#getAsYouTypeFormatter}. After that, digits can be added by invoking
 * {@link #inputDigit} on the formatter instance, and the partially formatted phone number will be
 * returned each time a digit is added. {@link #clear} can be invoked before formatting a new
 * number.
 *
 */
 2/18/2023, 2:57:45 AM: AsYouTypeFormatter - Doc comment parsing error. Level: Type
 2/18/2023, 2:57:45 AM: Comment:
 /**
 * A formatter which formats phone numbers as they are entered.
 *
 * <p>An AsYouTypeFormatter can be created by invoking
 * {@link PhoneNumberUtil#getAsYouTypeFormatter}. After that, digits can be added by invoking
 * {@link #inputDigit} on the formatter instance, and the partially formatted phone number will be
 * returned each time a digit is added. {@link #clear} can be invoked before formatting a new
 * number.
 *
 */
 2/18/2023, 2:57:45 AM: Exception: Error parsing Apex doc. Line 5:3 - mismatched input '{@' expecting {NEWLINE, SPACE, JAVADOC_END}
 2/18/2023, 2:57:45 AM: =================================

But if I add anything else before the {@link ... }, then the error disappears:

/**
 * A formatter which formats phone numbers as they are entered.
 *
 * <p>An AsYouTypeFormatter can be created by invoking
 * test {@link PhoneNumberUtil#getAsYouTypeFormatter}. After that, digits can be added by invoking
 * test {@link #inputDigit} on the formatter instance, and the partially formatted phone number will be
 * returned each time a digit is added. {@link #clear} can be invoked before formatting a new
 * number.
 *
 */

Sort Class methods alphabetically

Is there a way to sort all the methods in an apex class alphabetically? This would be useful in some of the classes that have methods that are not alphabetical in the code itself.

Document class without a class modifier

Thanks for fixing the other issues like a super human 💯
I noticed that the tool does not create Markdown files for classes without access modifier.
Example:

@istest
class TestObjectFactory { ... }

Return types using angle bracket notation - List<String>, Map<String, String>, etc

Any return type, parameter type, etc, that uses angle bracket notations causes issues with the output, especially when the output is not in a code block as this will get picked up by most Markdown parsers as HTML instead and effectively render nothing.

It also causes issues if plugging this into other rendering systems that accept MDX.

If not within a code block, &gt; and &lt; can be used as an escape

Don't parse escaped annotations within comments on methods and variables

Hi @cesarParra this issue is a follow up on #88. I just realized that while you deployed a fix for escaped annotations within class-level comments, the issue persists on method/variable comments.

For example, generating doc for the following code:

/**
 * @description Demonstrates the `@future` syntax and usage
 * @group Async Apex Recipes
 */
public with sharing class AtFutureRecipes {
    /**
     * This class features a 'circuit breaker' variable. While this is not a
     * pattern I routinely turn to, it is a valuable pattern for testing code
     * that is otherwise hard to test. For instance, `@future` methods must be
     * static void methods...
     */
    @testVisible
    private static Boolean testCircuitBreaker = false;
}

will crash with this error:

10/4/2023, 4:25:35 PM: AtFutureRecipes - Doc comment parsing error. Level: Field
10/4/2023, 4:25:35 PM: Comment:
 /**
   * This class features a 'circuit breaker' variable. While this is not a
   * pattern I routinely turn to, it is a valuable pattern for testing code
   * that is otherwise hard to test. For instance, `@future` methods must be
   * static void methods...
   */
10/4/2023, 4:25:35 PM: Exception: Error parsing Apex doc. Line 4:53 - mismatched input '`@future`' expecting {NAME, NEWLINE, SPACE, TEXT_CONTENT, '*', '/', JAVADOC_END, '{@', '{', '}'}

Option to not include Apex file meta information

Hi,
Thanks for creating this CLI, it helps a lot. However, I have a suggestion about what's being printed in the .md file for an Apex class.
Doesn't matter what options and generators I use, I always get ApexClass meta information in the final markdown file. I don't really see much sense in printing this information as I've never seen in that somebody would expose and not delete an Apex class with Status: Inactive. ApexClass API version is a bit more important but again, most of the time it's not required for a user to know the exact API version.

So, would it be possible to have at least a CLI option to disable that ApexClass meta information to be printed?

What I'm running:

npx apexdocs-generate -s ./src/main -t ./docs -p global -g docsify --defaultGroupName Classes

Example source file:

/**
 * @description Some description
 */
global abstract class Service implements IService {}

Expected result .md file:

# Service

Some description


**Implemented types**

[IService](/Interfaces/IService.md)

Actual result .md file:

# Service

`APIVERSION: 55`

`STATUS: ACTIVE`

Some description


**Implemented types**

[IService](/Interfaces/IService.md)

Apply code formatting to output parameter type documentation

When generating documentation for our code it would be nice to apply code formatting to the output type of a method:
Screenshot 2023-10-06 at 15 32 27

PS: ignore the description part that starts with the code formatted String. I'll need to fix my description.

I really appreciate all of your hard work and mention that there's no need to rush a fix for this and to release a version immediately, this can definitely wait.

Open API generation issue - tags not honoring slashes

When generating an open-API specification with a URL with v1/items, the generated tag does not include slashes. It generates v1items. Below is a snippet of the open-API specification file

   "v1/items/": {
      "get": {
        "tags": ["Vitems"],
....

Param parsing on multiple lines

First,

Let me say GREAT work. I love this.

I've discovered an issue where it's unable to properly determine parameters when they are on multiple lines. This causes issues with the default prettier config that forces param lists to wrap to one-per-line if the overall line exceeds 80 characters.

Example code to reproduce:

    /**
     * @description - This method is where the actual work occurs. It's run once per batch.
     * @param context - dependency injected by the system
     * @param scope - a list of up to 200 SObject records to be processed
     *   in this batch. It's this mechanism of breaking a large number of records
     *   into smaller batches called scope (in this example) that make this easier
     **/
    public void execute(
        Database.BatchableContext context,
        List<Account> scope
    ) { }

This generates the following markdown:

---
## Methods
### `)` → ``

- This method is where the actual work occurs. It's run once per batch.
#### Parameters
|Param|Description|
|-----|-----------|
|`context` |  - dependency injected by the system |
|`scope` |  - a list of up to 200 SObject records to be processed |

Specifically, the issue is here:

### `)` → ``

Feature Request: Better Class-level descriptions with Markdown

I'd like to have some longer form explanatory text at the top of my class files. With the recent addition of HTML support, this is (mostly) possible, but I'd prefer to use markdown. Markdown largely already works in apexdocs, but @description treats all content as one long unformatted span (unless you add html tags). Here's a (shortened) example of a class header I'd like to use. Note that I could use <p>, <ul>, and <li> tags for the beginning, but I still can't do a code block.

/**********************************************************
@class          TriggerService
@testClass      TriggerService_Test
@group          core-utils
@description    Simple Trigger Framework, integrated with <<CodeControl>>.

To use TriggerService for a given trigger,
1.  Build a trigger handler class that extends <<TriggerHelperBase>>, implementing any trigger stages (e.g., beforeInsert, afterUpdate, etc)
    needed by your trigger.
2.  In the trigger, call `TriggerService.run()`, passing a new instance of your handler.

```
// TriggerHandler
public class AccountHandler extends TriggerHelperBase {
    public override void afterInsert(List<SObject> newList) {
        // ... do trigger things
    }
}

// Trigger
trigger AccountTrigger on Account (after insert) {
    TriggerService.run(new AccountHandler());
}
```
@author         Jason Clark
@date           1/15/22
***********************************************************/

What I'd like is a way to specify the description is a block, and pass any standard markdown. Maybe @description-block and @end-block tags?

Access Modifiers is missing in the output

I really like a lot this tool. So great what you have been doing.

How do you add the method access modifier (global, private, public) to the md file? Seems to be missing for me in the generated output.

apexdocs-generate -s force-app -t docs -r --scope global public private -g docsify --includeMetadata

image

Improve descriptions when using grouping

Taken from #45 (comment). See that issue for more details

On @start-group/@end-group:

This works fine:

// @start-group Special Metadata Names
public static final String WILDCARD_SOURCE = 'CodeControl_Default';
public static final String SYSTEM_WIDE_SOURCE = 'CodeControl_Override';
// @end-group

And produces:

Special Metadata Names

  • SYSTEM_WIDE_SOURCEString
  • WILDCARD_SOURCEString

BUT, changing // @START-Group ... to /** start-group ... */ does not:

/** @start-group Special Metadata Names */
public static final String WILDCARD_SOURCE = 'CodeControl_Default';
public static final String SYSTEM_WIDE_SOURCE = 'CodeControl_Override';
/** @end-group */

That produces:

Other

  • SYSTEM_WIDE_SOURCEString
  • WILDCARD_SOURCEString

Which is probably okay, but since all other directives work with the Javadoc prefix (/**) it is a bit of an exception.

Also @description does not work with either the constants or the group. For example:

// @start-group Special Metadata Names
/** @description Wildcard and Override Settings are only used for Logging and Trigger control.*/
public static final String WILDCARD_SOURCE = 'CodeControl_Default';
public static final String SYSTEM_WIDE_SOURCE = 'CodeControl_Override';
// @end-group

I suppose you could read that @description as either describing the group (which I'd prefer) or WILDCARD_SOURCE, but either way, it did not appear in the output. I tried several variations of comment styles and locations without success. My suggestion is to support two types of description - A description in the same comment block as @START-Group is a group-level description, and a standalone comment is a property-level description

/** @start-group Special Metadata Names
 *  @description Wildcard and Override Settings are only used for Logging and Trigger control.
 */

/** @description Overrides all metadata */
public static final String WILDCARD_SOURCE = 'CodeControl_Default';
/** @description Used if no matching metadata found */
public static final String SYSTEM_WIDE_SOURCE = 'CodeControl_Override';
/** @end-group */

would produce:

Special Metadata Names

Wildcard and Override Settings are only used for Logging and Trigger control.

Overrides all metadata

  • SYSTEM_WIDE_SOURCEString
    Used if no matching metadata found
  • WILDCARD_SOURCEString

Or even better, allow in-line comments to appear in-line in the output:

/** @start-group Special Metadata Names
 *  @description Wildcard and Override Settings are only used for Logging and Trigger control.
 */

public static final String WILDCARD_SOURCE = 'CodeControl_Default'; /** @description Overrides all metadata */
public static final String SYSTEM_WIDE_SOURCE = 'CodeControl_Override'; /** @description Used if no matching metadata found */
/** @end-group */

Producing:

Special Metadata Names

Wildcard and Override Settings are only used for Logging and Trigger control.

  • SYSTEM_WIDE_SOURCEString : Overrides all metadata
  • WILDCARD_SOURCEString : Used if no matching metadata found

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.