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 🙏

© 2024 – Pkg Stats / Ryan Hefner

sf-metadata

v1.0.0

Published

Library for reading, writing and processing (read, update and write) Salesforce metadata files

Downloads

30

Readme

sf-metadata

Library for reading, writing and processing (read, update, write) Salesforce metadata files.

Version Known Vulnerabilities Downloads/week License Build and Test

Usage

Processor

Read all Salesforce metadata files in a given directory that match a set of patterns. Matched files are passed to a user defined callback function to make changes to the metadata. The processor writes changes back to the original files and returns a list of the filenames that have been updated.

Specification

Using options parameter:

let updatedFiles = await processor({
	baseDir: 'baseDir', 
	patterns: [ 'pattern' ], 
	processorFunction: (data, filename) => data, 
	format: 'object'
});

or as a traditional function call:

let updatedFiles = await processor(baseDir, patterns, processorFunction, format);
  • baseDir: read all files in this directory
  • patterns: match files by glob pattern(s) (note - can be an array of patterns)
  • processorFunction: synchronous or asynchronous callback function to process metadata
async (data, filename) => {
	return data || Promise<data>; // Required when format is string
}
  • format: (Default: object) format of the data as passed to the processing function
    • object: data is parsed into a JavaScript object (support for XML and JSON)
    • string: data is not parsed, instead the raw contents of the file is passed

Return: Promise of a list of updated files (all files in the baseDir that match one or more patterns). File paths are relative to the baseDir.

XML parsing uses the excellent xml2js module, see xml2js NPM docs for data format information.

Glob patterns use the minimatch module, see minimatch NPM docs for examples.

Note: *.json files will be interpreted as JSON. All other files will be interpreted as XML files (to support the various traditional MD API format .layout, .object, etc.).

Be careful not to process files that are not text based - I'm not sure exactly what will happen... definitely nothing good!

Example - Remove enableHistory and enableFeed attribute from object files

let updatedFiles = await processor(
	'force-app/main/default', 
	'**/*.object-meta.xml', 
	(data, filename) => { 
		delete data.enableHistory;
		delete data.enableFeeds;
	}
);

Example - Replace Information labels with Hello in layout files using a string format (i.e. data is not parsed)

let updatedFiles = await processor(
	'force-app/main/default', 
	'**/*.layout-meta.xml', 
	(data, filename) => data.replace('<label>Information</label>', '<label>Hello</label>'),
	'string'
);

This is only an example to demonstrate the difference between object and string format - working with a parsed format is obviously better...

Reader

Read all Salesforce metadata files in a given directory that match a set of patterns.

Specification

Using options parameter:

let files = await reader({
	baseDir: 'baseDir', 
	patterns: [ 'pattern' ]
});

or as a traditional function call:

let files = await reader(baseDir, patterns);
  • baseDir: read all files in this directory
  • patterns: match files by glob pattern(s) (note - can be an array of patterns)

Return: Promise of a list matched file objects (with methods for reading and writing metadata).

Be careful not to read files that are not text based - I'm not sure exactly what will happen... definitely nothing good!

Example - Get all object files

let files = await reader('force-app/main/default', '**/*.object-meta.xml');

Example - Get all object and layout files

let files = await reader({
	baseDir: 'force-app/main/default',
	patterns: [ '**/*.layout-meta.xml', '**/*.object-meta.xml' ]
});

Example - Read and write a file

Read file:

let metadata = await file.read();

Example metadata:

{
	type: 'xml',
	rootKey: 'CustomObject',
	data: {
		'$': { xmlns: 'http://soap.sforce.com/2006/04/metadata' },
		actionOverrides: [
			[Object], [Object],
			[Object], [Object],
			[Object], [Object],
			[Object], [Object],
			[Object], [Object]
		],
		allowInChatterGroups: [ 'false' ],
		compactLayoutAssignment: [ 'SYSTEM' ],
		deploymentStatus: [ 'Deployed' ],
		enableActivities: [ 'false' ],
		enableBulkApi: [ 'true' ],
		enableChangeDataCapture: [ 'false' ],
		enableReports: [ 'false' ],
		enableSearch: [ 'true' ],
		enableSharing: [ 'true' ],
		enableStreamingApi: [ 'true' ],
		label: [ 'Object Name' ],
		nameField: [ [Object] ],
		pluralLabel: [ 'Object Names' ],
		searchLayouts: [ '' ],
		sharingModel: [ 'ReadWrite' ],
		visibility: [ 'Public' ]
	}
}

Write metadata:

let metadata = await file.write();

Writer

Write a Salesforce metadata file. This is designed to be used to create a new metadata file, see Processor and Reader for modifying existing files.

Specification

Using options parameter:

await writer({
	filename: 'filename', 
	metadata: {
		rootKey: 'rootKey',
		data: {},
		type: 'type'
	}
});

or as a traditional function call:

await writer(filename, {
	rootKey: 'rootKey',
	data: {},
	type: 'type'
});
  • filename: full file path of file to be written
  • metadata: metadata object to be built and written to the file
    • rootKey: root node - applicable for XML files e.g. CustomObject
    • data: metadata that will be built and written to the file, the structure of the data will depend on the type
    • type: type of metadata, supported types:
      • xml: data must be in xml2js format
      • json: data must be a standard JavaScript object that will be passed to JSON.stringify
      • string: data must be a string and will be written to the file as-is (no building)

Example - Write a text file

await writer('force-app/main/default/myFile.txt', {
	data: 'Hello world',
	type: 'string'
});

Example - Write a JSON file

await writer('force-app/main/default/myFile.json', {
	data: {
		property: 'value'
	},
	type: 'json'
});

Example - Write an XML file

await writer('force-app/main/default/myFile.xml', {
	rootKey: 'CustomObject',
	data: {
		'$': { xmlns: 'http://soap.sforce.com/2006/04/metadata' },
		allowInChatterGroups: [ 'false' ],
		compactLayoutAssignment: [ 'SYSTEM' ],
		deploymentStatus: [ 'Deployed' ],
		enableActivities: [ 'false' ],
		enableBulkApi: [ 'true' ],
		enableChangeDataCapture: [ 'false' ],
		enableReports: [ 'false' ],
		enableSearch: [ 'true' ],
		enableSharing: [ 'true' ],
		enableStreamingApi: [ 'true' ],
		label: [ 'Object Name' ],
		pluralLabel: [ 'Object Names' ],
		sharingModel: [ 'ReadWrite' ],
		visibility: [ 'Public' ]
	},
	type: 'xml'
});