npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

sf-data-dictionary-plugin

v1.4.0

Published

Salesforce plugin for Data Dictionary generation

Readme

sf-data-dictionary

Automatically generate a Salesforce Data Dictionary in Excel format from your project metadata.

sf-data-dictionary scans your local Salesforce XML metadata files (custom objects, custom fields, custom labels, validation rules, and global value sets), then enriches them with data from multiple sources — a live Salesforce org, the Tooling API, an existing Excel file, git history, and translations — and exports a fully structured .xlsx workbook.

How It Works

┌──────────────────────────────────────────────────────────────────────┐
│  .field-meta.xml / .object-meta.xml        (local metadata)         │
│  .labels-meta.xml / .validationRule-meta.xml                        │
│  .globalValueSet-meta.xml                                           │
│  .sharingRules-meta.xml                                             │
│  Salesforce Org Describe / Tooling API     (live org)               │
│  EntityDefinition (REST API)               (live org)               │
│  .cls / .flow-meta.xml                     (manual sharing scan)    │
│  Existing Excel Data Dictionary            (manual data)            │
│  Git History & Diff                        (change tracking)        │
│  Translations (org API & local XML)        (multi-language labels)  │
└──────────────────────┬───────────────────────────────────────────────┘
                       │
                       ▼
              ┌────────────────┐
              │  sf-data-dict  │
              │    pipeline    │
              └───────┬────────┘
                      │
                      ▼
            ┌───────────────────┐
            │  data-dictionary  │
            │      .xlsx        │
            └───────────────────┘

Getting Started

Install the tool as an sf CLI plugin:

sf plugins install sf-data-dictionary

Generate a data dictionary:

# Fields dictionary from local metadata
sf data-dictionary fields -p force-app

# Objects dictionary enriched from a live org
sf data-dictionary objects -p force-app -u [email protected]

# Full example with custom config, git diff, and org enrichment
sf data-dictionary fields -p force-app -u myOrg -f main -t feature/release-25.2 -c ./my-config.js -o ./output/data-dictionary.xlsx

# All runners at once — fields, objects, custom labels, validation rules, global value sets in one file
sf data-dictionary all -p force-app -u [email protected] -c ./my-config.js -o ./data-dictionary.xlsx

# Custom labels dictionary
sf data-dictionary custom-labels -p force-app -c ./my-config.js

# Validation rules dictionary enriched from a live org
sf data-dictionary validation-rules -p force-app -u [email protected] -c ./my-config.js

# Global value sets dictionary with translations
sf data-dictionary global-value-sets -p force-app -c ./my-config.js

Commands


sf data-dictionary all

Runs all five runners (fields, objects, custom labels, validation rules, global value sets) and writes their results as separate tabs in a single Excel workbook. Each runner is executed independently — if one fails, the others still complete and their tabs are included in the output.

Flags

| Flag | Short | Required | Default | Description | |------|-------|----------|---------|-------------| | --path | -p | No | force-app | Path to the directory containing Salesforce metadata files. | | --inputExcel | -i | No | — | Path to an existing Excel file with the current Data Dictionary. | | --userName | -u | No | — | Username or alias of the target Salesforce org. | | --fromBranch | -f | No | main | Source (base) branch for git diff comparison (fields only). | | --toBranch | -t | No | DEV | Target branch for git diff comparison (fields only). | | --output | -o | No | ./sf-datadictionary.xlsx | Path for the generated Excel output file. | | --config | -c | No | — | Path to a custom configuration .js file. | | --json | — | No | — | Format output as JSON. |

Output

A single .xlsx file with one tab per runner, using the output.tabName from each section's config:

| Tab (default name) | Runner | |---------------------|--------| | Fields | FieldRunner | | Objects | ObjectRunner | | Custom Labels | CustomLabelRunner | | Validation Rules | ValidationRuleRunner | | Global Value Sets | GlobalValueSetRunner |


sf data-dictionary fields

Reads .field-meta.xml files from your Salesforce project and exports them to an Excel worksheet. Optionally enriches results with live org metadata, git diff/history, field translations, and data from an existing Excel file.

Flags

| Flag | Short | Required | Default | Description | |------|-------|----------|---------|-------------| | --path | -p | No | force-app | Path to the directory containing Salesforce metadata files. | | --inputExcel | -i | No | — | Path to an existing Excel file with the current Data Dictionary. Used by the inputFile value provider to preserve manually entered data across runs. | | --userName | -u | No | admin | Username or alias of the target Salesforce org. Needed for the orgMetadataDescribe and fieldTranslation value providers. | | --fromBranch | -f | No | main | Source (base) branch for git diff comparison. | | --toBranch | -t | No | DEV | Target branch for git diff comparison. | | --output | -o | No | ./sf-datadictionary.xlsx | Path for the generated Excel output file. | | --config | -c | No | — | Path to a custom configuration .js file that overrides or extends the default rules (see Custom Configuration). | | --json | — | No | — | Format output as JSON. |

Default Output Columns

| Column | Data Source | |--------|------------| | Object | XML metadata | | Field API Name | XML metadata | | Field Label | XML / Org Describe | | Description | XML / Org Describe | | Type | XML / Org Describe | | Required | XML / Org Describe | | Picklist Values | XML / Org Describe | | History Tracking | XML / Org Describe | | External ID | XML / Org Describe | | Unique | XML / Org Describe | | Created Date | Input File / Git Info | | Last Modified Date | Input File / Git Info |

