Skip to content

Instantly share code, notes, and snippets.

@yusuke8609
Last active October 18, 2022 11:23
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save yusuke8609/ab6f087a0a645a106a6f to your computer and use it in GitHub Desktop.
Save yusuke8609/ab6f087a0a645a106a6f to your computer and use it in GitHub Desktop.
{
"name": "retrieve_folders",
"dependencies": {
"bluebird": "^2.4.2",
"dotenv": "^0.4.0",
"jsforce": "^1.3.1",
"lodash": "^2.4.1",
"underscore": "^1.7.0",
"unzip": "^0.1.11"
}
}
jsforce = require 'jsforce'
Promise = require 'bluebird'
unzip = require 'unzip'
_ = require 'underscore'
require('dotenv').load()
username = process.env.SALESFORCE_USERNAME
password = process.env.SALESFORCE_PASSWORD
host = process.env.SALESFORCE_HOST || 'login.salesforce.com'
host = "https://#{host}" unless host.match(/^https:\/\//)
# 各フォルダタイプのMetadata名と、フォルダ内のファイルのMetadata名
type_of_folder =
DocumentFolder: 'Document'
DashboardFolder: 'Dashboard'
EmailFolder: 'EmailTemplate'
ReportFolder: 'Report'
_.mixin
# listMetadataは3つまでしか対象を指定できないので
split: (array, each_size) ->
for i in [0...array.length] by each_size
array.slice(i, i + each_size)
# listMetadataの結果が1件だと配列にならないので
wrap_array: (x) ->
return [] unless x?
if x instanceof Array then x else [x]
# 3つずつ取得したlisetMetadataを統合する関数(Array::reduceで使う)
list_metadata = (connection) ->
(promise, queries) ->
promise.then (all_props) ->
connection.metadata.list(queries)
.then (props) ->
all_props.concat(_.wrap_array(props))
connection = new jsforce.Connection loginUrl: host
connection.login(username, password)
.then ->
# フォルダタイプ毎のlistMetadata
_.chain(Object.keys(type_of_folder))
.map (e) -> type: e
.split(3)
.reduce(list_metadata(connection), Promise.resolve([]))
.value()
.then (folder_metadata) ->
# 各フォルダ内のファイルのlistMetadata
_.chain(folder_metadata)
.map (e) -> type: type_of_folder[e.type], folder: e.fullName
.split(3)
.reduce(list_metadata(connection), Promise.resolve([]))
.value()
.then (file_metadata) ->
# folderのlistMetadataも次に持っていく
Promise.resolve([folder_metadata, file_metadata])
.then ([folder_metadata, file_metadata]) ->
folder_metadata = folder_metadata.map (e) ->
type: type_of_folder[e.type], fullName: e.fullName
types = _.chain(folder_metadata).concat(file_metadata)
.groupBy('type')
.map (members, name) ->
members = members.map (e) -> e.fullName
name: name, members: members
.value()
unpackaged = types: types, version: '32.0'
connection.metadata.retrieve(unpackaged: unpackaged)
.stream().pipe(unzip.Extract(path: '.'))
.fail ->
console.error arguments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment