diff --git a/README.md b/README.md
index dd96e039..24c27518 100644
--- a/README.md
+++ b/README.md
@@ -115,7 +115,8 @@ apexdocs changelog --previousVersionDir force-app-previous --currentVersionDir f
|----------------------------|-------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------|----------|
| `--sourceDir` | `-s` | The directory where the source files are located. | N/A | Yes |
| `--targetDir` | `-t` | The directory where the generated files will be placed. | `docs` | No |
-| `--scope` | `-p` | A list of scopes to document. Values should be separated by a space, e.g --scope global public namespaceaccessible. | `global` | No |
+| `--scope` | `-p` | A list of scopes to document. Values should be separated by a space, e.g --scope global public namespaceaccessible. | `[global]` | No |
+| `--customObjectVisibility` | `-v` | Controls which custom objects are documented. Values should be separated by a space. | `[public]` | No |
| `--defaultGroupName` | N/A | The default group name to use when a group is not specified. | `Miscellaneous` | No |
| `--namespace` | N/A | The package namespace, if any. If provided, it will be added to the generated files. | N/A | No |
| `--sortAlphabetically` | N/A | Sorts files appearing in the Reference Guide alphabetically, as well as the members of a class, interface or enum alphabetically. If false, the members will be displayed in the same order as the code. | `false` | No |
@@ -184,14 +185,15 @@ apexdocs openapi -s force-app -t docs -n MyNamespace --title "My Custom OpenApi
#### Flags
-| Flag | Alias | Description | Default | Required |
-|------------------------|-------|--------------------------------------------------------------------|-------------|----------|
-| `--previousVersionDir` | `-p` | The directory location of the previous version of the source code. | N/A | Yes |
-| `--currentVersionDir` | `-t` | The directory location of the current version of the source code. | N/A | Yes |
-| `--targetDir` | `-t` | The directory location where the changelog file will be generated. | `./docs/` | No |
-| `--fileName` | N/A | The name of the changelog file to be generated. | `changelog` | No |
-| `--scope` | N/A | The list of scope to respect when generating the changelog. | ['global'] | No |
-| `--skipIfNoChanges` | N/A | Whether to skip generating the changelog if there are no changes. | `true` | No |
+| Flag | Alias | Description | Default | Required |
+|----------------------------|-------|--------------------------------------------------------------------------------------|-------------|----------|
+| `--previousVersionDir` | `-p` | The directory location of the previous version of the source code. | N/A | Yes |
+| `--currentVersionDir` | `-t` | The directory location of the current version of the source code. | N/A | Yes |
+| `--targetDir` | `-t` | The directory location where the changelog file will be generated. | `./docs/` | No |
+| `--fileName` | N/A | The name of the changelog file to be generated. | `changelog` | No |
+| `--scope` | N/A | The list of scope to respect when generating the changelog. | ['global'] | No |
+| `--customObjectVisibility` | `-v` | Controls which custom objects are documented. Values should be separated by a space. | ['public'] | No |
+| `--skipIfNoChanges` | N/A | Whether to skip generating the changelog if there are no changes. | `true` | No |
#### Sample Usage
diff --git a/examples/changelog/docs/changelog.md b/examples/changelog/docs/changelog.md
index b567be19..362fafba 100644
--- a/examples/changelog/docs/changelog.md
+++ b/examples/changelog/docs/changelog.md
@@ -51,7 +51,7 @@ These members have been added or modified.
- New Method: newMethod
- Removed Method: deprecatedMethod
-## New or Removed Fields in Existing Objects
+## New or Removed Fields to Custom Objects or Standard Objects
These custom fields have been added or removed.
@@ -66,4 +66,8 @@ These custom fields have been added or removed.
### Product__c
-- New Field: Description__c
\ No newline at end of file
+- New Field: Description__c
+
+### Contact
+
+- New Field: PhotoUrl__c
\ No newline at end of file
diff --git a/examples/markdown/docs/custom-objects/Event__c.md b/examples/markdown/docs/custom-objects/Event__c.md
index 111bcb28..023f2a04 100644
--- a/examples/markdown/docs/custom-objects/Event__c.md
+++ b/examples/markdown/docs/custom-objects/Event__c.md
@@ -18,6 +18,7 @@ Represents an event that people can register for.
---
### End Date
+**Required**
**API Name**
@@ -29,6 +30,7 @@ Represents an event that people can register for.
---
### Location
+**Required**
**API Name**
@@ -40,6 +42,7 @@ Represents an event that people can register for.
---
### Start Date
+**Required**
**API Name**
diff --git a/examples/markdown/docs/custom-objects/Price_Component__c.md b/examples/markdown/docs/custom-objects/Price_Component__c.md
index e2305371..e86e2002 100644
--- a/examples/markdown/docs/custom-objects/Price_Component__c.md
+++ b/examples/markdown/docs/custom-objects/Price_Component__c.md
@@ -55,6 +55,7 @@ Use this when the Price Component represents a Flat Price. To represent a Percen
---
### Type
+**Required**
**API Name**
@@ -62,4 +63,9 @@ Use this when the Price Component represents a Flat Price. To represent a Percen
**Type**
-*Picklist*
\ No newline at end of file
+*Picklist*
+
+#### Possible values are
+* List Price
+* Surcharge
+* Discount
\ No newline at end of file
diff --git a/examples/markdown/docs/custom-objects/Product__c.md b/examples/markdown/docs/custom-objects/Product__c.md
index 795d2ee1..95bfa4c6 100644
--- a/examples/markdown/docs/custom-objects/Product__c.md
+++ b/examples/markdown/docs/custom-objects/Product__c.md
@@ -18,6 +18,7 @@ Product that is sold or available for sale.
---
### Event
+**Required**
**API Name**
diff --git a/examples/markdown/docs/custom-objects/Sales_Order_Line__c.md b/examples/markdown/docs/custom-objects/Sales_Order_Line__c.md
index da0fb5bf..d99afa40 100644
--- a/examples/markdown/docs/custom-objects/Sales_Order_Line__c.md
+++ b/examples/markdown/docs/custom-objects/Sales_Order_Line__c.md
@@ -7,6 +7,7 @@ Represents a line item on a sales order.
## Fields
### Amount
+**Required**
**API Name**
@@ -18,6 +19,7 @@ Represents a line item on a sales order.
---
### Product
+**Required**
**API Name**
@@ -51,6 +53,7 @@ Represents a line item on a sales order.
---
### Type
+**Required**
**API Name**
@@ -58,4 +61,8 @@ Represents a line item on a sales order.
**Type**
-*Picklist*
\ No newline at end of file
+*Picklist*
+
+#### Possible values are
+* Charge
+* Discount
\ No newline at end of file
diff --git a/examples/open-api/docs/openapi.json b/examples/open-api/docs/openapi.json
index 2bec9b4e..f2e60a56 100644
--- a/examples/open-api/docs/openapi.json
+++ b/examples/open-api/docs/openapi.json
@@ -9,6 +9,574 @@
"url": "/services/apexrest/openapi/"
}
],
- "paths": {},
- "tags": []
+ "paths": {
+ "/AccountService/": {
+ "description": "Account related operations",
+ "get": {
+ "tags": [
+ "Account Service"
+ ],
+ "description": "This is a sample HTTP Get method",
+ "parameters": [
+ {
+ "name": "limit",
+ "in": "query",
+ "required": true,
+ "description": "Limits the number of items on a page",
+ "schema": {
+ "type": "integer"
+ }
+ },
+ {
+ "name": "complex",
+ "in": "cookie",
+ "description": "A more complex schema",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ ],
+ "responses": {
+ "100": {
+ "description": "Status code 100",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "anotherObject": {
+ "description": "An object inside of an object",
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string"
+ },
+ "somethingElse": {
+ "type": "number"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "200": {
+ "description": "Status code 200",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "The super Id."
+ },
+ "name": {
+ "type": "string"
+ },
+ "phone": {
+ "type": "string",
+ "format": "byte"
+ }
+ }
+ }
+ }
+ }
+ },
+ "304": {
+ "description": "Status code 304",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "error": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Status code 400",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Status code 500",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Account Service"
+ ],
+ "description": "This is a sample HTTP Post method",
+ "summary": "Posts an Account 2",
+ "requestBody": {
+ "description": "This is an example of a request body",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "required": true
+ },
+ "parameters": [
+ {
+ "name": "limit",
+ "in": "query",
+ "required": true,
+ "description": "Limits the number of items on a page",
+ "schema": {
+ "type": "integer"
+ }
+ },
+ {
+ "name": "complex",
+ "in": "cookie",
+ "description": "A more complex schema",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Status code 200",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "The super Id."
+ },
+ "name": {
+ "type": "string"
+ },
+ "phone": {
+ "type": "string",
+ "format": "byte"
+ }
+ }
+ }
+ }
+ }
+ },
+ "304": {
+ "description": "Status code 304",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "error": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Status code 400",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Status code 500",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Account Service"
+ ],
+ "description": "Sample HTTP Delete method with references to other types.",
+ "parameters": [
+ {
+ "name": "limit",
+ "in": "header",
+ "required": true,
+ "description": "My sample description.",
+ "schema": {
+ "$ref": "#/components/schemas/SampleClass"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Status code 200",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/SampleClass"
+ }
+ }
+ }
+ },
+ "304": {
+ "description": "Status code 304",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ChildClass"
+ }
+ }
+ }
+ },
+ "305": {
+ "description": "Status code 305",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Reference1"
+ }
+ }
+ }
+ },
+ "306": {
+ "description": "Status code 306",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Reference1_array"
+ }
+ }
+ }
+ },
+ "307": {
+ "description": "Status code 307",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Reference7_Reference7[untypedObject:Reference2]"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Status code 500",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/SampleClass"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/Contact/": {
+ "description": "Contact related operations",
+ "get": {
+ "tags": [
+ "Contact"
+ ],
+ "description": "This is a sample HTTP Get method",
+ "responses": {
+ "200": {
+ "description": "Status code 200",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/SampleRestResourceWithInnerClass.InnerClass"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/Order/": {
+ "description": "Order related operations",
+ "get": {
+ "tags": [
+ "Order"
+ ],
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "param1": {
+ "type": "string"
+ },
+ "param2": {
+ "$ref": "#/components/schemas/Reference1"
+ }
+ }
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Status code 200",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ },
+ "patch": {
+ "tags": [
+ "Order"
+ ],
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "param1": {
+ "type": "string"
+ },
+ "param2": {
+ "$ref": "#/components/schemas/Reference1"
+ }
+ }
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "Status code 200",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ {
+ "name": "Account Service",
+ "description": "Account related operations"
+ },
+ {
+ "name": "Contact",
+ "description": "Contact related operations"
+ },
+ {
+ "name": "Order",
+ "description": "Order related operations"
+ }
+ ],
+ "components": {
+ "schemas": {
+ "SampleClass": {
+ "type": "object",
+ "properties": {
+ "MyProp": {
+ "type": "string",
+ "description": "This is a String property."
+ },
+ "AnotherProp": {
+ "type": "number",
+ "description": "This is a Decimal property."
+ },
+ "listOfStrings": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "someVariable": {
+ "type": "string"
+ },
+ "somePrivateStuff": {
+ "type": "string"
+ }
+ }
+ },
+ "ChildClass": {
+ "type": "object",
+ "properties": {
+ "privateStringFromChild": {
+ "type": "string"
+ },
+ "aPrivateString": {
+ "type": "string"
+ }
+ }
+ },
+ "Reference1": {
+ "type": "object",
+ "properties": {
+ "reference2Member": {
+ "$ref": "#/components/schemas/Reference2",
+ "description": "This is a reference 2 member. Lorem."
+ },
+ "reference3Member": {
+ "$ref": "#/components/schemas/Reference3"
+ },
+ "reference4Collection": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Reference4"
+ }
+ },
+ "reference5Member": {
+ "$ref": "#/components/schemas/Reference5"
+ }
+ }
+ },
+ "Reference2": {
+ "type": "object",
+ "properties": {
+ "stringMember": {
+ "type": "string"
+ },
+ "objectReference": {
+ "$ref": "#/components/schemas/Reference3_array",
+ "description": "This is an object reference."
+ }
+ }
+ },
+ "Reference3_array": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Reference3"
+ }
+ },
+ "Reference3": {
+ "type": "object",
+ "properties": {
+ "someBoolean": {
+ "type": "boolean"
+ }
+ }
+ },
+ "Reference4": {
+ "type": "object",
+ "properties": {
+ "someString": {
+ "type": "string"
+ }
+ }
+ },
+ "Reference5": {
+ "type": "object",
+ "properties": {
+ "reference6Member": {
+ "$ref": "#/components/schemas/Reference6"
+ }
+ }
+ },
+ "Reference6": {
+ "type": "object",
+ "properties": {
+ "grandChildString": {
+ "type": "string",
+ "description": "This is the grandchild description."
+ }
+ }
+ },
+ "Reference1_array": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Reference1"
+ }
+ },
+ "Reference7_Reference7[untypedObject:Reference2]": {
+ "type": "object",
+ "properties": {
+ "untypedObject": {
+ "$ref": "#/components/schemas/Reference2"
+ }
+ }
+ },
+ "SampleRestResourceWithInnerClass.InnerClass": {
+ "type": "object",
+ "properties": {
+ "stringMember": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/examples/vitepress/docs/.vitepress/cache/deps/_metadata.json b/examples/vitepress/docs/.vitepress/cache/deps/_metadata.json
index e710f560..3a5d46ac 100644
--- a/examples/vitepress/docs/.vitepress/cache/deps/_metadata.json
+++ b/examples/vitepress/docs/.vitepress/cache/deps/_metadata.json
@@ -1,31 +1,31 @@
{
- "hash": "05eb2d4f",
+ "hash": "38118198",
"configHash": "7f7b0dad",
- "lockfileHash": "3a9c2374",
- "browserHash": "a831d6e7",
+ "lockfileHash": "09651dfc",
+ "browserHash": "1bd3b4f7",
"optimized": {
"vue": {
"src": "../../../../node_modules/vue/dist/vue.runtime.esm-bundler.js",
"file": "vue.js",
- "fileHash": "1632d62a",
+ "fileHash": "12c2c40e",
"needsInterop": false
},
"vitepress > @vue/devtools-api": {
"src": "../../../../node_modules/@vue/devtools-api/dist/index.js",
"file": "vitepress___@vue_devtools-api.js",
- "fileHash": "dc8fec00",
+ "fileHash": "7b21a64c",
"needsInterop": false
},
"vitepress > @vueuse/core": {
"src": "../../../../node_modules/@vueuse/core/index.mjs",
"file": "vitepress___@vueuse_core.js",
- "fileHash": "3d02446b",
+ "fileHash": "5d565a7a",
"needsInterop": false
},
"@theme/index": {
"src": "../../../../node_modules/vitepress/dist/client/theme-default/index.js",
"file": "@theme_index.js",
- "fileHash": "3d2d1de3",
+ "fileHash": "e4373905",
"needsInterop": false
}
},
diff --git a/examples/vitepress/docs/.vitepress/sidebar.json b/examples/vitepress/docs/.vitepress/sidebar.json
index 0fc24fcc..30ad720e 100644
--- a/examples/vitepress/docs/.vitepress/sidebar.json
+++ b/examples/vitepress/docs/.vitepress/sidebar.json
@@ -90,6 +90,14 @@
"text": "Sales_Order_Line__c",
"link": "custom-objects/Sales_Order_Line__c.md"
},
+ {
+ "text": "Sample_Custom_Setting__c",
+ "link": "custom-objects/Sample_Custom_Setting__c.md"
+ },
+ {
+ "text": "Sample_Platform_Event__e",
+ "link": "custom-objects/Sample_Platform_Event__e.md"
+ },
{
"text": "Speaker__c",
"link": "custom-objects/Speaker__c.md"
diff --git a/examples/vitepress/docs/changelog.md b/examples/vitepress/docs/changelog.md
index 915a7aae..e3eb7b3f 100644
--- a/examples/vitepress/docs/changelog.md
+++ b/examples/vitepress/docs/changelog.md
@@ -69,6 +69,11 @@ Represents a line item on a sales order.
### Sales_Order__c
Custom object for tracking sales orders.
+### Sample_Custom_Setting__c
+
+### Sample_Platform_Event__e
+
+Eu excepteur irure occaecat adipisicing anim non consequat deserunt ipsum id amet eu. Labore aliqua incididunt anim id in aliquip sit excepteur ad dolor irure incididunt. Ipsum eiusmod cillum ex ullamco minim eu nisi dolore ad velit consequat ullamco elit tempor. Occaecat aliquip ex mollit nostrud qui excepteur non commodo dolore ullamco ex voluptate ut. Culpa nostrud reprehenderit ipsum do. Sit deserunt sint occaecat duis eiusmod. Sunt laborum fugiat nulla.
### Speaker__c
Represents a speaker at an event.
diff --git a/examples/vitepress/docs/custom-objects/Sample_Custom_Setting__c.md b/examples/vitepress/docs/custom-objects/Sample_Custom_Setting__c.md
new file mode 100644
index 00000000..0e04ceba
--- /dev/null
+++ b/examples/vitepress/docs/custom-objects/Sample_Custom_Setting__c.md
@@ -0,0 +1,19 @@
+---
+title: Sample_Custom_Setting__c
+---
+
+# Sample Custom Setting
+
+## API Name
+`apexdocs__Sample_Custom_Setting__c`
+
+## Fields
+### Sample Setting Field
+
+**API Name**
+
+`apexdocs__Sample_Setting_Field__c`
+
+**Type**
+
+*Text*
\ No newline at end of file
diff --git a/examples/vitepress/docs/custom-objects/Sample_Platform_Event__e.md b/examples/vitepress/docs/custom-objects/Sample_Platform_Event__e.md
new file mode 100644
index 00000000..9191325d
--- /dev/null
+++ b/examples/vitepress/docs/custom-objects/Sample_Platform_Event__e.md
@@ -0,0 +1,37 @@
+---
+title: Sample_Platform_Event__e
+---
+
+# Sample Platform Event
+
+Eu excepteur irure occaecat adipisicing anim non consequat deserunt ipsum id amet eu. Labore aliqua incididunt anim id in aliquip sit excepteur ad dolor irure incididunt. Ipsum eiusmod cillum ex ullamco minim eu nisi dolore ad velit consequat ullamco elit tempor. Occaecat aliquip ex mollit nostrud qui excepteur non commodo dolore ullamco ex voluptate ut. Culpa nostrud reprehenderit ipsum do. Sit deserunt sint occaecat duis eiusmod. Sunt laborum fugiat nulla.
+
+## API Name
+`Sample_Platform_Event__e`
+
+## Publish Behavior
+
+**Publish Immediately**
+
+## Fields
+### Required Platform Event Field
+**Required**
+
+**API Name**
+
+`apexdocs__Required_Platform_Event_Field__c`
+
+**Type**
+
+*Date*
+
+---
+### Sample Platform Event Field
+
+**API Name**
+
+`apexdocs__Sample_Platform_Event_Field__c`
+
+**Type**
+
+*Text*
\ No newline at end of file
diff --git a/examples/vitepress/docs/index.md b/examples/vitepress/docs/index.md
index ca295921..b126b3b5 100644
--- a/examples/vitepress/docs/index.md
+++ b/examples/vitepress/docs/index.md
@@ -45,6 +45,12 @@ Custom object for tracking sales orders.
Represents a line item on a sales order.
+### [Sample_Custom_Setting__c](custom-objects/Sample_Custom_Setting__c)
+
+### [Sample_Platform_Event__e](custom-objects/Sample_Platform_Event__e)
+
+Eu excepteur irure occaecat adipisicing anim non consequat deserunt ipsum id amet eu. Labore aliqua incididunt anim id in aliquip sit excepteur ad dolor irure incididunt. Ipsum eiusmod cillum ex ullamco minim eu nisi dolore ad velit consequat ullamco elit tempor. Occaecat aliquip ex mollit nostrud qui excepteur non commodo dolore ullamco ex voluptate ut. Culpa nostrud reprehenderit ipsum do. Sit deserunt sint occaecat duis eiusmod. Sunt laborum fugiat nulla.
+
### [Speaker__c](custom-objects/Speaker__c)
Represents a speaker at an event.
diff --git a/examples/vitepress/force-app/main/default/objects/Sample_Custom_Setting__c/Sample_Custom_Setting__c.object-meta.xml b/examples/vitepress/force-app/main/default/objects/Sample_Custom_Setting__c/Sample_Custom_Setting__c.object-meta.xml
new file mode 100644
index 00000000..7fecae4e
--- /dev/null
+++ b/examples/vitepress/force-app/main/default/objects/Sample_Custom_Setting__c/Sample_Custom_Setting__c.object-meta.xml
@@ -0,0 +1,7 @@
+
+
+ Hierarchy
+ false
+
+ Public
+
diff --git a/examples/vitepress/force-app/main/default/objects/Sample_Custom_Setting__c/fields/Sample_Setting_Field__c.field-meta.xml b/examples/vitepress/force-app/main/default/objects/Sample_Custom_Setting__c/fields/Sample_Setting_Field__c.field-meta.xml
new file mode 100644
index 00000000..3eb89ad0
--- /dev/null
+++ b/examples/vitepress/force-app/main/default/objects/Sample_Custom_Setting__c/fields/Sample_Setting_Field__c.field-meta.xml
@@ -0,0 +1,11 @@
+
+
+ Sample_Setting_Field__c
+ false
+
+ 255
+ false
+ false
+ Text
+ false
+
diff --git a/examples/vitepress/force-app/main/default/objects/Sample_Platform_Event__e/Sample_Platform_Event__e.object-meta.xml b/examples/vitepress/force-app/main/default/objects/Sample_Platform_Event__e/Sample_Platform_Event__e.object-meta.xml
new file mode 100644
index 00000000..b4725341
--- /dev/null
+++ b/examples/vitepress/force-app/main/default/objects/Sample_Platform_Event__e/Sample_Platform_Event__e.object-meta.xml
@@ -0,0 +1,9 @@
+
+
+ Deployed
+ Eu excepteur irure occaecat adipisicing anim non consequat deserunt ipsum id amet eu. Labore aliqua incididunt anim id in aliquip sit excepteur ad dolor irure incididunt. Ipsum eiusmod cillum ex ullamco minim eu nisi dolore ad velit consequat ullamco elit tempor. Occaecat aliquip ex mollit nostrud qui excepteur non commodo dolore ullamco ex voluptate ut. Culpa nostrud reprehenderit ipsum do. Sit deserunt sint occaecat duis eiusmod. Sunt laborum fugiat nulla.
+ HighVolume
+
+ Sample Platform Events
+ PublishImmediately
+
diff --git a/examples/vitepress/force-app/main/default/objects/Sample_Platform_Event__e/fields/Required_Platform_Event_Field__c.field-meta.xml b/examples/vitepress/force-app/main/default/objects/Sample_Platform_Event__e/fields/Required_Platform_Event_Field__c.field-meta.xml
new file mode 100644
index 00000000..d3d1847d
--- /dev/null
+++ b/examples/vitepress/force-app/main/default/objects/Sample_Platform_Event__e/fields/Required_Platform_Event_Field__c.field-meta.xml
@@ -0,0 +1,11 @@
+
+
+ Required_Platform_Event_Field__c
+ false
+ false
+ false
+ false
+
+ true
+ Date
+
diff --git a/examples/vitepress/force-app/main/default/objects/Sample_Platform_Event__e/fields/Sample_Platform_Event_Field__c.field-meta.xml b/examples/vitepress/force-app/main/default/objects/Sample_Platform_Event__e/fields/Sample_Platform_Event_Field__c.field-meta.xml
new file mode 100644
index 00000000..04a0ad1d
--- /dev/null
+++ b/examples/vitepress/force-app/main/default/objects/Sample_Platform_Event__e/fields/Sample_Platform_Event_Field__c.field-meta.xml
@@ -0,0 +1,13 @@
+
+
+ Sample_Platform_Event_Field__c
+ false
+ false
+ false
+ false
+
+ 255
+ false
+ Text
+ false
+
diff --git a/package.json b/package.json
index 4acf912b..351e69b1 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@cparra/apexdocs",
- "version": "3.8.0",
+ "version": "3.9.0",
"description": "Library with CLI capabilities to generate documentation for Salesforce Apex classes.",
"keywords": [
"apex",
diff --git a/src/cli/commands/changelog.ts b/src/cli/commands/changelog.ts
index 58dcd507..b3ecaafb 100644
--- a/src/cli/commands/changelog.ts
+++ b/src/cli/commands/changelog.ts
@@ -35,6 +35,14 @@ export const changeLogOptions: { [key: string]: Options } = {
'Values should be separated by a space, e.g --scope global public namespaceaccessible. ' +
'Annotations are supported and should be passed lowercased and without the @ symbol, e.g. namespaceaccessible auraenabled.',
},
+ customObjectVisibility: {
+ type: 'string',
+ array: true,
+ alias: 'v',
+ default: changeLogDefaults.customObjectVisibility,
+ choices: ['public', 'protected', 'packageprotected'],
+ describe: 'Controls which custom objects are documented. Values should be separated by a space.',
+ },
skipIfNoChanges: {
type: 'boolean',
default: changeLogDefaults.skipIfNoChanges,
diff --git a/src/cli/commands/markdown.ts b/src/cli/commands/markdown.ts
index e029d3b8..34c50637 100644
--- a/src/cli/commands/markdown.ts
+++ b/src/cli/commands/markdown.ts
@@ -24,6 +24,14 @@ export const markdownOptions: Record {
return pipe(
- reflectCustomFieldsAndObjectsAndMetadataRecords(filterCustomObjectsFieldsAndMetadataRecords(bundles)),
+ reflectCustomFieldsAndObjectsAndMetadataRecords(
+ filterCustomObjectsFieldsAndMetadataRecords(bundles),
+ config.customObjectVisibility,
+ ),
TE.map((parsedObjectFiles) => [...parsedApexFiles, ...parsedObjectFiles]),
);
}),
diff --git a/src/core/markdown/__test__/generating-custom-object-docs.spec.ts b/src/core/markdown/__test__/generating-custom-object-docs.spec.ts
index 572c2901..a9c3b10c 100644
--- a/src/core/markdown/__test__/generating-custom-object-docs.spec.ts
+++ b/src/core/markdown/__test__/generating-custom-object-docs.spec.ts
@@ -6,6 +6,7 @@ import {
unparsedFieldBundleFromRawString,
} from '../../test-helpers/test-data-builders';
import { CustomObjectXmlBuilder } from '../../test-helpers/test-data-builders/custom-object-xml-builder';
+import { PlatformEventXmlBuilder } from '../../test-helpers/test-data-builders/platform-event-xml-builder';
describe('Generates Custom Object documentation', () => {
beforeAll(() => {
@@ -207,5 +208,29 @@ describe('Generates Custom Object documentation', () => {
assertEither(result, (data) => expect(data).firstDocContains('TestObject.TestField__c'));
});
});
+
+ describe('when documenting Platform Events', () => {
+ test('displays the publish behavior (publish immediately)', async () => {
+ const customObjectBundle = unparsedObjectBundleFromRawString({
+ rawContent: new PlatformEventXmlBuilder().build(),
+ filePath: 'src/object/TestObject__e.object-meta.xml',
+ });
+
+ const result = await generateDocs([customObjectBundle])();
+ expect(result).documentationBundleHasLength(1);
+ assertEither(result, (data) => expect(data).firstDocContains('Publish Immediately'));
+ });
+
+ test('displays the publish behavior (publish after commit)', async () => {
+ const customObjectBundle = unparsedObjectBundleFromRawString({
+ rawContent: new PlatformEventXmlBuilder().withPublishBehavior('PublishAfterCommit').build(),
+ filePath: 'src/object/TestObject__e.object-meta.xml',
+ });
+
+ const result = await generateDocs([customObjectBundle])();
+ expect(result).documentationBundleHasLength(1);
+ assertEither(result, (data) => expect(data).firstDocContains('Publish After Commit'));
+ });
+ });
});
});
diff --git a/src/core/markdown/__test__/generating-docs.spec.ts b/src/core/markdown/__test__/generating-docs.spec.ts
index bce18c9e..2ed1df82 100644
--- a/src/core/markdown/__test__/generating-docs.spec.ts
+++ b/src/core/markdown/__test__/generating-docs.spec.ts
@@ -160,11 +160,25 @@ describe('When generating documentation', () => {
expect(result).documentationBundleHasLength(0);
});
- it('does not return non-public custom objects', async () => {
- const input = new CustomObjectXmlBuilder().withVisibility('Protected').build();
-
- const result = await generateDocs([unparsedObjectBundleFromRawString({ rawContent: input, filePath: 'test' })])();
- expect(result).documentationBundleHasLength(0);
+ describe('and the custom object visibility', () => {
+ it('is not set, it does not return non-public custom objects', async () => {
+ const input = new CustomObjectXmlBuilder().withVisibility('Protected').build();
+
+ const result = await generateDocs([
+ unparsedObjectBundleFromRawString({ rawContent: input, filePath: 'test' }),
+ ])();
+ expect(result).documentationBundleHasLength(0);
+ });
+
+ it('is configured, it respects the configured visibility', async () => {
+ const input = new CustomObjectXmlBuilder().withVisibility('Protected').build();
+
+ const result = await generateDocs(
+ [unparsedObjectBundleFromRawString({ rawContent: input, filePath: 'test' })],
+ { customObjectVisibility: ['protected'] },
+ )();
+ expect(result).documentationBundleHasLength(1);
+ });
});
it('do not return files that have an @ignore in the docs', async () => {
diff --git a/src/core/markdown/__test__/test-helpers.ts b/src/core/markdown/__test__/test-helpers.ts
index 0ed98827..e71b998c 100644
--- a/src/core/markdown/__test__/test-helpers.ts
+++ b/src/core/markdown/__test__/test-helpers.ts
@@ -29,6 +29,7 @@ export function generateDocs(bundles: UnparsedSourceBundle[], config?: Partial customMetadataToRenderable(metadata, 3)),
},
+ publishBehavior: toRenderablePublishBehavior(objectMetadata.publishBehavior),
};
}
diff --git a/src/core/markdown/generate-docs.ts b/src/core/markdown/generate-docs.ts
index ef7f6e42..dc16aa5e 100644
--- a/src/core/markdown/generate-docs.ts
+++ b/src/core/markdown/generate-docs.ts
@@ -63,7 +63,10 @@ export function generateDocs(unparsedBundles: UnparsedSourceBundle[], config: Ma
generateForApex(filterApexSourceFiles(unparsedBundles), config),
TE.chain((parsedApexFiles) => {
return pipe(
- reflectCustomFieldsAndObjectsAndMetadataRecords(filterCustomObjectsFieldsAndMetadataRecords(unparsedBundles)),
+ reflectCustomFieldsAndObjectsAndMetadataRecords(
+ filterCustomObjectsFieldsAndMetadataRecords(unparsedBundles),
+ config.customObjectVisibility,
+ ),
TE.map((parsedObjectFiles) => [...parsedApexFiles, ...parsedObjectFiles]),
);
}),
diff --git a/src/core/markdown/templates/custom-object-template.ts b/src/core/markdown/templates/custom-object-template.ts
index f33022fd..e427230e 100644
--- a/src/core/markdown/templates/custom-object-template.ts
+++ b/src/core/markdown/templates/custom-object-template.ts
@@ -6,6 +6,12 @@ export const customObjectTemplate = `
## API Name
\`{{apiName}}\`
+{{#if publishBehavior}}
+## Publish Behavior
+
+**{{publishBehavior}}**
+{{/if}}
+
{{#if hasFields}}
{{ heading fields.headingLevel fields.heading }}
{{#each fields.value}}
diff --git a/src/core/reflection/sobject/reflect-custom-object-sources.ts b/src/core/reflection/sobject/reflect-custom-object-sources.ts
index 5654d6e8..aea2eb53 100644
--- a/src/core/reflection/sobject/reflect-custom-object-sources.ts
+++ b/src/core/reflection/sobject/reflect-custom-object-sources.ts
@@ -11,6 +11,8 @@ import { CustomFieldMetadata } from './reflect-custom-field-source';
import { getPickListValues } from './parse-picklist-values';
import { CustomMetadataMetadata } from './reflect-custom-metadata-source';
+export type PublishBehavior = 'PublishImmediately' | 'PublishAfterCommit';
+
export type CustomObjectMetadata = {
type_name: 'customobject';
deploymentStatus: string;
@@ -20,6 +22,7 @@ export type CustomObjectMetadata = {
description: string | null;
fields: CustomFieldMetadata[];
metadataRecords: CustomMetadataMetadata[];
+ publishBehavior?: PublishBehavior;
};
export function reflectCustomObjectSources(
diff --git a/src/core/reflection/sobject/reflectCustomFieldsAndObjectsAndMetadataRecords.ts b/src/core/reflection/sobject/reflectCustomFieldsAndObjectsAndMetadataRecords.ts
index 157f8354..6bf759a9 100644
--- a/src/core/reflection/sobject/reflectCustomFieldsAndObjectsAndMetadataRecords.ts
+++ b/src/core/reflection/sobject/reflectCustomFieldsAndObjectsAndMetadataRecords.ts
@@ -14,13 +14,26 @@ import { CustomMetadataMetadata, reflectCustomMetadataSources } from './reflect-
export function reflectCustomFieldsAndObjectsAndMetadataRecords(
objectBundles: (UnparsedCustomObjectBundle | UnparsedCustomFieldBundle | UnparsedCustomMetadataBundle)[],
+ visibilitiesToDocument: string[],
): TaskEither[]> {
function filterNonPublished(parsedFiles: ParsedFile[]): ParsedFile[] {
return parsedFiles.filter((parsedFile) => parsedFile.type.deploymentStatus === 'Deployed');
}
- function filterNonPublic(parsedFiles: ParsedFile[]): ParsedFile[] {
- return parsedFiles.filter((parsedFile) => parsedFile.type.visibility === 'Public');
+ /**
+ * Returns a tuple of parsed objects to document and the names of the objects that should be actively ignored.
+ * @param parsedFiles
+ */
+ function filter(parsedFiles: ParsedFile[]): [ParsedFile[], string[]] {
+ function shouldBeDocumented(parsedFile: ParsedFile): boolean {
+ return visibilitiesToDocument.includes(parsedFile.type.visibility.toLowerCase());
+ }
+
+ const objectsToDocument = parsedFiles.filter(shouldBeDocumented);
+ const objectsToIgnore = parsedFiles
+ .filter((parsedFile) => !shouldBeDocumented(parsedFile))
+ .map((parsedFile) => parsedFile.type.name);
+ return [objectsToDocument, objectsToIgnore];
}
const customObjects = objectBundles.filter(
@@ -51,12 +64,12 @@ export function reflectCustomFieldsAndObjectsAndMetadataRecords(
customObjects,
reflectCustomObjectSources,
TE.map(filterNonPublished),
- TE.map(filterNonPublic),
- TE.bindTo('objects'),
+ TE.map(filter),
+ TE.bindTo('filterResult'),
TE.bind('fields', () => generateForFields(customFields)),
TE.bind('metadata', () => generateForMetadata(customMetadata)),
- TE.map(({ objects, fields, metadata }) => {
- return [...mapFieldsAndMetadata(objects, fields, metadata), ...mapExtensionFields(objects, fields)];
+ TE.map(({ filterResult, fields, metadata }) => {
+ return [...mapFieldsAndMetadata(filterResult[0], fields, metadata), ...mapExtensionFields(filterResult, fields)];
}),
);
}
@@ -85,11 +98,16 @@ function mapFieldsAndMetadata(
// "Extension" fields are fields that are in the source code without the corresponding object-meta.xml file.
// These are fields that either extend a standard Salesforce object, or an object in a different package.
function mapExtensionFields(
- objects: ParsedFile[],
+ filterResult: [ParsedFile[], string[]],
fields: ParsedFile[],
): ParsedFile[] {
+ const objects = filterResult[0];
+ const ignoredObjectNames = filterResult[1];
+
const extensionFields = fields.filter(
- (field) => !objects.some((object) => object.type.name === field.type.parentName),
+ (field) =>
+ !objects.some((object) => object.type.name.toLowerCase() === field.type.parentName.toLowerCase()) &&
+ !ignoredObjectNames.map((name) => name.toLowerCase()).includes(field.type.parentName.toLowerCase()),
);
// There might be many objects for the same parent name, so we need to group the fields by parent name
const extensionFieldsByParent = extensionFields.reduce(
diff --git a/src/core/renderables/types.d.ts b/src/core/renderables/types.d.ts
index 5f1bd03a..5df71721 100644
--- a/src/core/renderables/types.d.ts
+++ b/src/core/renderables/types.d.ts
@@ -184,6 +184,7 @@ export type RenderableCustomObject = Omit & {
hasRecords: boolean;
fields: RenderableSection;
metadataRecords: RenderableSection;
+ publishBehavior: string | null;
};
export type RenderableCustomField = {
diff --git a/src/core/shared/types.d.ts b/src/core/shared/types.d.ts
index e2fdff5c..35c6d22b 100644
--- a/src/core/shared/types.d.ts
+++ b/src/core/shared/types.d.ts
@@ -20,6 +20,7 @@ export type CliConfigurableMarkdownConfig = {
sourceDir: string;
targetDir: string;
scope: string[];
+ customObjectVisibility: string[];
namespace?: string;
defaultGroupName: string;
customObjectsGroupName: string;
@@ -54,6 +55,7 @@ export type UserDefinedChangelogConfig = {
targetDir: string;
fileName: string;
scope: string[];
+ customObjectVisibility: string[];
exclude: string[];
skipIfNoChanges: boolean;
} & Partial;
diff --git a/src/core/test-helpers/test-data-builders/platform-event-xml-builder.ts b/src/core/test-helpers/test-data-builders/platform-event-xml-builder.ts
new file mode 100644
index 00000000..f35860f9
--- /dev/null
+++ b/src/core/test-helpers/test-data-builders/platform-event-xml-builder.ts
@@ -0,0 +1,26 @@
+import { PublishBehavior } from '../../reflection/sobject/reflect-custom-object-sources';
+
+export class PlatformEventXmlBuilder {
+ deploymentStatus = 'Deployed';
+ publishBehavior: PublishBehavior = 'PublishImmediately';
+ label = 'MyTestObject';
+
+ withPublishBehavior(publishBehavior: PublishBehavior): PlatformEventXmlBuilder {
+ this.publishBehavior = publishBehavior;
+ return this;
+ }
+
+ build(): string {
+ return `
+
+
+ ${this.deploymentStatus}
+ Eu exceptincididunt anicat aut
+ HighVolume
+
+ Sample Platform Events
+ ${this.publishBehavior}
+
+ `;
+ }
+}
diff --git a/src/defaults.ts b/src/defaults.ts
index 8510cf7a..73f12d68 100644
--- a/src/defaults.ts
+++ b/src/defaults.ts
@@ -2,9 +2,15 @@ const commonDefaults = {
targetDir: './docs/',
};
-export const markdownDefaults = {
+const markdownAndChangelogDefaults = {
...commonDefaults,
scope: ['global'],
+ customObjectVisibility: ['public'],
+ exclude: [],
+};
+
+export const markdownDefaults = {
+ ...markdownAndChangelogDefaults,
defaultGroupName: 'Miscellaneous',
customObjectsGroupName: 'Custom Objects',
includeMetadata: false,
@@ -12,7 +18,6 @@ export const markdownDefaults = {
linkingStrategy: 'relative' as const,
referenceGuideTitle: 'Reference Guide',
excludeTags: [],
- exclude: [],
};
export const openApiDefaults = {
@@ -24,9 +29,7 @@ export const openApiDefaults = {
};
export const changeLogDefaults = {
- ...commonDefaults,
+ ...markdownAndChangelogDefaults,
fileName: 'changelog',
- scope: ['global'],
- exclude: [],
skipIfNoChanges: true,
};