sfdx-hardis 6.12.9 → 6.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -3
- package/lib/commands/hardis/org/purge/profile.d.ts +53 -0
- package/lib/commands/hardis/org/purge/profile.js +384 -0
- package/lib/commands/hardis/org/purge/profile.js.map +1 -0
- package/lib/commands/hardis/project/clean/profiles-extract.d.ts +103 -0
- package/lib/commands/hardis/project/clean/profiles-extract.js +605 -0
- package/lib/commands/hardis/project/clean/profiles-extract.js.map +1 -0
- package/lib/common/utils/filesUtils.d.ts +5 -0
- package/lib/common/utils/filesUtils.js +64 -1
- package/lib/common/utils/filesUtils.js.map +1 -1
- package/lib/common/utils/orgUtils.d.ts +1 -1
- package/lib/common/utils/orgUtils.js +34 -3
- package/lib/common/utils/orgUtils.js.map +1 -1
- package/lib/hooks/prerun/check-dependencies.js +5 -3
- package/lib/hooks/prerun/check-dependencies.js.map +1 -1
- package/oclif.lock +78 -142
- package/oclif.manifest.json +1196 -981
- package/package.json +3 -4
|
@@ -0,0 +1,605 @@
|
|
|
1
|
+
// QUESTION: Where are the objects extracted in this code?
|
|
2
|
+
// ANSWER: The objects are extracted in the generateObjectsList function.
|
|
3
|
+
// This function calls conn.describeGlobal() to get all SObjects, then queries each one to check if it has records.
|
|
4
|
+
// The user is then prompted to select which objects to extract. The selected objects are returned and used in the rest of the extraction process.
|
|
5
|
+
import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
|
|
6
|
+
import { prompts } from '../../../../common/utils/prompts.js';
|
|
7
|
+
import { uxLog } from '../../../../common/utils/index.js';
|
|
8
|
+
import c from 'chalk';
|
|
9
|
+
import { generateCsvFile, generateReportPath, createXlsxFromCsvFiles } from '../../../../common/utils/filesUtils.js';
|
|
10
|
+
import { bulkQuery } from '../../../../common/utils/apiUtils.js';
|
|
11
|
+
import * as path from 'path';
|
|
12
|
+
import { getReportDirectory } from '../../../../config/index.js';
|
|
13
|
+
import { Messages } from '@salesforce/core';
|
|
14
|
+
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
|
|
15
|
+
const messages = Messages.loadMessages('sfdx-hardis', 'org');
|
|
16
|
+
// Main command class for extracting Salesforce org profiles and related metadata
|
|
17
|
+
export default class ProfilesExtract extends SfCommand {
|
|
18
|
+
static description = `
|
|
19
|
+
## Command Behavior
|
|
20
|
+
|
|
21
|
+
**Guides administrators through extracting Salesforce profiles, personas, and related metadata into structured CSV/XLSX deliverables.**
|
|
22
|
+
|
|
23
|
+
The command inventories SObjects that contain data, lets the user pick the ones to document, and then produces persona-centric spreadsheets that cover users, personas, relationships, record types, apps, permissions, tabs, fields, and permission sets. The output consolidates everything into both CSV files and a single Excel workbook, making it easy to audit access models or prepare remediation plans.
|
|
24
|
+
|
|
25
|
+
Key capabilities:
|
|
26
|
+
|
|
27
|
+
- **Interactive object discovery:** Lists queryable objects with records and allows multi-selection.
|
|
28
|
+
- **Persona modeling:** Lets users define the number of personas and generates cross-object matrices that leverage Excel formulas for faster updates.
|
|
29
|
+
- **Comprehensive metadata export:** Captures users, record types, apps, permissions, tabs, fields, and permission sets with persona/profile visibility indicators.
|
|
30
|
+
- **Profile field access coverage:** Retrieves FieldPermissions to surface read/edit status per profile and field.
|
|
31
|
+
- **Consolidated reporting:** Produces standalone CSVs plus an aggregated XLSX stored in the report directory.
|
|
32
|
+
|
|
33
|
+
<details markdown="1">
|
|
34
|
+
<summary>Technical explanations</summary>
|
|
35
|
+
|
|
36
|
+
- **Salesforce connectivity:** Uses the requested target org connection from \`Flags.requiredOrg\` to fetch metadata and records.
|
|
37
|
+
- **Bulk/REST queries:** Relies on \`bulkQuery\` and standard SOQL to evaluate record counts and pull FieldPermissions, Users, RecordTypes, Applications, Tabs, and PermissionSets.
|
|
38
|
+
- **Describe calls:** Invokes \`describeGlobal\` and \`describeSObject\` to enumerate objects and field-level metadata, including picklists and formulas.
|
|
39
|
+
- **Prompt-driven input:** Utilizes the shared \`prompts\` utility to collect object selections and persona counts, ensuring consistent CLI UX.
|
|
40
|
+
- **Reporting pipeline:** Writes intermediate CSV files via \`generateCsvFile\`, stores them under the report directory from \`getReportDirectory\`, and finally merges them using \`createXlsxFromCsvFiles\`.
|
|
41
|
+
- **Logging & diagnostics:** Uses \`uxLog\` with chalk coloring for progress, warnings, and debug output, integrating with the project-wide logging style.
|
|
42
|
+
|
|
43
|
+
</details>
|
|
44
|
+
`;
|
|
45
|
+
static examples = [
|
|
46
|
+
`$ sf hardis:project:clean:profiles-extract`,
|
|
47
|
+
`$ sf hardis:project:clean:profiles-extract --target-org my-org`,
|
|
48
|
+
];
|
|
49
|
+
/* jscpd:ignore-start */
|
|
50
|
+
static flags = {
|
|
51
|
+
'target-org': Flags.requiredOrg({
|
|
52
|
+
char: 'o',
|
|
53
|
+
description: 'The target Salesforce org to fetch SObjects from.',
|
|
54
|
+
}),
|
|
55
|
+
debug: Flags.boolean({
|
|
56
|
+
char: 'd',
|
|
57
|
+
default: false,
|
|
58
|
+
description: messages.getMessage('debugMode'),
|
|
59
|
+
}),
|
|
60
|
+
websocket: Flags.string({
|
|
61
|
+
description: messages.getMessage('websocket'),
|
|
62
|
+
}),
|
|
63
|
+
skipauth: Flags.boolean({
|
|
64
|
+
description: 'Skip authentication check when a default username is required',
|
|
65
|
+
}),
|
|
66
|
+
};
|
|
67
|
+
/* jscpd:ignore-end */
|
|
68
|
+
csvFiles = [];
|
|
69
|
+
outputFile = '';
|
|
70
|
+
activeProfileNames = new Set();
|
|
71
|
+
/**
|
|
72
|
+
* Main entry point for the command. Orchestrates the extraction process:
|
|
73
|
+
* - Prompts user to select objects
|
|
74
|
+
* - Extracts users, personas, relations, record types, apps, permissions, tabs, and object fields
|
|
75
|
+
* - Generates CSV and XLSX reports
|
|
76
|
+
*/
|
|
77
|
+
async run() {
|
|
78
|
+
const { flags } = await this.parse(ProfilesExtract);
|
|
79
|
+
const conn = flags['target-org'].getConnection();
|
|
80
|
+
let selectedObjects = [];
|
|
81
|
+
let numberOfPersonas = 1;
|
|
82
|
+
try {
|
|
83
|
+
selectedObjects = await this.generateObjectsList(conn);
|
|
84
|
+
uxLog("action", this, c.green('Handling extract of Users...'));
|
|
85
|
+
await this.generateUsersExtract(conn);
|
|
86
|
+
numberOfPersonas = await this.generatePersonaExtract();
|
|
87
|
+
uxLog("action", this, c.green(`Generating extracts for ${numberOfPersonas} personas...`));
|
|
88
|
+
await this.generateRelationExtract(selectedObjects, numberOfPersonas);
|
|
89
|
+
await this.generateRTExtract(conn, selectedObjects, numberOfPersonas);
|
|
90
|
+
await this.generateAppsExtract(conn, numberOfPersonas);
|
|
91
|
+
await this.generatePermissionsExtract(conn, numberOfPersonas);
|
|
92
|
+
await this.generateTabsExtract(conn, numberOfPersonas);
|
|
93
|
+
await this.generatePermissionSetsExtract(conn, numberOfPersonas);
|
|
94
|
+
// 1. Extract profile field access and get all profiles
|
|
95
|
+
uxLog("action", this, c.green('Extracting profile field access...'));
|
|
96
|
+
const profileFieldAccess = await this.getProfileFieldAccessData(conn, selectedObjects);
|
|
97
|
+
const profileNames = Array.from(new Set(profileFieldAccess.map(r => r.Profile).filter(Boolean)));
|
|
98
|
+
// 2. Pass profileNames to generateObjectFieldsExtract
|
|
99
|
+
await this.generateObjectFieldsExtract(conn, selectedObjects, numberOfPersonas, profileNames, profileFieldAccess);
|
|
100
|
+
// 3. Write the profile field access CSV (as before)
|
|
101
|
+
if (profileFieldAccess.length > 0) {
|
|
102
|
+
const reportDir = await getReportDirectory();
|
|
103
|
+
this.outputFile = path.join(reportDir, 'ProfileFieldAccess.csv');
|
|
104
|
+
await generateCsvFile(profileFieldAccess, this.outputFile, { fileTitle: 'Profile Field Access', noExcel: true });
|
|
105
|
+
this.csvFiles.push(this.outputFile);
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
uxLog('log', this, c.yellow('No profile field access records found, skipping ProfileFieldAccess.csv.'));
|
|
109
|
+
}
|
|
110
|
+
this.outputFile = '';
|
|
111
|
+
this.outputFile = await generateReportPath('profiles-extract', this.outputFile);
|
|
112
|
+
uxLog("action", this, c.green('Generating final XLSX report...'));
|
|
113
|
+
await createXlsxFromCsvFiles(this.csvFiles, this.outputFile, { fileTitle: 'profiles extract' });
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
uxLog('log', this, c.red('Failed to fetch SObjects.'));
|
|
117
|
+
throw error;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Extracts field-level access for profiles using FieldPermissions object.
|
|
122
|
+
* Generates a CSV report of profile-field access.
|
|
123
|
+
* @param conn Salesforce connection
|
|
124
|
+
*/
|
|
125
|
+
// Returns all profile field access records as an array
|
|
126
|
+
async getProfileFieldAccessData(conn, selectedObjects) {
|
|
127
|
+
const fieldAccessRecords = [];
|
|
128
|
+
try {
|
|
129
|
+
let soql = `SELECT Field, PermissionsRead, PermissionsEdit, SObjectType, Parent.Profile.Name FROM FieldPermissions WHERE Parent.ProfileId != null`;
|
|
130
|
+
if (selectedObjects && selectedObjects.length > 0) {
|
|
131
|
+
const objectList = selectedObjects.map(obj => `'${obj}'`).join(", ");
|
|
132
|
+
soql += ` AND SObjectType IN (${objectList})`;
|
|
133
|
+
}
|
|
134
|
+
// Add filter for active profiles
|
|
135
|
+
if (this.activeProfileNames && this.activeProfileNames.size > 0) {
|
|
136
|
+
const profileList = Array.from(this.activeProfileNames)
|
|
137
|
+
.filter((name) => !!name)
|
|
138
|
+
.map(name => `'${name.replace(/'/g, "''")}'`).join(", ");
|
|
139
|
+
soql += ` AND Parent.Profile.Name IN (${profileList})`;
|
|
140
|
+
}
|
|
141
|
+
const result = await bulkQuery(soql, conn);
|
|
142
|
+
result.records.forEach((rec) => {
|
|
143
|
+
fieldAccessRecords.push({
|
|
144
|
+
Profile: rec['Parent.Profile.Name'],
|
|
145
|
+
SObjectType: rec['SobjectType'],
|
|
146
|
+
Field: rec['Field'],
|
|
147
|
+
PermissionsRead: rec['PermissionsRead'] === true || rec['PermissionsRead'] === 'true' ? 'Yes' : 'No',
|
|
148
|
+
PermissionsEdit: rec['PermissionsEdit'] === true || rec['PermissionsEdit'] === 'true' ? 'Yes' : 'No',
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
uxLog('log', this, c.green(`Fetched ${fieldAccessRecords.length} profile field access records.`));
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
uxLog('warning', this, c.yellow(`Failed to query FieldPermissions: ${error.message}`));
|
|
155
|
+
}
|
|
156
|
+
return fieldAccessRecords;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Prompts the user to select Salesforce objects (SObjects) that have records in the org.
|
|
160
|
+
* Generates a CSV report of the selected objects.
|
|
161
|
+
* @param conn Salesforce connection
|
|
162
|
+
* @returns Array of selected object API names
|
|
163
|
+
*/
|
|
164
|
+
async generateObjectsList(conn) {
|
|
165
|
+
let selectedObjects = [];
|
|
166
|
+
uxLog('action', this, c.green('Fetching SObjects list...'));
|
|
167
|
+
let sobjectsList = [];
|
|
168
|
+
try {
|
|
169
|
+
// Exclude objects whose API names start with any of these prefixes
|
|
170
|
+
const excludedPrefixes = [
|
|
171
|
+
'Active',
|
|
172
|
+
'Apex',
|
|
173
|
+
'AuraDefinition',
|
|
174
|
+
'Business',
|
|
175
|
+
'Content',
|
|
176
|
+
'Dashboard',
|
|
177
|
+
'Email',
|
|
178
|
+
'Flow',
|
|
179
|
+
'Forecasting',
|
|
180
|
+
'Formula',
|
|
181
|
+
'ListView',
|
|
182
|
+
'LoginGeo',
|
|
183
|
+
'Marketing',
|
|
184
|
+
'MatchingRule',
|
|
185
|
+
'PermissionSet',
|
|
186
|
+
'UiFormula',
|
|
187
|
+
'WebLink',
|
|
188
|
+
'pi__'
|
|
189
|
+
];
|
|
190
|
+
// Exclude objects whose API names are in this explicit list
|
|
191
|
+
const excludedObjects = [
|
|
192
|
+
'AppDefinition', 'AppMenu', 'AssignmentRule', 'AsyncApexJob', 'AuthProvider', 'AuthSession',
|
|
193
|
+
'BrowserPolicyViolation', 'CampaignInfluenceModel', 'CaseStatus', 'ClientBrowser', 'Community',
|
|
194
|
+
'ConnectedApplication', 'ContractStatus', 'CronJobDetail', 'CronTrigger', 'CustomNotificationType',
|
|
195
|
+
'CustomPermission', 'DataType', 'DeleteEvent', 'Domain', 'DuplicateRule', 'EntityDefinition',
|
|
196
|
+
'FeedItem', 'FieldPermissions', 'FieldSecurityClassification', 'FileSearchActivity', 'FiscalYearSettings',
|
|
197
|
+
'Folder', 'Group', 'GroupMember', 'NamedCredential', 'OauthToken', 'ObjectPermissions', 'OrderStatus',
|
|
198
|
+
'OrgWideEmailAddress', 'Organization', 'PackageLicense', 'PartnerRole', 'Period', 'Profile', 'Publisher',
|
|
199
|
+
'QueueSobject', 'RecentlyViewed', 'RecordType', 'Report', 'Scontrol', 'SetupAuditTrail', 'SetupEntityAccess',
|
|
200
|
+
'SolutionStatus', 'StandardInvocableActionType', 'StaticResource', 'TabDefinition', 'TenantUsageEntitlement',
|
|
201
|
+
'Translation', 'VerificationHistory'
|
|
202
|
+
];
|
|
203
|
+
const sobjects = await conn.describeGlobal();
|
|
204
|
+
sobjectsList = sobjects.sobjects
|
|
205
|
+
.filter(sobj => sobj.queryable &&
|
|
206
|
+
!excludedPrefixes.some(prefix => sobj.name.startsWith(prefix)) &&
|
|
207
|
+
!excludedObjects.includes(sobj.name) &&
|
|
208
|
+
!sobj.name.endsWith('History') &&
|
|
209
|
+
!sobj.name.endsWith('Share'))
|
|
210
|
+
.map((sobject) => ({
|
|
211
|
+
label: sobject.label,
|
|
212
|
+
name: sobject.name,
|
|
213
|
+
masterObject: '',
|
|
214
|
+
objectType: sobject.name.endsWith('__c') ? 'Custom' : 'Standard',
|
|
215
|
+
}));
|
|
216
|
+
uxLog('log', this, c.green('Fetching SObjects completed.'));
|
|
217
|
+
uxLog('log', this, c.green(`Fetched ${sobjectsList.length} SObjects.`));
|
|
218
|
+
const sobjectsWithRecords = [];
|
|
219
|
+
uxLog('action', this, 'Checking SObjects for records...');
|
|
220
|
+
for (const sobject of sobjectsList) {
|
|
221
|
+
try {
|
|
222
|
+
const result = await conn.query(`SELECT COUNT() FROM ${sobject.name}`);
|
|
223
|
+
if (result.totalSize > 0) {
|
|
224
|
+
sobjectsWithRecords.push({ Object_Label: sobject.label, API_Name: sobject.name, Object_Type: sobject.objectType });
|
|
225
|
+
}
|
|
226
|
+
uxLog('log', this, `Checked ${sobject.name}: ${result.totalSize} records.`);
|
|
227
|
+
}
|
|
228
|
+
catch (error) {
|
|
229
|
+
uxLog('warning', this, c.yellow(`Failed to query ${sobject.name}: ${error.message}`));
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
this.spinner.stop();
|
|
233
|
+
if (sobjectsWithRecords.length === 0) {
|
|
234
|
+
uxLog('warning', this, c.red('No SObjects with records found.'));
|
|
235
|
+
return [];
|
|
236
|
+
}
|
|
237
|
+
const choices = [];
|
|
238
|
+
for (const sobject of sobjectsWithRecords) {
|
|
239
|
+
choices.push({
|
|
240
|
+
title: `${sobject.API_Name} - ${sobject.Object_Label} - ${sobject.Object_Type}`,
|
|
241
|
+
value: sobject.API_Name,
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
const statusRes = await prompts({
|
|
245
|
+
message: "Please select SObjects to add in the output Excel file",
|
|
246
|
+
type: "multiselect",
|
|
247
|
+
description: "Be careful, you can't update the selection later without re-running the command :)",
|
|
248
|
+
choices: choices,
|
|
249
|
+
});
|
|
250
|
+
if (statusRes && statusRes.value !== "all") {
|
|
251
|
+
selectedObjects = statusRes.value;
|
|
252
|
+
uxLog('log', this, `You selected ${selectedObjects.length} objects.`);
|
|
253
|
+
}
|
|
254
|
+
uxLog("log", this, c.green('Generating Objects.csv report...'));
|
|
255
|
+
const reportDir = await getReportDirectory();
|
|
256
|
+
this.outputFile = path.join(reportDir, 'Objects.csv');
|
|
257
|
+
// Without xlsx
|
|
258
|
+
await generateCsvFile(sobjectsWithRecords.filter((sobj) => selectedObjects.includes(sobj.API_Name)), this.outputFile, { fileTitle: 'profiles extract', noExcel: true });
|
|
259
|
+
// With xlsx
|
|
260
|
+
// this.outputFilesRes = await generateCsvFile(sobjectsWithRecords.filter((sobj) => selectedObjects.includes(sobj.API_Name)), this.outputFile, { fileTitle: 'profiles extract' });
|
|
261
|
+
this.csvFiles.push(this.outputFile);
|
|
262
|
+
}
|
|
263
|
+
catch (error) {
|
|
264
|
+
uxLog('log', this, c.red('Failed to fetch SObjects.'));
|
|
265
|
+
throw error;
|
|
266
|
+
}
|
|
267
|
+
return selectedObjects;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Extracts active users from the org, including their username, role, and profile.
|
|
271
|
+
* Generates a CSV report of users.
|
|
272
|
+
* @param conn Salesforce connection
|
|
273
|
+
*/
|
|
274
|
+
async generateUsersExtract(conn) {
|
|
275
|
+
const usersRecords = [];
|
|
276
|
+
const userQuery = "SELECT username, UserRole.Name, Profile.Name FROM User WHERE IsActive = true order by username";
|
|
277
|
+
const userResult = await bulkQuery(userQuery, conn);
|
|
278
|
+
usersRecords.push(...userResult.records.map((user) => ({
|
|
279
|
+
User: user.Username,
|
|
280
|
+
Role: user['UserRole.Name'],
|
|
281
|
+
Profile: user['Profile.Name'],
|
|
282
|
+
Profile_to_Associate: '',
|
|
283
|
+
New_Persona: '',
|
|
284
|
+
New_Role: '',
|
|
285
|
+
})));
|
|
286
|
+
// Build set of active profile names (filter out empty/null)
|
|
287
|
+
this.activeProfileNames = new Set(userResult.records.map((user) => user['Profile.Name']).filter((n) => !!n));
|
|
288
|
+
uxLog('log', this, c.green(`Fetched ${userResult.records.length} active users.`));
|
|
289
|
+
uxLog('log', this, c.cyan(`Active profiles: ${Array.from(this.activeProfileNames).join(', ')}`));
|
|
290
|
+
const reportDir = await getReportDirectory();
|
|
291
|
+
this.outputFile = path.join(reportDir, 'Users.csv');
|
|
292
|
+
await generateCsvFile(usersRecords, this.outputFile, { fileTitle: 'Users extract', noExcel: true });
|
|
293
|
+
this.csvFiles.push(this.outputFile);
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Prompts the user for the number of personas to create.
|
|
298
|
+
* Generates a CSV report listing the personas.
|
|
299
|
+
* @returns The number of personas
|
|
300
|
+
*/
|
|
301
|
+
async generatePersonaExtract() {
|
|
302
|
+
let numberOfPersonas = 1;
|
|
303
|
+
const statusRes = await prompts({
|
|
304
|
+
message: "Please enter the number of personas to create",
|
|
305
|
+
type: "number",
|
|
306
|
+
description: "One tab by personal will be created in the final Excel file",
|
|
307
|
+
placeholder: "Input a number of personas (better too much than too few!)",
|
|
308
|
+
});
|
|
309
|
+
if (statusRes && statusRes.value !== 0) {
|
|
310
|
+
numberOfPersonas = statusRes.value;
|
|
311
|
+
uxLog('log', this, `Creation of ${numberOfPersonas} personas.`);
|
|
312
|
+
}
|
|
313
|
+
const persona = [];
|
|
314
|
+
for (let i = 1; i <= numberOfPersonas; i++) {
|
|
315
|
+
persona.push({ 'Persona Name': `Persona${i}` });
|
|
316
|
+
}
|
|
317
|
+
const reportDir = await getReportDirectory();
|
|
318
|
+
this.outputFile = path.join(reportDir, 'persona.csv');
|
|
319
|
+
await generateCsvFile(persona, this.outputFile, { fileTitle: 'persona extract', noExcel: true });
|
|
320
|
+
this.csvFiles.push(this.outputFile);
|
|
321
|
+
return numberOfPersonas;
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Generates a CSV mapping each selected object to persona permissions (Read, Create, Edit, Delete).
|
|
325
|
+
* @param selectedObjects Array of object API names
|
|
326
|
+
* @param numberOfPersonas Number of personas
|
|
327
|
+
*/
|
|
328
|
+
async generateRelationExtract(selectedObjects, numberOfPersonas) {
|
|
329
|
+
const relationRecords = [];
|
|
330
|
+
// Generate dynamic persona columns using Excel formulas
|
|
331
|
+
selectedObjects.forEach((objName) => {
|
|
332
|
+
const personaCols = {};
|
|
333
|
+
for (let i = 1; i <= numberOfPersonas; i++) {
|
|
334
|
+
// Persona row in persona sheet is i+1 (header is row 1)
|
|
335
|
+
const personaRow = i + 1;
|
|
336
|
+
personaCols[`=persona!A${personaRow}&"_Read"`] = '';
|
|
337
|
+
personaCols[`=persona!A${personaRow}&"_Create"`] = '';
|
|
338
|
+
personaCols[`=persona!A${personaRow}&"_Edit"`] = '';
|
|
339
|
+
personaCols[`=persona!A${personaRow}&"_Delete"`] = '';
|
|
340
|
+
personaCols[`=persona!A${personaRow}&"_ViewAll"`] = '';
|
|
341
|
+
personaCols[`=persona!A${personaRow}&"_ModifyAll"`] = '';
|
|
342
|
+
}
|
|
343
|
+
relationRecords.push({
|
|
344
|
+
Object: objName,
|
|
345
|
+
...personaCols,
|
|
346
|
+
});
|
|
347
|
+
});
|
|
348
|
+
const reportDir = await getReportDirectory();
|
|
349
|
+
this.outputFile = path.join(reportDir, 'Relation.csv');
|
|
350
|
+
await generateCsvFile(relationRecords, this.outputFile, { fileTitle: 'Relation Object Persona', noExcel: true });
|
|
351
|
+
this.csvFiles.push(this.outputFile);
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Extracts record types for each selected object and maps persona access (Active, Default).
|
|
356
|
+
* Generates a CSV report of record types per object.
|
|
357
|
+
* @param conn Salesforce connection
|
|
358
|
+
* @param selectedObjects Array of object API names
|
|
359
|
+
* @param numberOfPersonas Number of personas
|
|
360
|
+
*/
|
|
361
|
+
async generateRTExtract(conn, selectedObjects, numberOfPersonas) {
|
|
362
|
+
const recordTypesRecords = [];
|
|
363
|
+
for (const objName of selectedObjects) {
|
|
364
|
+
try {
|
|
365
|
+
const rtResult = await conn.query(`SELECT Id, Name, DeveloperName FROM RecordType WHERE SobjectType='${objName}' ORDER BY Name`);
|
|
366
|
+
rtResult.records.forEach((rt) => {
|
|
367
|
+
const personaCols = {};
|
|
368
|
+
for (let i = 1; i <= numberOfPersonas; i++) {
|
|
369
|
+
const personaRow = i + 1;
|
|
370
|
+
personaCols[`=persona!A${personaRow}&"_Active"`] = '';
|
|
371
|
+
personaCols[`=persona!A${personaRow}&"_Default"`] = '';
|
|
372
|
+
}
|
|
373
|
+
recordTypesRecords.push({
|
|
374
|
+
Object: objName,
|
|
375
|
+
Record_Type: rt.Name,
|
|
376
|
+
...personaCols,
|
|
377
|
+
});
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
catch (error) {
|
|
381
|
+
uxLog('warning', this, c.yellow(`Failed to query RecordTypes for ${objName}: ${error.message}`));
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
const reportDir = await getReportDirectory();
|
|
385
|
+
this.outputFile = path.join(reportDir, 'RecordTypes.csv');
|
|
386
|
+
await generateCsvFile(recordTypesRecords, this.outputFile, { fileTitle: 'Record Types extract', noExcel: true });
|
|
387
|
+
this.csvFiles.push(this.outputFile);
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Extracts custom applications (AppDefinition) and maps persona access (Active, Default).
|
|
392
|
+
* Generates a CSV report of applications.
|
|
393
|
+
* @param conn Salesforce connection
|
|
394
|
+
* @param numberOfPersonas Number of personas
|
|
395
|
+
*/
|
|
396
|
+
/* jscpd:ignore-start */
|
|
397
|
+
async generateAppsExtract(conn, numberOfPersonas) {
|
|
398
|
+
const appsRecords = [];
|
|
399
|
+
try {
|
|
400
|
+
const rtResult = await conn.query(`SELECT Id, DurableId, DeveloperName, MasterLabel FROM AppDefinition WHERE NamespacePrefix != 'standard'`);
|
|
401
|
+
rtResult.records.forEach((rt) => {
|
|
402
|
+
const personaCols = {};
|
|
403
|
+
for (let i = 1; i <= numberOfPersonas; i++) {
|
|
404
|
+
const personaRow = i + 1;
|
|
405
|
+
personaCols[`=persona!A${personaRow}&"_Active"`] = '';
|
|
406
|
+
personaCols[`=persona!A${personaRow}&"_Default"`] = '';
|
|
407
|
+
}
|
|
408
|
+
appsRecords.push({
|
|
409
|
+
Application: rt.MasterLabel,
|
|
410
|
+
DeveloperName: rt.DeveloperName,
|
|
411
|
+
...personaCols,
|
|
412
|
+
});
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
catch (error) {
|
|
416
|
+
uxLog('warning', this, c.yellow(`Failed to query Applications : ${error.message}`));
|
|
417
|
+
}
|
|
418
|
+
const reportDir = await getReportDirectory();
|
|
419
|
+
this.outputFile = path.join(reportDir, 'Applications.csv');
|
|
420
|
+
await generateCsvFile(appsRecords, this.outputFile, { fileTitle: 'Applications extract', noExcel: true });
|
|
421
|
+
this.csvFiles.push(this.outputFile);
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
/* jscpd:ignore-end */
|
|
425
|
+
/**
|
|
426
|
+
* Extracts all boolean permission fields from PermissionSet object.
|
|
427
|
+
* Generates a CSV report mapping each permission to personas.
|
|
428
|
+
* @param conn Salesforce connection
|
|
429
|
+
* @param numberOfPersonas Number of personas
|
|
430
|
+
*/
|
|
431
|
+
async generatePermissionsExtract(conn, numberOfPersonas) {
|
|
432
|
+
const permissionsRecords = [];
|
|
433
|
+
// Describe the PermissionSet object
|
|
434
|
+
const desc = await conn.describeSObject("PermissionSet");
|
|
435
|
+
// Filter only fields that start with "Permissions"
|
|
436
|
+
const permissionFields = desc.fields.filter(f => f.name.startsWith("Permissions") && f.type === "boolean");
|
|
437
|
+
// Print API name + Label
|
|
438
|
+
permissionFields.forEach(field => {
|
|
439
|
+
const personaCols = {};
|
|
440
|
+
for (let i = 1; i <= numberOfPersonas; i++) {
|
|
441
|
+
const personaRow = i + 1;
|
|
442
|
+
personaCols[`=persona!A${personaRow}`] = '';
|
|
443
|
+
}
|
|
444
|
+
permissionsRecords.push({
|
|
445
|
+
Permission_Label: field.label,
|
|
446
|
+
Permission_API_Name: field.name,
|
|
447
|
+
...personaCols,
|
|
448
|
+
});
|
|
449
|
+
});
|
|
450
|
+
const reportDir = await getReportDirectory();
|
|
451
|
+
this.outputFile = path.join(reportDir, 'Permissions.csv');
|
|
452
|
+
await generateCsvFile(permissionsRecords, this.outputFile, { fileTitle: 'Permissions extract', noExcel: true });
|
|
453
|
+
this.csvFiles.push(this.outputFile);
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* Extracts custom tabs and maps persona access.
|
|
458
|
+
* Generates a CSV report of tabs.
|
|
459
|
+
* @param conn Salesforce connection
|
|
460
|
+
* @param numberOfPersonas Number of personas
|
|
461
|
+
*/
|
|
462
|
+
async generateTabsExtract(conn, numberOfPersonas) {
|
|
463
|
+
const tabsRecords = [];
|
|
464
|
+
try {
|
|
465
|
+
const tabsResult = await conn.query(`SELECT Name, Label FROM TabDefinition WHERE IsCustom = true`);
|
|
466
|
+
tabsResult.records.forEach((tab) => {
|
|
467
|
+
const personaCols = {};
|
|
468
|
+
for (let i = 1; i <= numberOfPersonas; i++) {
|
|
469
|
+
const personaRow = i + 1;
|
|
470
|
+
personaCols[`=persona!A${personaRow}`] = '';
|
|
471
|
+
}
|
|
472
|
+
tabsRecords.push({
|
|
473
|
+
Tab_Label: tab.Label,
|
|
474
|
+
Tab_API_Name: tab.Name,
|
|
475
|
+
...personaCols,
|
|
476
|
+
});
|
|
477
|
+
});
|
|
478
|
+
const reportDir = await getReportDirectory();
|
|
479
|
+
this.outputFile = path.join(reportDir, 'Tabs.csv');
|
|
480
|
+
await generateCsvFile(tabsRecords, this.outputFile, { fileTitle: 'Tabs extract', noExcel: true });
|
|
481
|
+
this.csvFiles.push(this.outputFile);
|
|
482
|
+
}
|
|
483
|
+
catch (error) {
|
|
484
|
+
uxLog('warning', this, c.yellow(`Failed to query Tabs : ${error.message}`));
|
|
485
|
+
}
|
|
486
|
+
return;
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* For each selected object, extracts all fields and their metadata (label, type, picklist values, etc.).
|
|
490
|
+
* Maps persona visibility and read-only status for each field.
|
|
491
|
+
* Generates a CSV report per object.
|
|
492
|
+
* @param conn Salesforce connection
|
|
493
|
+
* @param selectedObjects Array of object API names
|
|
494
|
+
* @param numberOfPersonas Number of personas
|
|
495
|
+
*/
|
|
496
|
+
async generateObjectFieldsExtract(conn, selectedObjects, numberOfPersonas, profileNames = [], profileFieldAccess = []) {
|
|
497
|
+
const fieldsRecords = [];
|
|
498
|
+
for (const objName of selectedObjects) {
|
|
499
|
+
try {
|
|
500
|
+
fieldsRecords.length = 0;
|
|
501
|
+
const desc = await conn.describeSObject(objName);
|
|
502
|
+
desc.fields.forEach((field) => {
|
|
503
|
+
let picklistValues = '';
|
|
504
|
+
if (field.picklistValues && field.picklistValues.length > 0) {
|
|
505
|
+
picklistValues = field.picklistValues.map(pv => pv.value).join('; ');
|
|
506
|
+
}
|
|
507
|
+
// Add persona columns using formula logic
|
|
508
|
+
const personaCols = {};
|
|
509
|
+
for (let i = 1; i <= numberOfPersonas; i++) {
|
|
510
|
+
const personaRow = i + 1;
|
|
511
|
+
personaCols[`=persona!A${personaRow}&"_View"`] = '';
|
|
512
|
+
personaCols[`=persona!A${personaRow}&"_Edit"`] = '';
|
|
513
|
+
}
|
|
514
|
+
// Add one column per profile, fill with 'none', 'edit', or 'read'
|
|
515
|
+
const profileCols = (profileNames || []).reduce((acc, profile) => {
|
|
516
|
+
// Find access for this field/profile/object (case-insensitive, and check both SObjectType and API_Name)
|
|
517
|
+
const access = profileFieldAccess.find((rec) => {
|
|
518
|
+
const profileMatch = rec.Profile === profile;
|
|
519
|
+
const objectMatch = (rec.SObjectType === objName || rec.SObjectType?.toLowerCase() === objName.toLowerCase());
|
|
520
|
+
// rec.Field can be 'ObjectName.FieldName' or just 'FieldName'
|
|
521
|
+
let recFieldName = rec.Field;
|
|
522
|
+
if (recFieldName && recFieldName.includes('.')) {
|
|
523
|
+
recFieldName = recFieldName.split('.').pop();
|
|
524
|
+
}
|
|
525
|
+
const fieldMatch = (recFieldName === field.name || recFieldName?.toLowerCase() === field.name.toLowerCase());
|
|
526
|
+
return profileMatch && objectMatch && fieldMatch;
|
|
527
|
+
});
|
|
528
|
+
let value = 'none';
|
|
529
|
+
if (access) {
|
|
530
|
+
if (access.PermissionsEdit === 'Yes') {
|
|
531
|
+
value = 'edit';
|
|
532
|
+
}
|
|
533
|
+
else if (access.PermissionsRead === 'Yes') {
|
|
534
|
+
value = 'read';
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
acc[`Profile_${profile}`] = value;
|
|
538
|
+
return acc;
|
|
539
|
+
}, {});
|
|
540
|
+
fieldsRecords.push({
|
|
541
|
+
Field_Label: field.label,
|
|
542
|
+
API_Name: field.name,
|
|
543
|
+
Data_Type: field.type,
|
|
544
|
+
Length: field.length ? field.length.toString() : '',
|
|
545
|
+
Field_Type: field.calculated ? 'Formula' : (field.type === 'reference' ? 'Lookup' : field.type),
|
|
546
|
+
Required: field.nillable ? 'No' : 'Yes',
|
|
547
|
+
PicklistValues: picklistValues,
|
|
548
|
+
Formula: field.calculated ? field.calculatedFormula : '',
|
|
549
|
+
ExternalId: field.externalId ? 'Yes' : 'No',
|
|
550
|
+
TrackHistory: field.trackHistory ? 'Yes' : 'No',
|
|
551
|
+
Description: field.description ? field.description : '',
|
|
552
|
+
HelpText: field.inlineHelpText ? field.inlineHelpText : '',
|
|
553
|
+
...personaCols,
|
|
554
|
+
...profileCols,
|
|
555
|
+
});
|
|
556
|
+
});
|
|
557
|
+
}
|
|
558
|
+
catch (error) {
|
|
559
|
+
uxLog('warning', this, c.yellow(`Failed to describe fields for ${objName}: ${error.message}`));
|
|
560
|
+
}
|
|
561
|
+
const reportDir = await getReportDirectory();
|
|
562
|
+
this.outputFile = path.join(reportDir, `${objName} Fields.csv`);
|
|
563
|
+
await generateCsvFile(fieldsRecords, this.outputFile, { fileTitle: `${objName} Fields extract`, noExcel: true });
|
|
564
|
+
this.csvFiles.push(this.outputFile);
|
|
565
|
+
}
|
|
566
|
+
return;
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* Extracts all Permission Sets in the org.
|
|
570
|
+
* Generates a CSV report mapping each permission set to personas.
|
|
571
|
+
* @param conn
|
|
572
|
+
* @param numberOfPersonas
|
|
573
|
+
*/
|
|
574
|
+
async generatePermissionSetsExtract(conn, numberOfPersonas) {
|
|
575
|
+
const permissionSetsRecords = [];
|
|
576
|
+
try {
|
|
577
|
+
const result = await conn.query(`SELECT Name, Label, Description, IsCustom FROM PermissionSet WHERE IsOwnedByProfile = false`);
|
|
578
|
+
result.records.forEach((ps) => {
|
|
579
|
+
const personaCols = {};
|
|
580
|
+
for (let i = 1; i <= numberOfPersonas; i++) {
|
|
581
|
+
const personaRow = i + 1;
|
|
582
|
+
personaCols[`=persona!A${personaRow}&"_Assigned"`] = ''; // Dynamic column for each persona
|
|
583
|
+
}
|
|
584
|
+
permissionSetsRecords.push({
|
|
585
|
+
Name: ps.Name,
|
|
586
|
+
Label: ps.Label || '',
|
|
587
|
+
Description: ps.Description || '',
|
|
588
|
+
IsCustom: ps.IsCustom ? 'Yes' : 'No',
|
|
589
|
+
...personaCols,
|
|
590
|
+
});
|
|
591
|
+
});
|
|
592
|
+
const reportDir = await getReportDirectory();
|
|
593
|
+
this.outputFile = path.join(reportDir, 'PermissionSets.csv');
|
|
594
|
+
await generateCsvFile(permissionSetsRecords, this.outputFile, {
|
|
595
|
+
fileTitle: 'Permission Sets extract',
|
|
596
|
+
noExcel: true,
|
|
597
|
+
});
|
|
598
|
+
this.csvFiles.push(this.outputFile);
|
|
599
|
+
}
|
|
600
|
+
catch (error) {
|
|
601
|
+
uxLog('warning', this, c.yellow(`Failed to query PermissionSets: ${error.message}`));
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
//# sourceMappingURL=profiles-extract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profiles-extract.js","sourceRoot":"","sources":["../../../../../src/commands/hardis/project/clean/profiles-extract.ts"],"names":[],"mappings":"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"}
|
|
@@ -179,3 +179,8 @@ export declare function generateCsvFile(data: any[], outputPath: string, options
|
|
|
179
179
|
xlsFileTitle?: string;
|
|
180
180
|
noExcel?: boolean;
|
|
181
181
|
}): Promise<any>;
|
|
182
|
+
export declare function createXlsxFromCsvFiles(csvFilesPath: string[], outputPath: string, options: {
|
|
183
|
+
fileTitle?: string;
|
|
184
|
+
csvFileTitle?: string;
|
|
185
|
+
xlsFileTitle?: string;
|
|
186
|
+
}): Promise<void>;
|