diff --git a/.gitignore b/.gitignore
index 5e8c19d7..4c28f20d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,4 @@ npm-debug.log
/.idea/
/dist/
/lib/
+.sfdx/
diff --git a/examples/vitepress/docs/custom-objects/Price_Component__c.md b/examples/vitepress/docs/custom-objects/Price_Component__c.md
index 053ccb3c..fa4be586 100644
--- a/examples/vitepress/docs/custom-objects/Price_Component__c.md
+++ b/examples/vitepress/docs/custom-objects/Price_Component__c.md
@@ -66,4 +66,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/vitepress/docs/custom-objects/Sales_Order_Line__c.md b/examples/vitepress/docs/custom-objects/Sales_Order_Line__c.md
index 041e94ce..bc1ac4f7 100644
--- a/examples/vitepress/docs/custom-objects/Sales_Order_Line__c.md
+++ b/examples/vitepress/docs/custom-objects/Sales_Order_Line__c.md
@@ -62,4 +62,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/src/core/markdown/__test__/generating-custom-object-docs.spec.ts b/src/core/markdown/__test__/generating-custom-object-docs.spec.ts
index f08d0499..e1af6d39 100644
--- a/src/core/markdown/__test__/generating-custom-object-docs.spec.ts
+++ b/src/core/markdown/__test__/generating-custom-object-docs.spec.ts
@@ -1,6 +1,7 @@
import { extendExpect } from './expect-extensions';
import {
customField,
+ customFieldPickListValues,
customObjectGenerator,
generateDocs,
unparsedFieldBundleFromRawString,
@@ -46,7 +47,7 @@ describe('Generates Custom Object documentation', () => {
expect(result).documentationBundleHasLength(1);
assertEither(result, (data) => expect(data).firstDocContains('`TestObject__c`'));
});
-
+
it('displays the Fields heading if fields are present', async () => {
const customObjectBundle = unparsedObjectBundleFromRawString({
rawContent: customObjectGenerator(),
@@ -64,6 +65,25 @@ describe('Generates Custom Object documentation', () => {
assertEither(result, (data) => expect(data).firstDocContains('## Fields'));
});
+ it('displays the pick list values name', async () => {
+ const customObjectBundle = unparsedObjectBundleFromRawString({
+ rawContent: customObjectGenerator(),
+ filePath: 'src/object/TestObject__c.object-meta.xml',
+ });
+
+ const customFieldBundle = unparsedFieldBundleFromRawString({
+ rawContent: customFieldPickListValues,
+ filePath: 'src/object/TestField__c.field-meta.xml',
+ parentName: 'TestObject__c',
+ });
+
+ const result = await generateDocs([customObjectBundle, customFieldBundle])();
+ expect(result).documentationBundleHasLength(1);
+ assertEither(result, (data) => expect(data).firstDocContains('* Staging'));
+ assertEither(result, (data) => expect(data).firstDocContains('* Active'));
+ assertEither(result, (data) => expect(data).firstDocContains('* Inactive'));
+ });
+
it('does not display the Fields heading if no fields are present', async () => {
const input = unparsedObjectBundleFromRawString({
rawContent: customObjectGenerator(),
diff --git a/src/core/markdown/__test__/test-helpers.ts b/src/core/markdown/__test__/test-helpers.ts
index d884958f..c711414d 100644
--- a/src/core/markdown/__test__/test-helpers.ts
+++ b/src/core/markdown/__test__/test-helpers.ts
@@ -84,3 +84,36 @@ export const customField = `
Url
A URL that points to a photo
`;
+
+export const customFieldPickListValues = `
+
+
+ Status__c
+ false
+
+ true
+ false
+ Status
+ Picklist
+
+ true
+
+ false
+
+ Staging
+ false
+
+
+
+ Active
+ false
+
+
+
+ Inactive
+ false
+
+
+
+
+`;
diff --git a/src/core/markdown/adapters/type-to-renderable.ts b/src/core/markdown/adapters/type-to-renderable.ts
index 286a09b9..638e9375 100644
--- a/src/core/markdown/adapters/type-to-renderable.ts
+++ b/src/core/markdown/adapters/type-to-renderable.ts
@@ -281,6 +281,11 @@ function fieldMetadataToRenderable(
description: field.description ? [field.description] : [],
apiName: getApiName(field.name, config),
fieldType: field.type,
+ pickListValues: field.pickListValues ? {
+ headingLevel: headingLevel + 1,
+ heading: 'Possible values are',
+ value: field.pickListValues,
+ } : undefined,
};
}
diff --git a/src/core/markdown/templates/custom-object-template.ts b/src/core/markdown/templates/custom-object-template.ts
index bedc7f41..b182c4cb 100644
--- a/src/core/markdown/templates/custom-object-template.ts
+++ b/src/core/markdown/templates/custom-object-template.ts
@@ -23,6 +23,13 @@ export const customObjectTemplate = `
**Type**
*{{fieldType}}*
+
+{{#if pickListValues}}
+{{ heading pickListValues.headingLevel pickListValues.heading }}
+{{#each pickListValues.value}}
+* {{{this}}}
+{{/each}}
+{{/if}}
{{/if}}
{{#unless @last}}---{{/unless}}
diff --git a/src/core/reflection/sobject/__test__/reflect-custom-field-sources.spec.ts b/src/core/reflection/sobject/__test__/reflect-custom-field-sources.spec.ts
index 0a621483..02e75eef 100644
--- a/src/core/reflection/sobject/__test__/reflect-custom-field-sources.spec.ts
+++ b/src/core/reflection/sobject/__test__/reflect-custom-field-sources.spec.ts
@@ -100,6 +100,52 @@ describe('when parsing custom field metadata', () => {
assertEither(result, (data) => expect(data[0].type.description).toBe('A Photo URL field'));
});
+ test('can parse picklist values', async() => {
+ const unparsed: UnparsedCustomFieldBundle = {
+ type: 'customfield',
+ name: 'Status__c',
+ parentName: 'MyFirstObject__c',
+ filePath: 'src/field/Status__c.field-meta.xml',
+ content: `
+
+
+ Status__c
+ false
+
+ true
+ false
+ Status
+ Picklist
+
+ true
+
+ false
+
+ Staging
+ false
+
+
+
+ Active
+ false
+
+
+
+ Inactive
+ false
+
+
+
+
+ `,
+ };
+
+ const result = await reflectCustomFieldSources([unparsed])();
+
+ assertEither(result, (data) => expect(data[0].type.description).toBe('Status'));
+ assertEither(result, (data) => expect(data[0].type.pickListValues).toEqual(['Staging', 'Active', 'Inactive']));
+ });
+
test('An error is returned when the XML is in an invalid format', async () => {
const unparsed: UnparsedCustomFieldBundle = {
type: 'customfield',
diff --git a/src/core/reflection/sobject/reflect-custom-field-source.ts b/src/core/reflection/sobject/reflect-custom-field-source.ts
index c42f78fc..4d03b3e6 100644
--- a/src/core/reflection/sobject/reflect-custom-field-source.ts
+++ b/src/core/reflection/sobject/reflect-custom-field-source.ts
@@ -15,6 +15,7 @@ export type CustomFieldMetadata = {
label?: string | null;
type?: string | null;
parentName: string;
+ pickListValues?: string[];
};
export function reflectCustomFieldSources(
@@ -58,12 +59,34 @@ function validate(parsedResult: unknown): E.Either 'fullName' in each).map((each) => each.fullName as string);
+ }
+ }
+ }
+
+ return [];
+}
+
+function hasType(customField: object): customField is CustomFieldMetadata {
+ return !!(customField as CustomFieldMetadata).type;
}
function addName(metadata: CustomFieldMetadata, name: string): CustomFieldMetadata {
diff --git a/src/core/renderables/types.d.ts b/src/core/renderables/types.d.ts
index cfdc58a8..3b646264 100644
--- a/src/core/renderables/types.d.ts
+++ b/src/core/renderables/types.d.ts
@@ -189,6 +189,7 @@ export type RenderableCustomField = {
heading: string;
apiName: string;
description: RenderableContent[];
+ pickListValues?: RenderableSection
type: 'field';
fieldType?: string | null;
};