Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LWC Metadata Browser example #297

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
16 changes: 16 additions & 0 deletions sfdx-project/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
**/lwc/**/*.css
**/lwc/**/*.html
**/lwc/**/*.json
**/lwc/**/*.svg
**/lwc/**/*.xml
**/aura/**/*.auradoc
**/aura/**/*.cmp
**/aura/**/*.css
**/aura/**/*.design
**/aura/**/*.evt
**/aura/**/*.json
**/aura/**/*.svg
**/aura/**/*.tokens
**/aura/**/*.xml
**/aura/**/*.app
.sfdx
12 changes: 12 additions & 0 deletions sfdx-project/.forceignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# List files or directories below to ignore them when running force:source:push, force:source:pull, and force:source:status
# More information: https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_exclude_source.htm
#

package.xml

# LWC configuration files
**/jsconfig.json
**/.eslintrc.json

# LWC Jest
**/__tests__/**
45 changes: 45 additions & 0 deletions sfdx-project/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# This file is used for Git repositories to specify intentionally untracked files that Git should ignore.
# If you are not using git, you can delete this file. For more information see: https://git-scm.com/docs/gitignore
# For useful gitignore templates see: https://github.com/github/gitignore

# Salesforce cache
.sf/
.sfdx/
.localdevserver/
deploy-options.json

# LWC VSCode autocomplete
**/lwc/jsconfig.json

# LWC Jest coverage reports
coverage/

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Dependency directories
node_modules/

# Eslint cache
.eslintcache

# MacOS system files
.DS_Store

# Windows system files
Thumbs.db
ehthumbs.db
[Dd]esktop.ini
$RECYCLE.BIN/

# Local environment variables
.env

# Python Salesforce Functions
**/__pycache__/
**/.venv/
**/venv/
4 changes: 4 additions & 0 deletions sfdx-project/.husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npm run precommit
10 changes: 10 additions & 0 deletions sfdx-project/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# List files or directories below to ignore them when running prettier
# More information: https://prettier.io/docs/en/ignore.html
#

**/staticresources/**
.localdevserver
.sfdx
.vscode

coverage/
13 changes: 13 additions & 0 deletions sfdx-project/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"trailingComma": "none",
"overrides": [
{
"files": "**/lwc/**/*.html",
"options": { "parser": "lwc" }
},
{
"files": "*.{cmp,page,component}",
"options": { "parser": "html" }
}
]
}
9 changes: 9 additions & 0 deletions sfdx-project/.vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"recommendations": [
"salesforce.salesforcedx-vscode",
"redhat.vscode-xml",
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"financialforce.lana"
]
}
16 changes: 16 additions & 0 deletions sfdx-project/.vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Launch Apex Replay Debugger",
"type": "apex-replay",
"request": "launch",
"logFile": "${command:AskForLogFileName}",
"stopOnEntry": true,
"trace": true
}
]
}
7 changes: 7 additions & 0 deletions sfdx-project/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"search.exclude": {
"**/node_modules": true,
"**/bower_components": true,
"**/.sfdx": true
}
}
18 changes: 18 additions & 0 deletions sfdx-project/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Salesforce DX Project: Next Steps

Now that you’ve created a Salesforce DX project, what’s next? Here are some documentation resources to get you started.

## How Do You Plan to Deploy Your Changes?