Pipeline

Each step only runs when its corresponding provider is configured:

  1. XML Metadata — Parse .field-meta.xml files and apply xml value providers.
  2. Additional Fields — Append extra fields from an external Excel sheet (additionalFields input provider).
  3. Org Metadata Describe — Enrich with live org describe data (orgMetadataDescribe value provider).
  4. Field Translations — Fetch translated labels per language (fieldTranslation value provider).
  5. Input File — Merge values from an existing Excel Data Dictionary (inputFile value provider).
  6. Git Diff — Compute change status between branches (gitDiff value provider).
  7. Git Info — Extract per-file commit dates (gitInfo value provider).
  8. Deduplicate & Sort — Remove duplicates (by Object + Field API Name) and sort alphabetically.
  9. Export — Write to the output .xlsx file.

sf data-dictionary objects

Reads .object-meta.xml files from your Salesforce project and exports them to an Excel worksheet. Optionally enriches results with live org metadata and data from an existing Excel file.

Flags

| Flag | Short | Required | Default | Description | |------|-------|----------|---------|-------------| | --path | -p | No | force-app | Path to the directory containing Salesforce metadata files. | | --inputExcel | -i | No | — | Path to an existing Excel file with the current Data Dictionary. Used by the inputFile value provider to preserve manually entered data across runs. | | --userName | -u | No | — | Username or alias of the target Salesforce org. Needed for the orgMetadataDescribe value provider. | | --output | -o | No | ./sf-datadictionary.xlsx | Path for the generated Excel output file. | | --config | -c | No | — | Path to a custom configuration .js file that overrides or extends the default rules (see Custom Configuration). | | --json | — | No | — | Format output as JSON. |

Default Output Columns

| Column | Data Source | |--------|------------| | Name (API Name) | XML metadata | | Object Label | XML / Org Describe / EntityDefinition | | Description | XML / Org Describe | | Internal Sharing Model | XML / EntityDefinition | | External Sharing Model | XML / EntityDefinition | | Key Prefix | Org Describe / EntityDefinition | | Has Sharing Rules | .sharingRules-meta.xml | | Manual Sharing Files | .cls / .flow-meta.xml scan |

Pipeline

  1. XML Metadata — Parse .object-meta.xml files and apply xml value providers.
  2. Additional Objects — Append extra objects from an external Excel sheet (additionalObjects input provider).
  3. Deduplicate — Remove duplicates by API Name.
  4. Org Metadata Describe — Enrich with live org describe data (orgMetadataDescribe value provider).
  5. Sharing Rules — Parse <ObjectName>.sharingRules-meta.xml files and apply sharingRules value providers.
  6. Manual Sharing — Scan .cls and .flow-meta.xml files for references to each object's Share object and apply manualSharing value providers.
  7. EntityDefinition — Query SELECT FIELDS(ALL) FROM EntityDefinition WHERE QualifiedApiName = '...' for each object and apply entityDefinition value providers.
  8. Object Translations — Fetch translated labels per language (objectTranslation value provider).
  9. Input File — Merge values from an existing Excel Data Dictionary (inputFile value provider).
  10. Deduplicate & Sort — Final deduplication and alphabetical sort.
  11. Export — Write to the output .xlsx file.

sf data-dictionary custom-labels

Reads *.labels-meta.xml files from your Salesforce project and exports them to an Excel worksheet. Each file can contain multiple <labels> entries. Optionally enriches results with translations from local *.translation-meta.xml files and data from an existing Excel file.

Flags

| Flag | Short | Required | Default | Description | |------|-------|----------|---------|-------------| | --path | -p | No | force-app | Path to the directory containing Salesforce metadata files. | | --inputExcel | -i | No | — | Path to an existing Excel file with the current Data Dictionary. Used by the inputFile value provider. | | --output | -o | No | ./sf-datadictionary.xlsx | Path for the generated Excel output file. | | --config | -c | No | — | Path to a custom configuration .js file that overrides or extends the default rules. | | --json | — | No | — | Format output as JSON. |

Default Output Columns

| Column | Data Source | |--------|------------| | Name | XML metadata (fullName) | | Short Description | XML metadata | | Value | XML metadata | | Language | XML metadata | | Categories | XML metadata | | Protected | XML metadata |

Pipeline

  1. XML Metadata — Parse *.labels-meta.xml files and apply xml value providers. Each file may contain multiple <labels> nodes.
  2. Deduplicate — Remove duplicates by apiName (fullName).
  3. Label Translations — Enrich with translations from local *.translation-meta.xml files (labelTranslation value provider).
  4. Input File — Merge values from an existing Excel Data Dictionary (inputFile value provider).
  5. Deduplicate & Sort — Final deduplication and alphabetical sort by name.
  6. Export — Write to the output .xlsx file.

sf data-dictionary validation-rules

Reads *.validationRule-meta.xml files from your Salesforce project and exports them to an Excel worksheet. Optionally enriches results with live data from the Salesforce Tooling API, translations from local *.objectTranslation-meta.xml files, and data from an existing Excel file.

Flags

