@simplysf/simply-permissions 1.0.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/lib/commands/simply/permissions/analyze.d.ts +19 -0
- package/lib/commands/simply/permissions/analyze.js +192 -0
- package/lib/commands/simply/permissions/analyze.js.map +1 -0
- package/lib/commands/simply/permissions/build.d.ts +25 -0
- package/lib/commands/simply/permissions/build.js +317 -0
- package/lib/commands/simply/permissions/build.js.map +1 -0
- package/lib/common/permissionSetXmlTemplate.d.ts +37 -0
- package/lib/common/permissionSetXmlTemplate.js +76 -0
- package/lib/common/permissionSetXmlTemplate.js.map +1 -0
- package/lib/common/permissionsReportTemplate.d.ts +41 -0
- package/lib/common/permissionsReportTemplate.js +109 -0
- package/lib/common/permissionsReportTemplate.js.map +1 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +17 -0
- package/lib/index.js.map +1 -0
- package/lib/schemas/build/permissionConfig.d.ts +24 -0
- package/lib/schemas/build/permissionConfig.js +43 -0
- package/lib/schemas/build/permissionConfig.js.map +1 -0
- package/messages/simply.permissions.analyze.md +57 -0
- package/messages/simply.permissions.build.md +97 -0
- package/package.json +201 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2026, Clay Chipps; Copyright (c) 2026 Salesforce, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
function escapeXml(value) {
|
|
17
|
+
return value
|
|
18
|
+
.replace(/&/g, '&')
|
|
19
|
+
.replace(/</g, '<')
|
|
20
|
+
.replace(/>/g, '>')
|
|
21
|
+
.replace(/"/g, '"')
|
|
22
|
+
.replace(/'/g, ''');
|
|
23
|
+
}
|
|
24
|
+
export function buildPermissionSetXml(data) {
|
|
25
|
+
const objectPermissionsXml = data.objectPermissions
|
|
26
|
+
.map((permission) => ` <objectPermissions>
|
|
27
|
+
<object>${escapeXml(permission.object)}</object>
|
|
28
|
+
<allowCreate>${permission.allowCreate}</allowCreate>
|
|
29
|
+
<allowDelete>${permission.allowDelete}</allowDelete>
|
|
30
|
+
<allowEdit>${permission.allowEdit}</allowEdit>
|
|
31
|
+
<allowRead>${permission.allowRead}</allowRead>
|
|
32
|
+
<modifyAllRecords>${permission.modifyAllRecords}</modifyAllRecords>
|
|
33
|
+
<viewAllRecords>${permission.viewAllRecords}</viewAllRecords>
|
|
34
|
+
</objectPermissions>`)
|
|
35
|
+
.join('\n');
|
|
36
|
+
const fieldPermissionsXml = data.fieldPermissions
|
|
37
|
+
.map((permission) => ` <fieldPermissions>
|
|
38
|
+
<field>${escapeXml(permission.field)}</field>
|
|
39
|
+
<readable>${permission.readable}</readable>
|
|
40
|
+
<editable>${permission.editable}</editable>
|
|
41
|
+
</fieldPermissions>`)
|
|
42
|
+
.join('\n');
|
|
43
|
+
const tabSettingsXml = data.tabSettings
|
|
44
|
+
.map((setting) => ` <tabSettings>
|
|
45
|
+
<tab>${escapeXml(setting.tab)}</tab>
|
|
46
|
+
<visibility>${setting.visible ? 'Visible' : 'Hidden'}</visibility>
|
|
47
|
+
</tabSettings>`)
|
|
48
|
+
.join('\n');
|
|
49
|
+
const recordTypeVisibilitiesXml = data.recordTypeVisibilities
|
|
50
|
+
.map((visibility) => ` <recordTypeVisibilities>
|
|
51
|
+
<recordType>${escapeXml(visibility.recordType)}</recordType>
|
|
52
|
+
<visible>${visibility.visible}</visible>
|
|
53
|
+
</recordTypeVisibilities>`)
|
|
54
|
+
.join('\n');
|
|
55
|
+
const userPermissionsXml = data.userPermissions
|
|
56
|
+
.map((permission) => ` <userPermissions>
|
|
57
|
+
<name>${escapeXml(permission.name)}</name>
|
|
58
|
+
<enabled>${permission.enabled}</enabled>
|
|
59
|
+
</userPermissions>`)
|
|
60
|
+
.join('\n');
|
|
61
|
+
const sections = [
|
|
62
|
+
` <label>${escapeXml(data.label)}</label>`,
|
|
63
|
+
data.description ? ` <description>${escapeXml(data.description)}</description>` : '',
|
|
64
|
+
objectPermissionsXml,
|
|
65
|
+
fieldPermissionsXml,
|
|
66
|
+
tabSettingsXml,
|
|
67
|
+
recordTypeVisibilitiesXml,
|
|
68
|
+
userPermissionsXml,
|
|
69
|
+
].filter(Boolean);
|
|
70
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
71
|
+
<PermissionSet xmlns="http://soap.sforce.com/2006/04/metadata">
|
|
72
|
+
${sections.join('\n')}
|
|
73
|
+
</PermissionSet>
|
|
74
|
+
`;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=permissionSetXmlTemplate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissionSetXmlTemplate.js","sourceRoot":"","sources":["../../src/common/permissionSetXmlTemplate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AA4CH,SAAS,SAAS,CAAC,KAAa;IAC9B,OAAO,KAAK;SACT,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,IAA+B;IACnE,MAAM,oBAAoB,GAAG,IAAI,CAAC,iBAAiB;SAChD,GAAG,CACF,CAAC,UAAU,EAAE,EAAE,CAAC;cACR,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC;mBACvB,UAAU,CAAC,WAAW;mBACtB,UAAU,CAAC,WAAW;iBACxB,UAAU,CAAC,SAAS;iBACpB,UAAU,CAAC,SAAS;wBACb,UAAU,CAAC,gBAAgB;sBAC7B,UAAU,CAAC,cAAc;uBACxB,CAClB;SACA,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,mBAAmB,GAAG,IAAI,CAAC,gBAAgB;SAC9C,GAAG,CACF,CAAC,UAAU,EAAE,EAAE,CAAC;aACT,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC;gBACxB,UAAU,CAAC,QAAQ;gBACnB,UAAU,CAAC,QAAQ;sBACb,CACjB;SACA,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,cAAc,GAAG,IAAI,CAAC,WAAW;SACpC,GAAG,CACF,CAAC,OAAO,EAAE,EAAE,CAAC;WACR,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC;kBACf,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ;iBACvC,CACZ;SACA,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,yBAAyB,GAAG,IAAI,CAAC,sBAAsB;SAC1D,GAAG,CACF,CAAC,UAAU,EAAE,EAAE,CAAC;kBACJ,SAAS,CAAC,UAAU,CAAC,UAAU,CAAC;eACnC,UAAU,CAAC,OAAO;4BACL,CACvB;SACA,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,kBAAkB,GAAG,IAAI,CAAC,eAAe;SAC5C,GAAG,CACF,CAAC,UAAU,EAAE,EAAE,CAAC;YACV,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC;eACvB,UAAU,CAAC,OAAO;qBACZ,CAChB;SACA,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,QAAQ,GAAG;QACf,YAAY,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU;QAC3C,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,kBAAkB,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE;QACrF,oBAAoB;QACpB,mBAAmB;QACnB,cAAc;QACd,yBAAyB;QACzB,kBAAkB;KACnB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAElB,OAAO;;EAEP,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;;CAEpB,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export type ObjectPermissionEntry = {
|
|
2
|
+
SobjectType: string;
|
|
3
|
+
PermissionsRead: boolean;
|
|
4
|
+
PermissionsCreate: boolean;
|
|
5
|
+
PermissionsEdit: boolean;
|
|
6
|
+
PermissionsDelete: boolean;
|
|
7
|
+
PermissionsViewAllRecords: boolean;
|
|
8
|
+
PermissionsModifyAllRecords: boolean;
|
|
9
|
+
};
|
|
10
|
+
export type FieldPermissionEntry = {
|
|
11
|
+
SobjectType: string;
|
|
12
|
+
Field: string;
|
|
13
|
+
PermissionsRead: boolean;
|
|
14
|
+
PermissionsEdit: boolean;
|
|
15
|
+
};
|
|
16
|
+
export type PermissionSetReportEntry = {
|
|
17
|
+
Id: string;
|
|
18
|
+
Name: string;
|
|
19
|
+
Label: string;
|
|
20
|
+
Description?: string;
|
|
21
|
+
objectPerms: ObjectPermissionEntry[];
|
|
22
|
+
fieldPerms: FieldPermissionEntry[];
|
|
23
|
+
};
|
|
24
|
+
export type PermissionSetGroupReportEntry = {
|
|
25
|
+
Id: string;
|
|
26
|
+
DeveloperName: string;
|
|
27
|
+
MasterLabel: string;
|
|
28
|
+
Description?: string;
|
|
29
|
+
components: string[];
|
|
30
|
+
objectPerms: ObjectPermissionEntry[];
|
|
31
|
+
fieldPerms: FieldPermissionEntry[];
|
|
32
|
+
};
|
|
33
|
+
export type GroupedPermissionsData = Map<string, {
|
|
34
|
+
permissionSets: PermissionSetReportEntry[];
|
|
35
|
+
permissionSetGroups: PermissionSetGroupReportEntry[];
|
|
36
|
+
}>;
|
|
37
|
+
export declare function buildPermissionsReportHtml(options: {
|
|
38
|
+
username: string;
|
|
39
|
+
reportDate: string;
|
|
40
|
+
groupedData: GroupedPermissionsData;
|
|
41
|
+
}): string;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2026, Clay Chipps; Copyright (c) 2026 Salesforce, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
function escapeHtml(value) {
|
|
17
|
+
return value.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
|
18
|
+
}
|
|
19
|
+
function renderObjectPermsTable(perms) {
|
|
20
|
+
if (perms.length === 0) {
|
|
21
|
+
return '<p>No object permissions.</p>';
|
|
22
|
+
}
|
|
23
|
+
const rows = perms
|
|
24
|
+
.map((permission) => `<tr><td>${escapeHtml(permission.SobjectType)}</td><td>${permission.PermissionsRead}</td><td>${permission.PermissionsCreate}</td><td>${permission.PermissionsEdit}</td><td>${permission.PermissionsDelete}</td><td>${permission.PermissionsViewAllRecords}</td><td>${permission.PermissionsModifyAllRecords}</td></tr>`)
|
|
25
|
+
.join('');
|
|
26
|
+
return `<table><thead><tr><th>Object</th><th>Read</th><th>Create</th><th>Edit</th><th>Delete</th><th>View All</th><th>Modify All</th></tr></thead><tbody>${rows}</tbody></table>`;
|
|
27
|
+
}
|
|
28
|
+
function renderFieldPermsTable(perms) {
|
|
29
|
+
if (perms.length === 0) {
|
|
30
|
+
return '<p>No field permissions.</p>';
|
|
31
|
+
}
|
|
32
|
+
const rows = perms
|
|
33
|
+
.map((permission) => `<tr><td>${escapeHtml(permission.SobjectType)}</td><td>${escapeHtml(permission.Field.split('.')[1] ?? permission.Field)}</td><td>${permission.PermissionsRead}</td><td>${permission.PermissionsEdit}</td></tr>`)
|
|
34
|
+
.join('');
|
|
35
|
+
return `<table><thead><tr><th>Object</th><th>Field</th><th>Read</th><th>Edit</th></tr></thead><tbody>${rows}</tbody></table>`;
|
|
36
|
+
}
|
|
37
|
+
function renderPermissionSet(permissionSet) {
|
|
38
|
+
return `
|
|
39
|
+
<details>
|
|
40
|
+
<summary>${escapeHtml(permissionSet.Label)} (${escapeHtml(permissionSet.Name)})</summary>
|
|
41
|
+
<div class="content">
|
|
42
|
+
${permissionSet.Description ? `<p>${escapeHtml(permissionSet.Description)}</p>` : ''}
|
|
43
|
+
<h4>Object Permissions</h4>
|
|
44
|
+
${renderObjectPermsTable(permissionSet.objectPerms)}
|
|
45
|
+
<h4>Field Permissions</h4>
|
|
46
|
+
${renderFieldPermsTable(permissionSet.fieldPerms)}
|
|
47
|
+
</div>
|
|
48
|
+
</details>`;
|
|
49
|
+
}
|
|
50
|
+
function renderPermissionSetGroup(permissionSetGroup) {
|
|
51
|
+
return `
|
|
52
|
+
<details>
|
|
53
|
+
<summary>${escapeHtml(permissionSetGroup.MasterLabel)} (${escapeHtml(permissionSetGroup.DeveloperName)}) [Group]</summary>
|
|
54
|
+
<div class="content">
|
|
55
|
+
${permissionSetGroup.Description ? `<p>${escapeHtml(permissionSetGroup.Description)}</p>` : ''}
|
|
56
|
+
<p><strong>Components:</strong> ${permissionSetGroup.components.map(escapeHtml).join(', ') || 'None'}</p>
|
|
57
|
+
<h4>Object Permissions</h4>
|
|
58
|
+
${renderObjectPermsTable(permissionSetGroup.objectPerms)}
|
|
59
|
+
<h4>Field Permissions</h4>
|
|
60
|
+
${renderFieldPermsTable(permissionSetGroup.fieldPerms)}
|
|
61
|
+
</div>
|
|
62
|
+
</details>`;
|
|
63
|
+
}
|
|
64
|
+
export function buildPermissionsReportHtml(options) {
|
|
65
|
+
const { username, reportDate, groupedData } = options;
|
|
66
|
+
const sortedPackages = [...groupedData.keys()].sort();
|
|
67
|
+
const sections = sortedPackages
|
|
68
|
+
.map((pkg) => {
|
|
69
|
+
const data = groupedData.get(pkg);
|
|
70
|
+
if (!data) {
|
|
71
|
+
return '';
|
|
72
|
+
}
|
|
73
|
+
return `
|
|
74
|
+
<div class="package-section" data-package="${escapeHtml(pkg)}">
|
|
75
|
+
<h2>Package: ${escapeHtml(pkg)}</h2>
|
|
76
|
+
<h3>Permission Sets (${data.permissionSets.length})</h3>
|
|
77
|
+
${data.permissionSets.map(renderPermissionSet).join('')}
|
|
78
|
+
<h3>Permission Set Groups (${data.permissionSetGroups.length})</h3>
|
|
79
|
+
${data.permissionSetGroups.map(renderPermissionSetGroup).join('')}
|
|
80
|
+
</div>`;
|
|
81
|
+
})
|
|
82
|
+
.join('');
|
|
83
|
+
return `<!DOCTYPE html>
|
|
84
|
+
<html lang="en">
|
|
85
|
+
<head>
|
|
86
|
+
<meta charset="UTF-8">
|
|
87
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
88
|
+
<title>Permissions Report</title>
|
|
89
|
+
<style>
|
|
90
|
+
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; line-height: 1.6; color: #333; max-width: 1200px; margin: 0 auto; padding: 20px; background-color: #f4f7f6; }
|
|
91
|
+
h1 { color: #2c3e50; border-bottom: 2px solid #3498db; padding-bottom: 10px; }
|
|
92
|
+
.package-section { background: white; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); margin-bottom: 20px; padding: 15px; }
|
|
93
|
+
details { margin-bottom: 10px; border: 1px solid #ddd; border-radius: 4px; }
|
|
94
|
+
summary { padding: 12px; cursor: pointer; font-weight: bold; background: #eee; outline: none; }
|
|
95
|
+
summary:hover { background: #e0e0e0; }
|
|
96
|
+
.content { padding: 15px; background: white; }
|
|
97
|
+
table { width: 100%; border-collapse: collapse; margin-top: 10px; margin-bottom: 15px; font-size: 0.9em; }
|
|
98
|
+
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
|
|
99
|
+
th { background-color: #f8f9fa; }
|
|
100
|
+
</style>
|
|
101
|
+
</head>
|
|
102
|
+
<body>
|
|
103
|
+
<h1>Permissions Report</h1>
|
|
104
|
+
<p>Org: <strong>${escapeHtml(username)}</strong> | Generated: ${escapeHtml(reportDate)}</p>
|
|
105
|
+
${sections}
|
|
106
|
+
</body>
|
|
107
|
+
</html>`;
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=permissionsReportTemplate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissionsReportTemplate.js","sourceRoot":"","sources":["../../src/common/permissionsReportTemplate.ts"],"names":[],"mappings":"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"}
|
package/lib/index.d.ts
ADDED
package/lib/index.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2026, Clay Chipps; Copyright (c) 2026 Salesforce, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
export default {};
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,eAAe,EAAE,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const PermissionSetBuildConfigSchema: z.ZodObject<{
|
|
3
|
+
objects: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
4
|
+
read: z.ZodOptional<z.ZodBoolean>;
|
|
5
|
+
create: z.ZodOptional<z.ZodBoolean>;
|
|
6
|
+
edit: z.ZodOptional<z.ZodBoolean>;
|
|
7
|
+
delete: z.ZodOptional<z.ZodBoolean>;
|
|
8
|
+
modifyAll: z.ZodOptional<z.ZodBoolean>;
|
|
9
|
+
viewAll: z.ZodOptional<z.ZodBoolean>;
|
|
10
|
+
viewAllFields: z.ZodOptional<z.ZodBoolean>;
|
|
11
|
+
}, z.core.$strip>>>;
|
|
12
|
+
fields: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
13
|
+
readable: z.ZodOptional<z.ZodBoolean>;
|
|
14
|
+
editable: z.ZodOptional<z.ZodBoolean>;
|
|
15
|
+
}, z.core.$strip>>>;
|
|
16
|
+
tabs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
17
|
+
visible: z.ZodOptional<z.ZodBoolean>;
|
|
18
|
+
}, z.core.$strip>>>;
|
|
19
|
+
recordTypeVisibilities: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
20
|
+
visible: z.ZodOptional<z.ZodBoolean>;
|
|
21
|
+
}, z.core.$strip>>>;
|
|
22
|
+
userPermissions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodBoolean>>;
|
|
23
|
+
}, z.core.$strip>;
|
|
24
|
+
export type PermissionSetBuildConfig = z.infer<typeof PermissionSetBuildConfigSchema>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2026, Clay Chipps; Copyright (c) 2026 Salesforce, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { z } from 'zod';
|
|
17
|
+
const ObjectPermissionConfigSchema = z.object({
|
|
18
|
+
read: z.boolean().optional(),
|
|
19
|
+
create: z.boolean().optional(),
|
|
20
|
+
edit: z.boolean().optional(),
|
|
21
|
+
delete: z.boolean().optional(),
|
|
22
|
+
modifyAll: z.boolean().optional(),
|
|
23
|
+
viewAll: z.boolean().optional(),
|
|
24
|
+
viewAllFields: z.boolean().optional(),
|
|
25
|
+
});
|
|
26
|
+
const FieldPermissionConfigSchema = z.object({
|
|
27
|
+
readable: z.boolean().optional(),
|
|
28
|
+
editable: z.boolean().optional(),
|
|
29
|
+
});
|
|
30
|
+
const TabPermissionConfigSchema = z.object({
|
|
31
|
+
visible: z.boolean().optional(),
|
|
32
|
+
});
|
|
33
|
+
const RecordTypeVisibilityConfigSchema = z.object({
|
|
34
|
+
visible: z.boolean().optional(),
|
|
35
|
+
});
|
|
36
|
+
export const PermissionSetBuildConfigSchema = z.object({
|
|
37
|
+
objects: z.record(z.string(), ObjectPermissionConfigSchema).optional(),
|
|
38
|
+
fields: z.record(z.string(), FieldPermissionConfigSchema).optional(),
|
|
39
|
+
tabs: z.record(z.string(), TabPermissionConfigSchema).optional(),
|
|
40
|
+
recordTypeVisibilities: z.record(z.string(), RecordTypeVisibilityConfigSchema).optional(),
|
|
41
|
+
userPermissions: z.record(z.string(), z.boolean()).optional(),
|
|
42
|
+
});
|
|
43
|
+
//# sourceMappingURL=permissionConfig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissionConfig.js","sourceRoot":"","sources":["../../../src/schemas/build/permissionConfig.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,4BAA4B,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5C,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAC5B,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAC9B,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAC5B,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAC9B,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IACjC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAC/B,aAAa,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;CACtC,CAAC,CAAC;AAEH,MAAM,2BAA2B,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAChC,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;CACjC,CAAC,CAAC;AAEH,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;CAChC,CAAC,CAAC;AAEH,MAAM,gCAAgC,GAAG,CAAC,CAAC,MAAM,CAAC;IAChD,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;CAChC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,CAAC,MAAM,CAAC;IACrD,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,4BAA4B,CAAC,CAAC,QAAQ,EAAE;IACtE,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,2BAA2B,CAAC,CAAC,QAAQ,EAAE;IACpE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,yBAAyB,CAAC,CAAC,QAAQ,EAAE;IAChE,sBAAsB,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,gCAAgC,CAAC,CAAC,QAAQ,EAAE;IACzF,eAAe,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE;CAC9D,CAAC,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# summary
|
|
2
|
+
|
|
3
|
+
Analyze permission sets and permission set groups in an org.
|
|
4
|
+
|
|
5
|
+
# description
|
|
6
|
+
|
|
7
|
+
Generates an HTML report of every permission set and permission set group in the target org, grouped by installed package, including their object and field permissions.
|
|
8
|
+
|
|
9
|
+
# flags.output.summary
|
|
10
|
+
|
|
11
|
+
Output HTML file path
|
|
12
|
+
|
|
13
|
+
# flags.output.description
|
|
14
|
+
|
|
15
|
+
The path to write the generated HTML report to.
|
|
16
|
+
|
|
17
|
+
# flags.filter.summary
|
|
18
|
+
|
|
19
|
+
Permission set or group names to include
|
|
20
|
+
|
|
21
|
+
# flags.filter.description
|
|
22
|
+
|
|
23
|
+
One or more PermissionSet (Name) or PermissionSetGroup (DeveloperName) API names to restrict the report to. If omitted, all permission sets and groups are included.
|
|
24
|
+
|
|
25
|
+
# examples
|
|
26
|
+
|
|
27
|
+
- <%= config.bin %> <%= command.id %> --target-org myOrg
|
|
28
|
+
|
|
29
|
+
- <%= config.bin %> <%= command.id %> --target-org myOrg --output reports/permissions.html --filter My_Permission_Set --filter Another_Set
|
|
30
|
+
|
|
31
|
+
# error.targetOrgConnectionFailed
|
|
32
|
+
|
|
33
|
+
Unable to establish connection to the org.
|
|
34
|
+
|
|
35
|
+
# info.fetchingPermissionSets
|
|
36
|
+
|
|
37
|
+
Fetching permission sets and groups...
|
|
38
|
+
|
|
39
|
+
# info.resolvingPackages
|
|
40
|
+
|
|
41
|
+
Resolving package names...
|
|
42
|
+
|
|
43
|
+
# info.fetchingPermissions
|
|
44
|
+
|
|
45
|
+
Fetching object and field permissions...
|
|
46
|
+
|
|
47
|
+
# info.mappingGroups
|
|
48
|
+
|
|
49
|
+
Mapping permission sets to groups...
|
|
50
|
+
|
|
51
|
+
# info.generatingReport
|
|
52
|
+
|
|
53
|
+
Generating HTML report...
|
|
54
|
+
|
|
55
|
+
# info.reportGenerated
|
|
56
|
+
|
|
57
|
+
Report successfully generated at: %s
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# summary
|
|
2
|
+
|
|
3
|
+
Generate a permission set from Salesforce source metadata.
|
|
4
|
+
|
|
5
|
+
# description
|
|
6
|
+
|
|
7
|
+
Scans a Salesforce project directory for custom objects, fields, tabs, and (optionally) record types, then generates a permission set XML file with a baseline of permissions determined by --type. An optional JSON --config file can override individual object, field, tab, record type, and user permission settings.
|
|
8
|
+
|
|
9
|
+
# flags.type.summary
|
|
10
|
+
|
|
11
|
+
Baseline permission type
|
|
12
|
+
|
|
13
|
+
# flags.type.description
|
|
14
|
+
|
|
15
|
+
The baseline permission level to generate: 'read-only' grants read access to all discovered objects and fields, 'view-all' additionally grants view-all-records, and 'modify-all' grants full CRUD and modify-all-records access.
|
|
16
|
+
|
|
17
|
+
# flags.name.summary
|
|
18
|
+
|
|
19
|
+
API name for the permission set
|
|
20
|
+
|
|
21
|
+
# flags.name.description
|
|
22
|
+
|
|
23
|
+
The API name for the generated permission set; also used to derive the output filename.
|
|
24
|
+
|
|
25
|
+
# flags.directory.summary
|
|
26
|
+
|
|
27
|
+
Path to the Salesforce project directory
|
|
28
|
+
|
|
29
|
+
# flags.directory.description
|
|
30
|
+
|
|
31
|
+
The path to the Salesforce source directory to scan for custom objects, fields, tabs, and record types.
|
|
32
|
+
|
|
33
|
+
# flags.config.summary
|
|
34
|
+
|
|
35
|
+
Path to a permission set configuration file
|
|
36
|
+
|
|
37
|
+
# flags.config.description
|
|
38
|
+
|
|
39
|
+
The path to a JSON file that overrides individual object, field, tab, record type, and user permission settings on top of the --type baseline.
|
|
40
|
+
|
|
41
|
+
# flags.output.summary
|
|
42
|
+
|
|
43
|
+
Output directory
|
|
44
|
+
|
|
45
|
+
# flags.output.description
|
|
46
|
+
|
|
47
|
+
The directory to write the generated permission set XML file to.
|
|
48
|
+
|
|
49
|
+
# flags.include-record-types.summary
|
|
50
|
+
|
|
51
|
+
Include record type visibilities
|
|
52
|
+
|
|
53
|
+
# flags.include-record-types.description
|
|
54
|
+
|
|
55
|
+
Automatically include record type visibilities discovered from the source metadata, marked as visible by default.
|
|
56
|
+
|
|
57
|
+
# flags.label.summary
|
|
58
|
+
|
|
59
|
+
Label for the permission set
|
|
60
|
+
|
|
61
|
+
# flags.description.summary
|
|
62
|
+
|
|
63
|
+
Description for the permission set
|
|
64
|
+
|
|
65
|
+
# examples
|
|
66
|
+
|
|
67
|
+
- <%= config.bin %> <%= command.id %> --type read-only --name My_Read_Only_Access --directory force-app --output force-app/main/default/permissionsets
|
|
68
|
+
|
|
69
|
+
- <%= config.bin %> <%= command.id %> --type modify-all --name My_Admin_Access --directory force-app --config config/permission-overrides.json --output force-app/main/default/permissionsets --include-record-types
|
|
70
|
+
|
|
71
|
+
# error.invalidConfig
|
|
72
|
+
|
|
73
|
+
The permission set configuration file is invalid: %s
|
|
74
|
+
|
|
75
|
+
# error.scanFailed
|
|
76
|
+
|
|
77
|
+
Failed to scan the Salesforce project directory: %s
|
|
78
|
+
|
|
79
|
+
# info.readingConfig
|
|
80
|
+
|
|
81
|
+
Reading and validating configuration file...
|
|
82
|
+
|
|
83
|
+
# info.scanningProject
|
|
84
|
+
|
|
85
|
+
Scanning Salesforce project directory...
|
|
86
|
+
|
|
87
|
+
# info.compilingPermissions
|
|
88
|
+
|
|
89
|
+
Compiling permissions baseline and configuration overrides...
|
|
90
|
+
|
|
91
|
+
# info.writingFile
|
|
92
|
+
|
|
93
|
+
Generating and writing permission set XML file...
|
|
94
|
+
|
|
95
|
+
# info.fileGenerated
|
|
96
|
+
|
|
97
|
+
Permission set successfully generated at %s
|