Do you want to deploy a set of changes, or create a self-contained application? Choose a [development model](https://developer.salesforce.com/tools/vscode/en/user-guide/development-models).

## Configure Your Salesforce DX Project

The `sfdx-project.json` file contains useful configuration information for your project. See [Salesforce DX Project Configuration](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_ws_config.htm) in the _Salesforce DX Developer Guide_ for details about this file.

## Read All About It

- [Salesforce Extensions Documentation](https://developer.salesforce.com/tools/vscode/)
- [Salesforce CLI Setup Guide](https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_setup_intro.htm)
- [Salesforce DX Developer Guide](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_intro.htm)
- [Salesforce CLI Command Reference](https://developer.salesforce.com/docs/atlas.en-us.sfdx_cli_reference.meta/sfdx_cli_reference/cli_reference.htm)
13 changes: 13 additions & 0 deletions sfdx-project/config/project-scratch-def.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"orgName": "Certinia Apex Metadata API",
"edition": "Developer",
"features": ["EnableSetPasswordInApi"],
"settings": {
"lightningExperienceSettings": {
"enableS1DesktopEnabled": true
},
"mobileSettings": {
"enableS1EncryptedStoragePref2": false
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<CustomApplication xmlns="http://soap.sforce.com/2006/04/metadata">
<brand>
<headerColor>#0070D2</headerColor>
<shouldOverrideOrgTheme>false</shouldOverrideOrgTheme>
</brand>
<formFactors>Small</formFactors>
<formFactors>Large</formFactors>
<isNavAutoTempTabsDisabled>false</isNavAutoTempTabsDisabled>
<isNavPersonalizationDisabled>false</isNavPersonalizationDisabled>
<isNavTabPersistenceDisabled>false</isNavTabPersistenceDisabled>
<label>Metadata API</label>
<navType>Standard</navType>
<tabs>standard-home</tabs>
<tabs>MetadataBrowser</tabs>
<tabs>MetadataDeployDemo</tabs>
<tabs>MetadataRetrieveDemo</tabs>
<tabs>Metadata_Browser_LWC</tabs>
<uiType>Lightning</uiType>
</CustomApplication>
8 changes: 8 additions & 0 deletions sfdx-project/force-app/main/default/aura/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"plugins": ["@salesforce/eslint-plugin-aura"],
"extends": ["plugin:@salesforce/eslint-plugin-aura/recommended"],
"rules": {
"vars-on-top": "off",
"no-unused-expressions": "off"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
public class MetadataBrowserLwcController {
public static final Double API_VERSION = 58.0;

@Auraenabled(cacheable=true)
public static String retrieveDescribeMetadata() {
MetadataService.MetadataPort service = createService();
MetadataService.DescribeMetadataResult descMetaResult = service.describeMetadata(API_VERSION);
System.debug('descMetaResult.organizationNamespace: ' + descMetaResult.organizationNamespace);
System.debug('descMetaResult.partialSaveAllowed: ' + descMetaResult.partialSaveAllowed);
System.debug('descMetaResult.testRequired: ' + descMetaResult.testRequired);
for(MetadataService.DescribeMetadataObject descMetaObj : descMetaResult.metadataObjects) {
System.debug('descMetaObj.directoryName: ' + descMetaObj.directoryName);
System.debug('descMetaObj.inFolder: ' + descMetaObj.inFolder);
System.debug('descMetaObj.metaFile: ' + descMetaObj.metaFile);
System.debug('descMetaObj.suffix: ' + descMetaObj.suffix);
System.debug('descMetaObj.xmlName: ' + descMetaObj.xmlName);
if(descMetaObj.childXmlNames != null) {
for(String childXmlName : descMetaObj.childXmlNames) {
System.debug('childXmlName: ' + childXmlName);
}
}
}
String descMetaResultJson = JSON.serialize(descMetaResult);
return descMetaResultJson;
}

@Auraenabled(cacheable=true)
public static String retrieveListMetadata(String metadataTypeName) {
MetadataService.ListMetadataQuery mdQuery = new MetadataService.ListMetadataQuery();
mdQuery.folder = '';
mdQuery.type_x = metadataTypeName;
List<MetadataService.ListMetadataQuery> mdQueries = new List<MetadataService.ListMetadataQuery>{mdQuery};

MetadataService.MetadataPort service = createService();
List<MetadataService.FileProperties> listMetaResults = service.listMetadata(mdQueries, API_VERSION);
String listMetaResultJson = JSON.serialize(listMetaResults);
return listMetaResultJson;
}

private static MetadataService.MetadataPort createService() {
MetadataService.MetadataPort service = new MetadataService.MetadataPort();
service.SessionHeader = new MetadataService.SessionHeader_element();
service.SessionHeader.sessionId = getSessionId();
return service;
}

private static String getSessionId() {
return Page.sessionid.getContent().toString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>59.0</apiVersion>
<status>Active</status>
</ApexClass>
117 changes: 117 additions & 0 deletions sfdx-project/force-app/main/default/classes/MetadataDataController.cls
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/**
* Copyright (c) 2012, FinancialForce.com, inc
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the FinancialForce.com, inc nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**/

public with sharing class MetadataDataController
{
private static final Integer METADATA_API_VERSION =
Integer.valueOf(new MetadataService.MetadataPort().endpoint_x.substringAfterLast('/'));

public String Data {get; set;}

public PageReference constructResponse()
{
try {
List<Node> nodes = new List<Node>();
String node = ApexPages.currentPage().getParameters().get('node');
if(node=='root')
{
// List available Metadata Types via the 'describeMetadata' API call
MetadataService.MetadataPort service = MetadataServiceExamples.createService();
MetadataService.DescribeMetadataResult describeResult = service.describeMetadata(METADATA_API_VERSION);
for(MetadataService.DescribeMetadataObject metadataObject : describeResult.metadataObjects)
{
nodes.add(new FolderNode(metadataObject.xmlName, metadataObject.xmlName, false, null));
// Include child Metadata Types (such as CustomField, ValidationRule etc..)
if(metadataObject.childXmlNames!=null)
for(String childXmlName : metadataObject.childXmlNames)
if(childXmlName!=null)
nodes.add(new FolderNode(childXmlName, childXmlName, false, null));
}
}
else
{
// List Metadata for the given type via the listMetadata API call
MetadataService.MetadataPort service = MetadataServiceExamples.createService();
List<MetadataService.ListMetadataQuery> queries = new List<MetadataService.ListMetadataQuery>();
MetadataService.ListMetadataQuery query = new MetadataService.ListMetadataQuery();
query.type_x = node;
queries.add(query);
MetadataService.FileProperties[] fileProperties = service.listMetadata(queries, METADATA_API_VERSION);

// Emit leaf nodes (ensure unique IDs)
if(fileProperties!=null) {
Integer index = 0;
for(MetadataService.FileProperties fileProperty : fileProperties)
nodes.add(new LeafNode(fileProperty.fullName + ':' + index++, EncodingUtil.urlDecode(fileProperty.fullName, 'UTF-8'), false));
}
}
Data = JSON.serialize(nodes);
}
catch (Exception e) {
Data = JSON.serialize(new List<Node> { new FolderNode('error', e.getMessage(), false, null) });
}
return null;
}

public abstract class Node
{
public String id;
public String text;
public String cls;
public boolean leaf;
public boolean checked;
public boolean expanded;
public List<Node> children;
}

public class FolderNode extends Node
{
public FolderNode(String id, String text, boolean expanded, List<Node> children)
{
this.id = id;
this.text = text;
this.cls = 'folder';
this.leaf = false;
this.checked = false;
this.expanded = expanded;
this.children = children;
}
}

public class LeafNode extends Node
{
public LeafNode(String id, String text, boolean checked)
{
this.id = id;
this.text = text;
this.cls = null;
this.leaf = true;
this.checked = checked;
this.expanded = false;
this.children = null;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>42.0</apiVersion>
<status>Active</status>
</ApexClass>
Loading