| Flag | Short | Required | Default | Description | |------|-------|----------|---------|-------------| | --path | -p | No | force-app | Path to the directory containing Salesforce metadata files. | | --inputExcel | -i | No | — | Path to an existing Excel file with the current Data Dictionary. Used by the inputFile value provider. | | --userName | -u | No | — | Username or alias of the target Salesforce org. Needed for the orgMetadataDescribe value provider (Tooling API). | | --output | -o | No | ./sf-datadictionary.xlsx | Path for the generated Excel output file. | | --config | -c | No | — | Path to a custom configuration .js file that overrides or extends the default rules. | | --json | — | No | — | Format output as JSON. |

Default Output Columns

| Column | Data Source | |--------|------------| | Object | XML metadata (from file path) | | Rule Name | XML metadata (from filename) | | Active | XML / Tooling API | | Description | XML / Tooling API | | Error Condition Formula | XML / Tooling API | | Error Display Field | XML / Tooling API | | Error Message | XML / Tooling API |

Pipeline

  1. XML Metadata — Parse *.validationRule-meta.xml files (under objects/{ObjectName}/validationRules/) and apply xml value providers.
  2. Deduplicate — Remove duplicates by Object + Rule Name.
  3. Org Metadata Describe (Tooling API) — Query the Tooling API's ValidationRule entity per object (orgMetadataDescribe value provider). Also queries for objects listed in the additionalObjects input provider. Rules found on the org but not in local metadata are added as new entries.
  4. Validation Rule Translations — Enrich with translated error messages from local *.objectTranslation-meta.xml files (validationRuleTranslation value provider).
  5. Input File — Merge values from an existing Excel Data Dictionary (inputFile value provider).
  6. Deduplicate & Sort — Final deduplication and sort by Object then Rule Name.
  7. Export — Write to the output .xlsx file.

sf data-dictionary global-value-sets

Reads *.globalValueSet-meta.xml files from your Salesforce project and exports them to an Excel worksheet. Optionally enriches results with translations from local *.globalValueSetTranslation-meta.xml files and data from an existing Excel file.

Flags

| Flag | Short | Required | Default | Description | |------|-------|----------|---------|-------------| | --path | -p | No | force-app | Path to the directory containing Salesforce metadata files. | | --inputExcel | -i | No | — | Path to an existing Excel file with the current Data Dictionary. Used by the inputFile value provider. | | --output | -o | No | ./sf-datadictionary.xlsx | Path for the generated Excel output file. | | --config | -c | No | — | Path to a custom configuration .js file that overrides or extends the default rules. | | --json | — | No | — | Format output as JSON. |

Default Output Columns

| Column | Data Source | |--------|------------| | Name | XML metadata (from filename) | | Master Label | XML metadata | | Description | XML metadata | | Sorted | XML metadata | | Values | XML metadata (active customValue entries) |

Pipeline

  1. XML Metadata — Parse *.globalValueSet-meta.xml files and apply xml value providers. The value set API name is extracted from the filename (e.g. CRM_ApproverRole from CRM_ApproverRole.globalValueSet-meta.xml).
  2. Deduplicate — Remove duplicates by apiName.
  3. Global Value Set Translations — Enrich with translations from local *.globalValueSetTranslation-meta.xml files (globalValueSetTranslation value provider). Translations follow the same order as values in the main file; missing translations produce blank lines to keep columns aligned.
  4. Input File — Merge values from an existing Excel Data Dictionary (inputFile value provider).
  5. Deduplicate & Sort — Final deduplication and alphabetical sort by name.
  6. Export — Write to the output .xlsx file.

Translation File Convention

Translation files follow the naming pattern {GlobalValueSetName}-{languageCode}.globalValueSetTranslation-meta.xml. For example, CRM_ApproverRole-en_US.globalValueSetTranslation-meta.xml contains the en_US translations for the CRM_ApproverRole global value set.


Custom Configuration

Pass a custom JavaScript configuration file via --config (-c) to override or extend the default rules. The configuration is deep-merged with the built-in defaults — you only need to specify what you want to change.

Configuration Structure

export default {
  general: {
    apiVersion: "62.0",
    defaultLanguage: "en_US",   // optional — see Language Management below
  },
  fields: {
    inputProviders: { /* ... */ },
    output: { /* ... */ },
    columns: { /* ... */ },
  },
  objects: {
    inputProviders: { /* ... */ },
    output: { /* ... */ },
    columns: { /* ... */ },
  },
  customLabels: {
    inputProviders: { /* ... */ },
    output: { /* ... */ },
    columns: { /* ... */ },
  },
  validationRules: {
    inputProviders: { /* ... */ },
    output: { /* ... */ },
    columns: { /* ... */ },
  },
  globalValueSets: {
    inputProviders: { /* ... */ },
    output: { /* ... */ },
    columns: { /* ... */ },
  },
};

Full Example

