diff --git a/examples/markdown/docs/custom-objects/Event__c.md b/examples/markdown/docs/custom-objects/Event__c.md
index 023f2a04..4ab294bc 100644
--- a/examples/markdown/docs/custom-objects/Event__c.md
+++ b/examples/markdown/docs/custom-objects/Event__c.md
@@ -40,6 +40,25 @@ Represents an event that people can register for.
*Location*
+---
+### Social Security Number
+
+Used to store the U.S. social security number in 9 digit format.
+
+**Compliance Category**
+PII
+
+**Security Classification**
+Internal
+
+**API Name**
+
+`ns__Social_Security_Number__c`
+
+**Type**
+
+*Text*
+
---
### Start Date
**Required**
diff --git a/examples/markdown/force-app/objects/Event__c/fields/Social_Security_Number__c.field-meta.xml b/examples/markdown/force-app/objects/Event__c/fields/Social_Security_Number__c.field-meta.xml
new file mode 100644
index 00000000..6cd99937
--- /dev/null
+++ b/examples/markdown/force-app/objects/Event__c/fields/Social_Security_Number__c.field-meta.xml
@@ -0,0 +1,12 @@
+
+
+ Social_Security_Number__c
+ false
+
+ Used to store the U.S. social security number in 9 digit format.
+ 9
+ false
+ Text
+ PII
+ Internal
+
diff --git a/src/cli/commands/markdown.ts b/src/cli/commands/markdown.ts
index 5666d5d6..d92cefff 100644
--- a/src/cli/commands/markdown.ts
+++ b/src/cli/commands/markdown.ts
@@ -72,4 +72,9 @@ export const markdownOptions: Recordfalse
Url
A Photo URL field
+ Internal
+ PII
`;
describe('when parsing custom field metadata', () => {
@@ -107,6 +109,34 @@ describe('when parsing custom field metadata', () => {
assertEither(result, (data) => expect(data[0].type.description).toBe('A Photo URL field'));
});
+ test('the resulting type contains the correct security classification', async () => {
+ const unparsed: UnparsedCustomFieldBundle = {
+ type: 'customfield',
+ name: 'PhotoUrl__c',
+ parentName: 'MyFirstObject__c',
+ filePath: 'src/field/PhotoUrl__c.field-meta.xml',
+ content: customFieldContent,
+ };
+
+ const result = await reflectCustomFieldSources([unparsed])();
+
+ assertEither(result, (data) => expect(data[0].type.securityClassification).toBe('Internal'));
+ });
+
+ test('the resulting type contains the correct compliance category', async () => {
+ const unparsed: UnparsedCustomFieldBundle = {
+ type: 'customfield',
+ name: 'PhotoUrl__c',
+ parentName: 'MyFirstObject__c',
+ filePath: 'src/field/PhotoUrl__c.field-meta.xml',
+ content: customFieldContent,
+ };
+
+ const result = await reflectCustomFieldSources([unparsed])();
+
+ assertEither(result, (data) => expect(data[0].type.complianceCategory).toBe('PII'));
+ });
+
test('can parse picklist values when there are multiple picklist values available', 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 698864aa..c16c9296 100644
--- a/src/core/reflection/sobject/reflect-custom-field-source.ts
+++ b/src/core/reflection/sobject/reflect-custom-field-source.ts
@@ -18,6 +18,8 @@ export type CustomFieldMetadata = {
parentName: string;
pickListValues?: string[];
required: boolean;
+ securityClassification: string | null;
+ complianceCategory: string | null;
};
export function reflectCustomFieldSources(
@@ -66,6 +68,8 @@ function toCustomFieldMetadata(parserResult: { CustomField: unknown }): CustomFi
const defaultValues = {
description: null,
required: false,
+ securityClassification: null,
+ complianceCategory: null,
};
return {
diff --git a/src/core/reflection/sobject/reflect-custom-object-sources.ts b/src/core/reflection/sobject/reflect-custom-object-sources.ts
index aea2eb53..7f274651 100644
--- a/src/core/reflection/sobject/reflect-custom-object-sources.ts
+++ b/src/core/reflection/sobject/reflect-custom-object-sources.ts
@@ -109,6 +109,8 @@ function convertInlineFieldsToCustomFieldMetadata(
const label = inlineField.label ? (inlineField.label as string) : name;
const type = inlineField.type ? (inlineField.type as string) : null;
const required = inlineField.required ? (inlineField.required as boolean) : false;
+ const securityClassification = inlineField.securityClassification ? (inlineField.securityClassification as string) : null;
+ const complianceCategory = inlineField.complianceCategory ? (inlineField.complianceCategory as string) : null;
return {
type_name: 'customfield',
@@ -118,6 +120,8 @@ function convertInlineFieldsToCustomFieldMetadata(
parentName,
type,
required,
+ securityClassification,
+ complianceCategory,
pickListValues: getPickListValues(inlineField),
};
}
diff --git a/src/core/renderables/types.d.ts b/src/core/renderables/types.d.ts
index c56a10d9..9067c9c0 100644
--- a/src/core/renderables/types.d.ts
+++ b/src/core/renderables/types.d.ts
@@ -202,6 +202,8 @@ export type RenderableCustomField = {
type: 'field';
fieldType?: string | null;
required: boolean;
+ complianceCategory: string | null;
+ securityClassification: string | null;
};
export type RenderableCustomMetadata = {
diff --git a/src/core/shared/types.d.ts b/src/core/shared/types.d.ts
index c4fd9bab..5df8281e 100644
--- a/src/core/shared/types.d.ts
+++ b/src/core/shared/types.d.ts
@@ -38,6 +38,7 @@ export type CliConfigurableMarkdownConfig = {
includeMetadata: boolean;
linkingStrategy: LinkingStrategy;
referenceGuideTitle: string;
+ includeFieldSecurityMetadata: boolean;
};
export type UserDefinedMarkdownConfig = {
diff --git a/src/defaults.ts b/src/defaults.ts
index f30c2e0d..780991c9 100644
--- a/src/defaults.ts
+++ b/src/defaults.ts
@@ -19,6 +19,7 @@ export const markdownDefaults = {
linkingStrategy: 'relative' as const,
referenceGuideTitle: 'Reference Guide',
excludeTags: [],
+ includeFieldSecurityMetadata: false,
};
export const openApiDefaults = {