スクラッチ組織定義ファイルにあるsettings
の意味がよく分かってなかった。
処理を追ってみると、settings
は設定メタデータがそのまま指定できるものだった。
設定 | メタデータ API 開発者ガイド | Salesforce Developers
例
例えばSalesforce DXプロジェクトを作成したときに作成されるスクラッチ組織定義ファイルのsettings
:
"settings": {
"lightningExperienceSettings": {
"enableS1DesktopEnabled": true
},
"mobileSettings": {
"enableS1EncryptedStoragePref2": false
}
}
これは:
-
LightningExperienceSettings
メタデータのenableS1DesktopEnabled
項目を有効化- LightningExperienceSettings | メタデータ API 開発者ガイド | Salesforce Developers
-
組織で Lightning Experience が有効化されているか (true)、否か (false) を示します。有効化されると、この設定をユーザインターフェースや API によって無効にすることはできません。「組織の Lightning Experience の有効化」を参照してください。
-
MobileSettings
メタデータのenableS1EncryptedStoragePref2
を無効化- MobileSettings | メタデータ API 開発者ガイド | Salesforce Developers
-
Salesforce モバイル Web がパフォーマンスを改善するために安全で永続的なブラウザキャッシュを使用するか (true)、否か (false) を示します。デフォルト値は true です。
API バージョン 47.0 以降で利用できます。
という設定になる。
例えばもし管理者による代理ログインを有効化したい場合は、SecuritySettings
メタデータのenableAdminLoginAsAnyUser
項目を有効化する。
"settings": {
+ "securitySettings": {
+ "enableAdminLoginAsAnyUser": true
+ },
"lightningExperienceSettings": {
"enableS1DesktopEnabled": true
},
"mobileSettings": {
"enableS1EncryptedStoragePref2": false
}
}
SecuritySettings | メタデータ API 開発者ガイド | Salesforce Developers
仕組み
settings
がどのようにスクラッチ組織に反映されるか処理の流れを追ってみる。
先に書くと大まかな流れは次のようになっていた:
- スクラッチ組織定義ファイルをもとに
ScratchOrgInfo
オブジェクトレコードを作成(=スクラッチ組織作成) -
settings
から設定メタデータのXMLファイルを生成 - 設定メタデータのXMLファイルをスクラッチ組織にデプロイ
スクラッチ組織の作成はsf org create scratch
コマンドで行うので、orgプラグインの実装を追う。
sf org create scratch
コマンドの実体はこれ:
run()
メソッドの中でscratchOrgCreate
を呼んでる:
const { username, scratchOrgInfo, authFields, warnings } = await scratchOrgCreate(createCommandOptions);
scratchOrgCreate
は@salesforce/core
パッケージ(sfdx-core
プロジェクト)にあるので、そっちを見ていく。
scratchOrgCreate
を追っていくと次の処理がある:
const [scratchOrgInfoRequestResult, signupTargetLoginUrlConfig] = await Promise.all([
// creates the scratch org info in the devhub
requestScratchOrgCreation(hubOrg, scratchOrgInfo, settingsGenerator),
getSignupTargetLoginUrl(),
]);
呼んでるrequestScratchOrgCreation
はScratchOrgInfo
オブジェクトのレコードを作成する関数:
ScratchOrgInfo
オブジェクトのレコードを作成するとスクラッチ組織が作成されるようになってる。
参考: Salesforce DXでAPIからスクラッチ組織を作成する - Qiita
スクラッチ組織ができたら後続の処理で設定をデプロイする:
const [authInfo] = await Promise.all([
resolveUrl(scratchOrgAuthInfo),
deploySettings(
scratchOrg,
settingsGenerator,
apiversion ??
configAggregator.getPropertyValue(OrgConfigProperties.ORG_API_VERSION) ??
(await scratchOrg.retrieveMaxApiVersion()),
// some of our "wait" time has already been used. Calculate how much remains that we can spend on the deployment.
Duration.milliseconds(wait.milliseconds - (Date.now() - startTimestamp))
),
]);
deploySettings
はここ:
export const deploySettings = async (
scratchOrg: Org,
orgSettings: SettingsGenerator,
apiVersion: string,
timeout: Duration = Duration.minutes(10)
): Promise<void> => {
const logger = await Logger.child('scratchOrgInfoApi-deploySettings');
if (orgSettings.hasSettings()) {
// deploy the settings to the newly created scratch org
logger.debug(`deploying scratch org settings with apiVersion ${apiVersion}`);
try {
await orgSettings.createDeploy();
await orgSettings.deploySettingsViaFolder(scratchOrg, apiVersion, timeout);
// updating the revision num to zero during org:creation if source members are created during org:create.
// This only happens for some specific scratch org definition file.
await updateRevisionCounterToZero(scratchOrg);
logger.trace('Settings deployed to org');
} catch (error) {
throw SfError.wrap(error as Error);
}
}
};
SettingGenerator
のcreateDeploy()
を呼んでる:
public async createDeploy(): Promise<void> {
const settingsDir = path.join(this.shapeDirName, 'settings');
const objectsDir = path.join(this.shapeDirName, 'objects');
await Promise.all([
this.writeSettingsIfNeeded(settingsDir),
this.writeObjectSettingsIfNeeded(objectsDir, this.allRecordTypes, this.allBusinessProcesses),
]);
}
writeSettingsIfNeeded()
はこちら:
private async writeSettingsIfNeeded(settingsDir: string): Promise<void> {
if (this.settingData) {
await Promise.all(
Object.entries(this.settingData).map(([item, value]) => {
const typeName = upperFirst(item);
const fname = typeName.replace('Settings', '');
const fileContent = js2xmlparser.parse(typeName, value);
return this.writer.addToStore(fileContent, path.join(settingsDir, fname + '.settings'));
})
);
}
}
js2xmlparser.parse()
を呼んだりしてるのでXMLを作ってる様子。
createDeploy()
のあとdeploySettingsViaFolder()
メソッドを呼んで設定をスクラッチ組織にデプロイしている。
public async deploySettingsViaFolder(
scratchOrg: Org,
apiVersion: string,
timeout: Duration = Duration.minutes(10)
): Promise<void> {
...
const connection = scratchOrg.getConnection();
logger.debug(`deploying to apiVersion: ${apiVersion}`);
connection.setApiVersion(apiVersion);
const { id } = await connection.deploy(this.writer.buffer, {});
...
まとめ
settings
はスクラッチ組織定義ファイルのドキュメントでも明確な説明がなくて、何を書けばいいかよくわからずググってそれらしい情報を探して試してを繰り返していた。
プラグインの実装を確認して正体が設定メタデータとはっきりしたので、これからはメタデータのドキュメントをもとにsettings
を記述できるようになった。