export default {
  general: {
    apiVersion: "62.0",
    defaultLanguage: "en_US",   // switch org user language before each runner, then restore
  },
  fields: {
    inputProviders: {
      xmlMetadataFiles: {
        excludeCustomMetadataObjects: true,
        excludeCustomEventObjects: true,
      },
      additionalFields: {
        path: "./extra-fields.xlsx",
        fileType: "xlsx",
        sheetName: "Fields",
        objectColumnName: "Object",
        fieldColumnName: "Field API Name",
      },
      inputFile: {
        path: "./current-data-dictionary.xlsx",
        fileType: "xlsx",
        sheetName: "Fields",
      },
      orgMetadataDescribe: {
        username: "[email protected]",
        includeStandardFields: ["Account", "Contact"],
      },
    },
    output: {
      tabName: "Custom Fields",
    },
    columns: {
      // Keep built-in columns but rename them
      label: {
        outputColumnName: "Field Label (EN)",
      },

      // Track release status via git diff
      releaseStatus: {
        outputColumnName: "Release Status",
        valueProviders: {
          gitDiff: function (changeType) {
            return changeType; // "New", "Updated", "Deleted", or "Unchanged"
          },
        },
      },

      // Add a French translation column (simple property shorthand)
      labelFR: {
        outputColumnName: "Field Label (FR)",
        valueProviders: {
          fieldTranslation: {
            language: "fr",
            ignoreIfEquals: true,
          },
        },
      },

      // Add a Japanese help text column (using translationFunction for full control)
      helpTextJA: {
        outputColumnName: "Help Text (JA)",
        valueProviders: {
          fieldTranslation: {
            language: "ja",
            translationFunction: function (fieldDescribe, field) {
              return fieldDescribe.inlineHelpText ?? "";
            },
          },
        },
      },

      // Preserve a manually-managed column from the existing Excel
      businessOwner: {
        outputColumnName: "Business Owner",
        valueProviders: {
          inputFile: {
            columnName: "Business Owner",
          },
        },
      },

      // Combine git info with input file data
      createdDate: {
        outputColumnName: "Created Date",
        valueProviders: {
          xml: false,
          orgMetadataDescribe: false,
          inputFile: {
            columnName: "Created Date",
          },
          gitInfo: function (gitInfo, field) {
            if (field.releaseStatus !== undefined && field.releaseStatus !== "") {
              return gitInfo.createdAt || "";
            }
            return field.createdDate;
          },
        },
      },
    },
  },
  objects: {
    inputProviders: {
      xmlMetadataFiles: {
        excludeCustomMetadataObjects: true,
        excludeCustomEventObjects: true,
      },
      orgMetadataDescribe: {
        username: "[email protected]",
      },
    },
    output: {
      tabName: "Custom Objects",
    },
    columns: {
      apiName: {
        outputColumnName: "Object API Name",
      },
      // Key Prefix from EntityDefinition (e.g. "001" for Account)
      keyPrefix: {
        outputColumnName: "Key Prefix",
        valueProviders: {
          entityDefinition: function (entityDefinition, obj) {
            return entityDefinition.KeyPrefix || "";
          },
        },
      },
      // Whether sharing rules are defined for this object
      hasSharingRules: {
        outputColumnName: "Has Sharing Rules",
        valueProviders: {
          sharingRules: function (objectInfo, objectName, sharingRulesMetadata) {
            const total =
              (sharingRulesMetadata.sharingOwnerRules    || []).length +
              (sharingRulesMetadata.sharingCriteriaRules || []).length +
              (sharingRulesMetadata.sharingGuestRules    || []).length;
            return total > 0 ? "Yes" : "No";
          },
        },
      },
      // Files that manually manage sharing via Apex or Flows
      manualSharingFiles: {
        outputColumnName: "Manual Sharing Files",
        valueProviders: {
          manualSharing: function (objectInfo, objectName, filePaths) {
            return filePaths.join("\r\n");
          },
        },
      },
    },
  },
  customLabels: {
    inputProviders: {
      inputFile: {
        path: "./current-data-dictionary.xlsx",
        fileType: "xlsx",
        sheetName: "Custom Labels",
      },
    },
    output: {
      tabName: "Labels",
    },
    columns: {
      apiName: { outputColumnName: "Label Name" },
      value: { outputColumnName: "Value" },
      // Add a Japanese translation column from local translation files
      valueJA: {
        outputColumnName: "Value (JA)",
        valueProviders: {
          labelTranslation: {
            language: "ja",
          },
        },
      },
      // Preserve a manually-managed column
      notes: {
        outputColumnName: "Notes",
        valueProviders: {
          inputFile: { columnName: "Notes" },
        },
      },
    },
  },
  validationRules: {
    inputProviders: {
      additionalObjects: {
        path: "./extra-objects.xlsx",
        fileType: "xlsx",
        sheetName: "Missing fields",
        objectColumnName: "Object",
      },
      orgMetadataDescribe: {
        username: "[email protected]",
      },
    },
    output: {
      tabName: "Validation Rules",
    },
    columns: {
      object: { outputColumnName: "Object" },
      apiName: { outputColumnName: "Rule Name" },
      active: { outputColumnName: "Active" },
      description: { outputColumnName: "Description" },
      errorMessage: { outputColumnName: "Error Message" },
      // Add a French translation of the error message
      errorMessageFR: {
        outputColumnName: "Error Message (FR)",
        valueProviders: {
          validationRuleTranslation: {
            language: "fr",
            ignoreIfEquals: true,
          },
        },
      },
      // Extract the Tooling API record Id
      ruleId: {
        outputColumnName: "Rule Id",
        valueProviders: {
          orgMetadataDescribe: function (toolingRecord) {
            return toolingRecord.Id || "";
          },
        },
      },
    },
  },
  globalValueSets: {
    inputProviders: {
      inputFile: {
        path: "./current-data-dictionary.xlsx",
        fileType: "xlsx",
        sheetName: "Global Value Sets",
      },
    },
    output: {
      tabName: "Picklist Value Sets",
    },
    columns: {
      apiName: { outputColumnName: "Value Set Name" },
      masterLabel: { outputColumnName: "Master Label" },
      description: { outputColumnName: "Description" },
      sorted: { outputColumnName: "Sorted" },
      values: { outputColumnName: "Values" },
      // Add a Japanese translation column from local translation files
      valuesJA: {
        outputColumnName: "Values (JA)",
        valueProviders: {
          globalValueSetTranslation: {
            language: "ja",
          },
        },
      },
      // Preserve a manually-managed column
      notes: {
        outputColumnName: "Notes",
        valueProviders: {
          inputFile: { columnName: "Notes" },
        },
      },
    },
  },
};

