Skip to content

Commit 770cee4

Browse files
authored
feat: support Field History Tracking for managed Person Account fields (#737)
Example: `CustomField:Account.myNamespace__PreferredName__pc`
1 parent a851e07 commit 770cee4

1 file changed

Lines changed: 54 additions & 24 deletions

File tree

src/plugins/history-tracking/index.ts

Lines changed: 54 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,38 @@ export class HistoryTracking extends BrowserforcePlugin {
156156
}
157157
}
158158

159+
private async queryCustomFieldsAndPopulateMap(
160+
fieldApiNameTuples: [string, string | undefined][],
161+
tableEnumOrId: string,
162+
suffix: string,
163+
fieldSelectorByFieldApiName: Map<string, string>,
164+
): Promise<void> {
165+
const developerNameConditions = fieldApiNameTuples.map(([apiname, namespace]) =>
166+
namespace
167+
? `(DeveloperName ='${apiname}' AND NamespacePrefix ='${namespace}')`
168+
: `(DeveloperName = '${apiname}')`,
169+
);
170+
const customFieldsQuery = await this.browserforce.connection.tooling.query(
171+
`SELECT Id, DeveloperName, NamespacePrefix FROM CustomField WHERE (${developerNameConditions.join(' OR ')}) AND TableEnumOrId = '${tableEnumOrId}' ORDER By CreatedDate ASC`,
172+
);
173+
174+
for (const customField of customFieldsQuery.records) {
175+
const fieldApiName = `${customField.NamespacePrefix ? `${customField.NamespacePrefix}__` : ''}${customField.DeveloperName}${suffix}`;
176+
fieldSelectorByFieldApiName.set(fieldApiName, customField.Id.substring(0, 15));
177+
}
178+
}
179+
180+
private parseNamespacedFieldApiName(
181+
fieldApiName: string,
182+
suffix: string,
183+
): [apiname: string, namespace: string | undefined] {
184+
const fieldNameWithoutSuffix = fieldApiName.replace(suffix, '');
185+
const parts = fieldNameWithoutSuffix.split('__');
186+
const namespace = parts.length > 1 ? parts[0] : undefined;
187+
const apiname = parts.length > 1 ? parts.slice(1).join('__') : parts[0];
188+
return [apiname, namespace];
189+
}
190+
159191
private async getFieldSelectorByFieldApiName(
160192
tableEnumOrId: String,
161193
fieldHistoryTrackingConfigs: FieldHistoryTrackingConfig[],
@@ -168,13 +200,15 @@ export class HistoryTracking extends BrowserforcePlugin {
168200
for (const fieldHistoryTrackingConfig of fieldHistoryTrackingConfigs) {
169201
// If this is a person account field, we must do special handling for this
170202
if (tableEnumOrId === 'Account' && fieldHistoryTrackingConfig.fieldApiName.includes('__pc')) {
171-
personAccountFieldApiNames.push(`'${fieldHistoryTrackingConfig.fieldApiName.replace('__pc', '')}'`);
203+
personAccountFieldApiNames.push(
204+
this.parseNamespacedFieldApiName(fieldHistoryTrackingConfig.fieldApiName, '__pc'),
205+
);
172206
continue;
173207
}
174208

175209
// If this is a custom field, we must query for the Field Id
176210
if (fieldHistoryTrackingConfig.fieldApiName.includes('__c')) {
177-
customFieldApiNames.push(`'${fieldHistoryTrackingConfig.fieldApiName.replace('__c', '')}'`);
211+
customFieldApiNames.push(this.parseNamespacedFieldApiName(fieldHistoryTrackingConfig.fieldApiName, '__c'));
178212
continue;
179213
}
180214

@@ -189,32 +223,23 @@ export class HistoryTracking extends BrowserforcePlugin {
189223
if (personAccountFieldApiNames.length > 0) {
190224
// NOTE: Unfortunately this includes deleted records
191225
// WORKAROUND: ORDER BY CreatedDate
192-
const personAccountFieldsQuery = await this.browserforce.connection.tooling.query(
193-
`SELECT Id, DeveloperName FROM CustomField WHERE DeveloperName IN (${personAccountFieldApiNames.join(
194-
',',
195-
)}) AND TableEnumOrId = 'Contact' ORDER By CreatedDate ASC`,
226+
await this.queryCustomFieldsAndPopulateMap(
227+
personAccountFieldApiNames,
228+
'Contact',
229+
'__pc',
230+
fieldSelectorByFieldApiName,
196231
);
197-
198-
for (const personAccountField of personAccountFieldsQuery.records) {
199-
fieldSelectorByFieldApiName.set(
200-
`${personAccountField.DeveloperName}__pc`,
201-
personAccountField.Id.substring(0, 15),
202-
);
203-
}
204232
}
205233

206234
if (customFieldApiNames.length > 0) {
207235
// NOTE: Unfortunately this includes deleted records
208236
// WORKAROUND: ORDER BY CreatedDate
209-
const customFieldsQuery = await this.browserforce.connection.tooling.query(
210-
`SELECT Id, DeveloperName FROM CustomField WHERE DeveloperName IN (${customFieldApiNames.join(
211-
',',
212-
)}) AND TableEnumOrId = '${tableEnumOrId}' ORDER By CreatedDate ASC`,
237+
await this.queryCustomFieldsAndPopulateMap(
238+
customFieldApiNames,
239+
tableEnumOrId as string,
240+
'__c',
241+
fieldSelectorByFieldApiName,
213242
);
214-
215-
for (const customField of customFieldsQuery.records) {
216-
fieldSelectorByFieldApiName.set(`${customField.DeveloperName}__c`, customField.Id.substring(0, 15));
217-
}
218243
}
219244

220245
return fieldSelectorByFieldApiName;
@@ -228,7 +253,7 @@ export class HistoryTracking extends BrowserforcePlugin {
228253
for (const historyTrackingConfig of historyTrackingConfigs) {
229254
// If it is a custom object, the CustomField.TableEnumOrId is the Object Id
230255
if (historyTrackingConfig.objectApiName.includes('__c')) {
231-
customObjectApiNames.push(`'${historyTrackingConfig.objectApiName.replace('__c', '')}'`);
256+
customObjectApiNames.push(this.parseNamespacedFieldApiName(historyTrackingConfig.objectApiName, '__c'));
232257
continue;
233258
}
234259

@@ -242,9 +267,14 @@ export class HistoryTracking extends BrowserforcePlugin {
242267

243268
// NOTE: Unfortunately this includes deleted records
244269
// WORKAROUND: ORDER BY CreatedDate
270+
const customObjectDeveloperNames = customObjectApiNames.map(([apiname, namespace]) =>
271+
namespace
272+
? `(DeveloperName = '${apiname}' AND NamespacePrefix = '${namespace}')`
273+
: `(DeveloperName = '${apiname}')`,
274+
);
245275
const customObjectsQuery = await this.browserforce.connection.tooling.query(
246-
`SELECT Id, DeveloperName FROM CustomObject WHERE DeveloperName IN (${customObjectApiNames.join(
247-
',',
276+
`SELECT Id, DeveloperName FROM CustomObject WHERE (${customObjectDeveloperNames.join(
277+
' OR ',
248278
)}) ORDER BY CreatedDate ASC`,
249279
);
250280

0 commit comments

Comments
 (0)