Merge Behaviour

| Section | Strategy | |---------|----------| | inputProviders | Shallow merge — your values override the defaults. | | output | Shallow merge — your values override the defaults. | | columns | Only columns present in your config are included, in the order you define them. This gives you full control over which columns appear and their order. |

Mandatory Columns

Some columns are mandatory — their valueProviders are locked to the built-in implementation and cannot be overridden via custom config. You can still rename them by changing outputColumnName.

Fields command

| Column key | Default outputColumnName | Mandatory valueProvider | What it returns | |------------|---------------------------|--------------------------|-----------------| | object | "Object" | xml | The parent object API name, extracted from the file path. | | apiName | "Field API Name" | xml | The field API name, extracted from the .field-meta.xml filename. |

Objects command

| Column key | Default outputColumnName | Mandatory valueProvider | What it returns | |------------|---------------------------|--------------------------|-----------------| | apiName | "Name" | xml | The object API name, extracted from the .object-meta.xml file path. |

Custom Labels command

| Column key | Default outputColumnName | Mandatory valueProvider | What it returns | |------------|---------------------------|--------------------------|-----------------| | apiName | "Name" | xml | The label fullName from the .labels-meta.xml file. |

Validation Rules command

| Column key | Default outputColumnName | Mandatory valueProvider | What it returns | |------------|---------------------------|--------------------------|-----------------| | object | "Object" | xml | The parent object API name, extracted from the file path. | | apiName | "Rule Name" | xml | The validation rule name, extracted from the .validationRule-meta.xml filename. |

Global Value Sets command

| Column key | Default outputColumnName | Mandatory valueProvider | What it returns | |------------|---------------------------|--------------------------|-----------------| | apiName | "Name" | xml | The global value set API name, extracted from the .globalValueSet-meta.xml filename. |

These columns are the unique identifiers used internally for deduplication and row matching, which is why their extraction logic is protected.


Value Providers

Each column in the output is populated by one or more value providers. A value provider is a data source that extracts or computes a value for that column. When multiple providers are defined for a single column, they execute in pipeline order and the tool merges results, prioritising non-empty values from later stages.

A value provider can be set to false to explicitly disable that source for a given column.

xml

Extracts data from local metadata XML files (parsed via xml2js). The function signature varies by command.

Applies to: fields, objects, custom labels, validation rules, global value sets

// Field column
xml: function (fieldInfo, objectName, fieldName) {
  return fieldInfo.label?.[0] || "";
}

// Object column
xml: function (objectInfo, objectName) {
  return objectInfo.description?.[0] || "";
}

// Custom Label column
xml: function (labelInfo) {
  return labelInfo.value?.[0] || "";
}

// Validation Rule column
xml: function (ruleInfo, objectName, ruleName) {
  return ruleInfo.errorMessage?.[0] || "";
}

// Global Value Set column
xml: function (valueSetInfo, valueSetName) {
  return valueSetInfo.masterLabel?.[0] || "";
}

| Parameter | Description | |-----------|-------------| | fieldInfo / objectInfo / labelInfo / ruleInfo / valueSetInfo | Parsed XML object from xml2js. Values are arrays — access them as info.label[0], info.type[0], etc. | | objectName | API name of the object (e.g. Account, MyObject__c). Available for fields, objects, and validation rules. | | fieldName / ruleName / valueSetName | API name of the field, validation rule, or global value set. Available for fields, validation rules, and global value sets respectively. |


orgMetadataDescribe

Calls the Salesforce REST API on a connected org to retrieve live metadata. For fields and objects, it uses the standard sobject/describe endpoint. For validation rules, it queries the Tooling API (ValidationRule entity). Requires a valid --userName or inputProviders.orgMetadataDescribe.username.

Applies to: fields, objects, validation rules

// Field column
orgMetadataDescribe: function (fieldMetadata) {
  return fieldMetadata.label || "";
}

// Object column
orgMetadataDescribe: function (objectMetadata) {
  return objectMetadata.sharingModel || "";
}

// Validation Rule column — receives the Tooling API record
orgMetadataDescribe: function (toolingRecord) {
  return toolingRecord.Description || "";
}

| Parameter | Description | |-----------|-------------| | fieldMetadata | Salesforce field describe result. Properties include label, type, length, nillable, picklistValues, calculated, externalId, unique, etc. | | objectMetadata | Salesforce object describe result. Properties include label, description, sharingModel, externalSharingModel, etc. | | toolingRecord | Tooling API ValidationRule record. Properties include Id, ValidationName, Active, Description, ErrorConditionFormula, ErrorDisplayField, ErrorMessage. |

For validation rules, the Tooling API query is scoped to objects found in local metadata plus any objects listed in the additionalObjects input provider. Rules that exist on the org but not in local XML are added as new rows.


inputFile

Reads values from an existing Excel file — typically the previous version of the Data Dictionary. Useful for preserving manually entered data (e.g. business owner, comments) across regeneration runs. Requires inputProviders.inputFile to be configured.

Applies to: fields, objects, custom labels, validation rules, global value sets

inputFile: {
  columnName: "Business Owner",
}

| Property | Description | |----------|-------------| | columnName | Header of the column in the source Excel file to read from. Rows are matched by Object + Field API Name (fields, validation rules) or API Name (objects, custom labels, global value sets). |


gitDiff

Computes a git diff between two branches (--fromBranch--toBranch) to determine the change status of each field's metadata file.

Applies to: fields only

gitDiff: function (changeType) {
  return changeType;
}

| Parameter | Description | |-----------|-------------| | changeType | "New" — file added between branches. "Updated" — file modified. "Deleted" — file removed. "Unchanged" — no changes detected. |


gitInfo

Extracts git commit history for each field's metadata file to determine when it was first created and last modified.

Applies to: fields only

gitInfo: function (gitInfo, field) {
  return gitInfo.createdAt || "";
}

| Parameter | Description | |-----------|-------------| | gitInfo | Object with createdAt (date of the first commit for the file) and updatedAt (date of the most recent commit). | | field | The current field object with all previously populated column values — useful for conditional logic. |


fieldTranslation

Retrieves translated field data from a live Salesforce org. The tool temporarily switches the running user's LanguageLocaleKey, calls sobject/describe for each object to collect the full locale-aware field describe, then restores the original language. Requires a valid --userName.

Applies to: fields only

When no translationFunction is provided, the translated label is extracted by default (backward compatible). When provided, it receives the full field describe object and the current field row, giving you complete control over the output.

// Simple: translated label (backward compatible)
fieldTranslation: {
  language: "fr",
  ignoreIfEquals: true,
}

// Custom function with access to the entire field describe
fieldTranslation: {
  language: "ja",
  translationFunction: function (fieldDescribe, field) {
    if (fieldDescribe.type === "picklist") {
      return (fieldDescribe.picklistValues || [])
        .filter((pv) => pv.active)
        .map((pv) => pv.label)
        .join(", ");
    }
    return fieldDescribe.label ?? "";
  },
  ignoreIfEquals: true,
}

| Property | Type | Description | |----------|------|-------------| | language | string | (required) A Salesforce LanguageLocaleKey value (e.g. "fr", "de", "es", "ja"). | | translationFunction | function(fieldDescribe, field) | Custom function receiving the raw Salesforce field describe object and the current field row. Return the value you want in the output column. When omitted, defaults to fieldDescribe.label. | | ignoreIfEquals | boolean | When true, the cell is left empty if the resolved value is identical to the field's default label. Useful to only surface actual translations. |


objectTranslation

Retrieves translated object data from a live Salesforce org. Works the same way as fieldTranslation but operates on the object-level describe result. Requires a valid --userName.

Applies to: objects only

// Simple: translated label (backward compatible)
objectTranslation: {
  language: "fr",
  ignoreIfEquals: true,
}

// Custom function
objectTranslation: {
  language: "ja",
  translationFunction: function (objectDescribe, obj) {
    return `${objectDescribe.label} (${objectDescribe.labelPlural})`;
  },
}

| Property | Type | Description | |----------|------|-------------| | language | string | (required) A Salesforce LanguageLocaleKey value (e.g. "fr", "de", "es", "ja"). | | translationFunction | function(objectDescribe, obj) | Custom function receiving the raw Salesforce object describe result and the current object row. Return the value you want in the output column. When omitted, defaults to objectDescribe.label. | | ignoreIfEquals | boolean | When true, the cell is left empty if the resolved value is identical to the object's default label. Useful to only surface actual translations. |


entityDefinition

Queries SELECT FIELDS(ALL) FROM EntityDefinition WHERE QualifiedApiName = '...' against the Salesforce standard REST API for each object. The EntityDefinition entity exposes system-level metadata not available through sobject/describe, such as InternalSharingModel, ExternalSharingModel, KeyPrefix, DeveloperName, IsCustom, IsQueryable, IsSearchable, and many more. Requires a valid --userName.

Applies to: objects only

// Retrieve the object's Key Prefix (e.g. "001" for Account)
keyPrefix: {
  outputColumnName: "Key Prefix",
  valueProviders: {
    entityDefinition: function (entityDefinition, obj) {
      return entityDefinition.KeyPrefix || "";
    },
  },
},

// Check whether the object supports custom sharing
isCustom: {
  outputColumnName: "Is Custom?",
  valueProviders: {
    entityDefinition: function (entityDefinition, obj) {
      return entityDefinition.IsCustom ? "Yes" : "No";
    },
  },
},

| Parameter | Description | |-----------|-------------| | entityDefinition | The full EntityDefinition record returned by SELECT FIELDS(ALL). All standard EntityDefinition fields are available, including Label, DeveloperName, KeyPrefix, InternalSharingModel, ExternalSharingModel, IsCustom, IsQueryable, IsSearchable, PluralLabel, etc. | | obj | The current object record with all columns populated by previous pipeline steps (apiName, label, etc.). |

A LIMIT 1 query is issued per object — one API call per object. Objects not found in EntityDefinition (e.g. external objects) are silently skipped.


sharingRules

Parses <ObjectName>.sharingRules-meta.xml files found anywhere under the project --path. For each object, the corresponding file (e.g. Account.sharingRules-meta.xml) is located, parsed, and its content passed to the value provider function. No org connection is required — this is a purely file-based provider.

Applies to: objects only

// Show whether the object has any sharing rules defined
hasSharingRules: {
  outputColumnName: "Has Sharing Rules",
  valueProviders: {
    sharingRules: function (objectInfo, objectName, sharingRulesMetadata) {
      const ownerRules    = sharingRulesMetadata.sharingOwnerRules    || [];
      const criteriaRules = sharingRulesMetadata.sharingCriteriaRules || [];
      const guestRules    = sharingRulesMetadata.sharingGuestRules    || [];
      return (ownerRules.length + criteriaRules.length + guestRules.length) > 0
        ? "Yes"
        : "No";
    },
  },
},

// List the names and access levels of all sharing rules
sharingRulesSummary: {
  outputColumnName: "Sharing Rules",
  valueProviders: {
    sharingRules: function (objectInfo, objectName, sharingRulesMetadata) {
      const all = [
        ...(sharingRulesMetadata.sharingOwnerRules    || []),
        ...(sharingRulesMetadata.sharingCriteriaRules || []),
        ...(sharingRulesMetadata.sharingGuestRules    || []),
      ];
      return all
        .map((rule) => `[${rule.accessLevel?.[0]}] ${rule.fullName?.[0]}`)
        .join("\r\n");
    },
  },
},

| Parameter | Description | |-----------|-------------| | objectInfo | The current object record with all columns populated by previous pipeline steps. | | objectName | The object API name (e.g. Account, MyObject__c). | | sharingRulesMetadata | The parsed <SharingRules> root element from xml2js. Contains sharingOwnerRules, sharingCriteriaRules, and sharingGuestRules arrays, each element having fields like fullName, accessLevel, description, sharedTo, etc. |

Objects that have no corresponding .sharingRules-meta.xml file are silently skipped (the provider is not called for them).


manualSharing

Scans all .cls (Apex class) and .flow-meta.xml (Flow) files under the project --path for references to an object's Share sObject. The Share object name is derived automatically:

| Object | Share name | |--------|-----------| | Account | AccountShare | | MyObject__c | MyObject__Share |

No org connection is required — this is a purely file-based provider that reads source code content.

Applies to: objects only

// List relative paths of all files that reference the Share object
manualSharingFiles: {
  outputColumnName: "Manual Sharing Files",
  valueProviders: {
    manualSharing: function (objectInfo, objectName, filePaths) {
      return filePaths.join("\r\n");
    },
  },
},

// Just flag whether manual sharing exists
hasManualSharing: {
  outputColumnName: "Has Manual Sharing?",
  valueProviders: {
    manualSharing: function (objectInfo, objectName, filePaths) {
      return filePaths.length > 0 ? "Yes" : "No";
    },
  },
},

| Parameter | Description | |-----------|-------------| | objectInfo | The current object record with all columns populated by previous pipeline steps. | | objectName | The object API name (e.g. Account, MyObject__c). | | filePaths | Array of relative file paths (relative to the project --path) of .cls or .flow-meta.xml files that contain the Share object name as a string. Paths use the OS path separator. |

Objects with no matching files in the scan results are silently skipped (the provider is not called for them).


labelTranslation

Reads translated custom label values from local *.translation-meta.xml files (e.g. ja.translation-meta.xml). Inside these files, <customLabels> nodes contain a <name> matching the label's fullName and a <label> with the translated text.

Applies to: custom labels only

// Simple: translated value
labelTranslation: {
  language: "ja",
}

// Custom function for full control
labelTranslation: {
  language: "fr",
  translationFunction: function (translatedValue, labelRow) {
    return translatedValue ? `[FR] ${translatedValue}` : "";
  },
  ignoreIfEquals: true,
}

| Property | Type | Description | |----------|------|-------------| | language | string | (required) Language code matching the translation file prefix (e.g. "ja" for ja.translation-meta.xml). | | translationFunction | function(translatedValue, labelRow) | Custom function receiving the translated string and the current label row. When omitted, the raw translated value is used. | | ignoreIfEquals | boolean | When true, the cell is left empty if the resolved value is identical to the label's default value. |


validationRuleTranslation

Reads translated validation rule error messages from local *.objectTranslation-meta.xml files. These files follow the naming convention {ObjectName}-{languageCode}.objectTranslation-meta.xml (e.g. CustomObject__c-fr.objectTranslation-meta.xml). Inside, <validationRules> nodes contain a <name> matching the rule's API name and an <errorMessage> with the translated text.

Applies to: validation rules only

// Simple: translated error message
validationRuleTranslation: {
  language: "fr",
}

// Custom function for full control
validationRuleTranslation: {
  language: "ja",
  translationFunction: function (translatedErrorMessage, rule) {
    return translatedErrorMessage || "";
  },
  ignoreIfEquals: true,
}

| Property | Type | Description | |----------|------|-------------| | language | string | (required) Language code matching the objectTranslation file suffix (e.g. "fr" for Account-fr.objectTranslation-meta.xml). | | translationFunction | function(translatedErrorMessage, rule) | Custom function receiving the translated error message string and the current rule row. When omitted, the raw translated error message is used. | | ignoreIfEquals | boolean | When true, the cell is left empty if the resolved value is identical to the rule's default errorMessage. |


globalValueSetTranslation

Reads translated global value set values from local *.globalValueSetTranslation-meta.xml files. These files follow the naming convention {GlobalValueSetName}-{languageCode}.globalValueSetTranslation-meta.xml (e.g. CRM_ApproverRole-en_US.globalValueSetTranslation-meta.xml). Inside, <valueTranslation> nodes contain a <masterLabel> matching the value's fullName and a <translation> with the translated text.

Translated values are always emitted in the same order as the values column (which reflects the order from the main .globalValueSet-meta.xml file). When a value has no translation in the translation file, a blank line is produced so that the translation column stays row-aligned with the values column.

Applies to: global value sets only

// Simple: translated values
globalValueSetTranslation: {
  language: "en_US",
}

// Custom function for full control
globalValueSetTranslation: {
  language: "ja",
  translationFunction: function (translations, valueSet, orderedValues) {
    // translations: { masterLabel → translatedString }
    // orderedValues: array of value fullNames in the same order as the values column
    return orderedValues
      .map((v) => translations[v] || "—")
      .join("\r\n");
  },
  ignoreIfEquals: true,
}

| Property | Type | Description | |----------|------|-------------| | language | string | (required) Language code matching the translation file suffix (e.g. "en_US" for CRM_ApproverRole-en_US.globalValueSetTranslation-meta.xml). | | translationFunction | function(translations, valueSet, orderedValues) | Custom function receiving a masterLabel → translation map, the current value set row, and the ordered array of value fullName entries. When omitted, translations are joined by \r\n in the same order as the values column. | | ignoreIfEquals | boolean | When true, the cell is left empty if the resolved value is identical to the value set's values column. |


Value Providers Summary

| Provider | Type | Applies To | Requires | |----------|------|------------|----------| | xml | function(info, objectName?, name?) | fields, objects, custom labels, validation rules, global value sets | Local metadata files | | orgMetadataDescribe | function(metadata) | fields, objects, validation rules | --userName or config username | | entityDefinition | function(entityDefinition, obj) | objects | --userName or config username | | sharingRules | function(objectInfo, objectName, sharingRulesMetadata) | objects | Local *.sharingRules-meta.xml files | | manualSharing | function(objectInfo, objectName, filePaths) | objects | Local .cls / .flow-meta.xml files | | inputFile | { columnName: "..." } | fields, objects, custom labels, validation rules, global value sets | inputProviders.inputFile configured | | gitDiff | function(changeType) | fields | --fromBranch and --toBranch | | gitInfo | function(gitInfo, field) | fields | Git repository | | fieldTranslation | { language, translationFunction?, ignoreIfEquals? } | fields | --userName or config username | | objectTranslation | { language, translationFunction?, ignoreIfEquals? } | objects | --userName or config username | | labelTranslation | { language, translationFunction?, ignoreIfEquals? } | custom labels | Local *.translation-meta.xml files | | validationRuleTranslation | { language, translationFunction?, ignoreIfEquals? } | validation rules | Local *.objectTranslation-meta.xml files | | globalValueSetTranslation | { language, translationFunction?, ignoreIfEquals? } | global value sets | Local *.globalValueSetTranslation-meta.xml files |

Any provider can be set to false to disable it for a specific column.


Language Management

general.defaultLanguage

When a Salesforce org connection is required (e.g. for orgMetadataDescribe, fieldTranslation, objectTranslation, or entityDefinition), the tool can automatically switch the running user's LanguageLocaleKey to a specific language before executing the runner, then restore the original language afterward.

This is useful when your Salesforce user's default language is not English but you want object labels, field labels, and picklist values in the output to be in a consistent language (typically en_US).

export default {
  general: {
    apiVersion: "62.0",
    defaultLanguage: "en_US",
  },
  // ...
};

| Property | Type | Description | |----------|------|-------------| | defaultLanguage | string \| undefined | A Salesforce LanguageLocaleKey value (e.g. "en_US", "fr", "ja"). When set and the org user's current language differs, the tool swaps to this language before the runner executes and restores the original language when done. When undefined or when the user's current language already matches, no swap is performed. |

How it works:

  1. Before the runner starts, the tool reads the user's current LanguageLocaleKey via a SOQL query on the User object.
  2. If it differs from defaultLanguage, it updates the user's LanguageLocaleKey to the configured value.
  3. The runner executes all its data extraction steps (including org API calls).
  4. After the runner finishes (even if an error occurs), the user's LanguageLocaleKey is restored to its original value.

Note: The language swap affects the running user's profile in Salesforce. Ensure that the target language is an active translation language in your org (Setup > Translation Workbench). This setting only affects data returned by the Salesforce REST API describe endpoints — it does not affect static XML metadata values read from local files.