permcraft 0.1.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/LICENSE +21 -0
- package/README.md +350 -0
- package/dist/dependencies.d.ts +9 -0
- package/dist/dependencies.js +51 -0
- package/dist/dependencies.js.map +1 -0
- package/dist/env.d.ts +10 -0
- package/dist/env.js +54 -0
- package/dist/env.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +320 -0
- package/dist/index.js.map +1 -0
- package/dist/org-fetch.d.ts +4 -0
- package/dist/org-fetch.js +59 -0
- package/dist/org-fetch.js.map +1 -0
- package/dist/prompts.d.ts +15 -0
- package/dist/prompts.js +358 -0
- package/dist/prompts.js.map +1 -0
- package/dist/search.d.ts +3 -0
- package/dist/search.js +17 -0
- package/dist/search.js.map +1 -0
- package/dist/types.d.ts +49 -0
- package/dist/types.js +13 -0
- package/dist/types.js.map +1 -0
- package/dist/xml-mutator.d.ts +32 -0
- package/dist/xml-mutator.js +223 -0
- package/dist/xml-mutator.js.map +1 -0
- package/package.json +54 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
3
|
+
import { validateEnvironment, getPackageDirectories } from './env.js';
|
|
4
|
+
import { fetchObjectList, fetchFieldsForObject, discoverLocalPermissionSets } from './org-fetch.js';
|
|
5
|
+
import { promptObjectSearch, promptFieldSearch, promptPermissionMode, promptObjectPermissions, promptFieldPermissions, promptPermissionSetSelection, printExistingPermissions, printPreview, promptConfirm, } from './prompts.js';
|
|
6
|
+
import { resolveObjectDependencies, resolveFieldDependencies } from './dependencies.js';
|
|
7
|
+
import { parsePermissionSetXml, createEmptyPermissionSet, applyObjectPermission, applyFieldPermission, readExistingObjectPermissions, readExistingFieldPermissions, serializePermissionSetXml, writePermissionSetFile, detectIndentation, } from './xml-mutator.js';
|
|
8
|
+
const OBJECT_PERM_LABEL_MAP = {
|
|
9
|
+
allowRead: 'Read',
|
|
10
|
+
allowCreate: 'Create',
|
|
11
|
+
allowEdit: 'Edit',
|
|
12
|
+
allowDelete: 'Delete',
|
|
13
|
+
viewAllRecords: 'View All',
|
|
14
|
+
modifyAllRecords: 'Modify All',
|
|
15
|
+
};
|
|
16
|
+
const FIELD_PERM_LABEL_MAP = {
|
|
17
|
+
readable: 'Read',
|
|
18
|
+
editable: 'Edit',
|
|
19
|
+
};
|
|
20
|
+
// Handle --version and --help
|
|
21
|
+
const args = process.argv.slice(2);
|
|
22
|
+
if (args.includes('--version') || args.includes('-v')) {
|
|
23
|
+
const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf-8'));
|
|
24
|
+
console.log(pkg.version);
|
|
25
|
+
process.exit(0);
|
|
26
|
+
}
|
|
27
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
28
|
+
console.log(`
|
|
29
|
+
permcraft — Interactive Salesforce permission set editor
|
|
30
|
+
|
|
31
|
+
Usage: permcraft
|
|
32
|
+
|
|
33
|
+
Interactively select objects, fields, and permissions, then apply
|
|
34
|
+
them to one or more permission set XML files in your SFDX project.
|
|
35
|
+
|
|
36
|
+
Options:
|
|
37
|
+
-h, --help Show this help message
|
|
38
|
+
-v, --version Show version number
|
|
39
|
+
|
|
40
|
+
Requirements:
|
|
41
|
+
- Must be run inside an SFDX project (sfdx-project.json)
|
|
42
|
+
- Must have an authenticated Salesforce org (sf org login web)
|
|
43
|
+
`);
|
|
44
|
+
process.exit(0);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Parse all selected permission set files upfront so we can read
|
|
48
|
+
* existing permissions before prompting the user.
|
|
49
|
+
*/
|
|
50
|
+
function loadParsedTargets(targets) {
|
|
51
|
+
const map = new Map();
|
|
52
|
+
for (const t of targets) {
|
|
53
|
+
if (t.filePath && existsSync(t.filePath)) {
|
|
54
|
+
const content = readFileSync(t.filePath, 'utf-8');
|
|
55
|
+
map.set(t.name, {
|
|
56
|
+
parsed: parsePermissionSetXml(t.filePath),
|
|
57
|
+
indent: detectIndentation(content),
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return map;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Read existing permissions for a given item across all selected permission sets.
|
|
65
|
+
*/
|
|
66
|
+
function readExistingForItem(itemType, itemName, targets, parsedFiles) {
|
|
67
|
+
const result = new Map();
|
|
68
|
+
for (const t of targets) {
|
|
69
|
+
const entry = parsedFiles.get(t.name);
|
|
70
|
+
if (!entry) {
|
|
71
|
+
result.set(t.name, null);
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (itemType === 'object') {
|
|
75
|
+
result.set(t.name, readExistingObjectPermissions(entry.parsed, itemName));
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
result.set(t.name, readExistingFieldPermissions(entry.parsed, itemName));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return result;
|
|
82
|
+
}
|
|
83
|
+
async function main() {
|
|
84
|
+
console.log('Permcraft — Salesforce Permission Set Editor\n');
|
|
85
|
+
// Step 0: Validate environment
|
|
86
|
+
console.log('Checking environment...');
|
|
87
|
+
const { projectRoot, project, org } = validateEnvironment();
|
|
88
|
+
console.log(` Project: ${projectRoot}`);
|
|
89
|
+
console.log(` Org: ${org.username}\n`);
|
|
90
|
+
const packageDirs = getPackageDirectories(project, projectRoot);
|
|
91
|
+
// Step 1: Fetch object list from org
|
|
92
|
+
console.log('Fetching objects from org...');
|
|
93
|
+
const objects = fetchObjectList();
|
|
94
|
+
console.log(`Found ${objects.length} objects.\n`);
|
|
95
|
+
// Step 2: Fuzzy search and select objects
|
|
96
|
+
const selectedObjects = await promptObjectSearch(objects);
|
|
97
|
+
console.log(`\nSelected objects: ${selectedObjects.join(', ')}`);
|
|
98
|
+
// Step 3: For each object, fetch fields and fuzzy search to select
|
|
99
|
+
const allSelections = [];
|
|
100
|
+
for (const obj of selectedObjects) {
|
|
101
|
+
allSelections.push({ type: 'object', name: obj });
|
|
102
|
+
console.log(`\nFetching fields for ${obj}...`);
|
|
103
|
+
const fields = fetchFieldsForObject(obj);
|
|
104
|
+
console.log(`Found ${fields.length} fields.`);
|
|
105
|
+
const selectedFields = await promptFieldSearch(obj, fields);
|
|
106
|
+
for (const field of selectedFields) {
|
|
107
|
+
allSelections.push({ type: 'field', name: field, object: obj });
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// Step 4: Select permission sets FIRST (so we can read existing state)
|
|
111
|
+
console.log('\nScanning local permission sets...');
|
|
112
|
+
const allTargets = discoverLocalPermissionSets(packageDirs);
|
|
113
|
+
console.log(`Found ${allTargets.length} permission sets.\n`);
|
|
114
|
+
const selectedTargets = await promptPermissionSetSelection(allTargets);
|
|
115
|
+
// Parse selected permission set files to read existing permissions
|
|
116
|
+
const parsedFiles = loadParsedTargets(selectedTargets);
|
|
117
|
+
// Build a map of existing permissions: targetName → itemName → perms
|
|
118
|
+
const existingPerms = new Map();
|
|
119
|
+
for (const t of selectedTargets) {
|
|
120
|
+
const itemMap = new Map();
|
|
121
|
+
const entry = parsedFiles.get(t.name);
|
|
122
|
+
for (const sel of allSelections) {
|
|
123
|
+
if (!entry) {
|
|
124
|
+
itemMap.set(sel.name, null);
|
|
125
|
+
}
|
|
126
|
+
else if (sel.type === 'object') {
|
|
127
|
+
itemMap.set(sel.name, readExistingObjectPermissions(entry.parsed, sel.name));
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
itemMap.set(sel.name, readExistingFieldPermissions(entry.parsed, sel.name));
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
existingPerms.set(t.name, itemMap);
|
|
134
|
+
}
|
|
135
|
+
// Step 5: Choose permission mode and assign permissions
|
|
136
|
+
const changes = [];
|
|
137
|
+
const objectSelections = allSelections.filter((s) => s.type === 'object');
|
|
138
|
+
const fieldSelections = allSelections.filter((s) => s.type === 'field');
|
|
139
|
+
const hasMultipleItems = objectSelections.length + fieldSelections.length > 1;
|
|
140
|
+
const mode = hasMultipleItems ? await promptPermissionMode() : 'bulk';
|
|
141
|
+
if (mode === 'bulk') {
|
|
142
|
+
if (objectSelections.length > 0) {
|
|
143
|
+
console.log();
|
|
144
|
+
// Show existing state for each object across permission sets
|
|
145
|
+
for (const sel of objectSelections) {
|
|
146
|
+
const byTarget = readExistingForItem('object', sel.name, selectedTargets, parsedFiles);
|
|
147
|
+
const nonNull = new Map([...byTarget.entries()].filter(([, v]) => v !== null));
|
|
148
|
+
if (nonNull.size > 0) {
|
|
149
|
+
printExistingPermissions(sel.name, nonNull);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// Compute union of existing across all targets for pre-checking
|
|
153
|
+
const objExisting = new Map();
|
|
154
|
+
for (const t of selectedTargets) {
|
|
155
|
+
for (const sel of objectSelections) {
|
|
156
|
+
const perms = existingPerms.get(t.name)?.get(sel.name);
|
|
157
|
+
if (perms) {
|
|
158
|
+
const current = objExisting.get(t.name);
|
|
159
|
+
if (!current) {
|
|
160
|
+
objExisting.set(t.name, { ...perms });
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
// Merge: union
|
|
164
|
+
for (const key of Object.keys(current)) {
|
|
165
|
+
if (perms[key])
|
|
166
|
+
current[key] = true;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
// For bulk mode, merge all existing across ALL targets + items into one union
|
|
173
|
+
const bulkExisting = new Map();
|
|
174
|
+
for (const t of selectedTargets) {
|
|
175
|
+
const merged = {
|
|
176
|
+
allowRead: false, allowCreate: false, allowEdit: false,
|
|
177
|
+
allowDelete: false, viewAllRecords: false, modifyAllRecords: false,
|
|
178
|
+
};
|
|
179
|
+
for (const sel of objectSelections) {
|
|
180
|
+
const perms = existingPerms.get(t.name)?.get(sel.name);
|
|
181
|
+
if (perms) {
|
|
182
|
+
for (const key of Object.keys(merged)) {
|
|
183
|
+
if (perms[key])
|
|
184
|
+
merged[key] = true;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
bulkExisting.set(t.name, merged);
|
|
189
|
+
}
|
|
190
|
+
const rawPerms = await promptObjectPermissions(objectSelections.map((s) => s.name), bulkExisting);
|
|
191
|
+
const { resolved, autoEnabled } = resolveObjectDependencies(rawPerms);
|
|
192
|
+
const autoLabels = autoEnabled.map((k) => OBJECT_PERM_LABEL_MAP[k] || k);
|
|
193
|
+
if (autoLabels.length > 0) {
|
|
194
|
+
console.log(` Auto-enabled dependencies: ${autoLabels.join(', ')}`);
|
|
195
|
+
}
|
|
196
|
+
for (const sel of objectSelections) {
|
|
197
|
+
changes.push({ selection: sel, permissions: resolved, autoEnabled: autoLabels });
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
if (fieldSelections.length > 0) {
|
|
201
|
+
console.log();
|
|
202
|
+
for (const sel of fieldSelections) {
|
|
203
|
+
const byTarget = readExistingForItem('field', sel.name, selectedTargets, parsedFiles);
|
|
204
|
+
const nonNull = new Map([...byTarget.entries()].filter(([, v]) => v !== null));
|
|
205
|
+
if (nonNull.size > 0) {
|
|
206
|
+
printExistingPermissions(sel.name, nonNull);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
const bulkExisting = new Map();
|
|
210
|
+
for (const t of selectedTargets) {
|
|
211
|
+
const merged = { readable: false, editable: false };
|
|
212
|
+
for (const sel of fieldSelections) {
|
|
213
|
+
const perms = existingPerms.get(t.name)?.get(sel.name);
|
|
214
|
+
if (perms) {
|
|
215
|
+
if (perms.readable)
|
|
216
|
+
merged.readable = true;
|
|
217
|
+
if (perms.editable)
|
|
218
|
+
merged.editable = true;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
bulkExisting.set(t.name, merged);
|
|
222
|
+
}
|
|
223
|
+
const rawPerms = await promptFieldPermissions(fieldSelections.map((s) => s.name), bulkExisting);
|
|
224
|
+
const { resolved, autoEnabled } = resolveFieldDependencies(rawPerms);
|
|
225
|
+
const autoLabels = autoEnabled.map((k) => FIELD_PERM_LABEL_MAP[k] || k);
|
|
226
|
+
if (autoLabels.length > 0) {
|
|
227
|
+
console.log(` Auto-enabled dependencies: ${autoLabels.join(', ')}`);
|
|
228
|
+
}
|
|
229
|
+
for (const sel of fieldSelections) {
|
|
230
|
+
changes.push({ selection: sel, permissions: resolved, autoEnabled: autoLabels });
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
// Granular mode
|
|
236
|
+
for (const sel of objectSelections) {
|
|
237
|
+
console.log();
|
|
238
|
+
const byTarget = readExistingForItem('object', sel.name, selectedTargets, parsedFiles);
|
|
239
|
+
const nonNull = new Map([...byTarget.entries()].filter(([, v]) => v !== null));
|
|
240
|
+
if (nonNull.size > 0) {
|
|
241
|
+
printExistingPermissions(sel.name, nonNull);
|
|
242
|
+
}
|
|
243
|
+
const objExisting = new Map();
|
|
244
|
+
for (const t of selectedTargets) {
|
|
245
|
+
objExisting.set(t.name, existingPerms.get(t.name)?.get(sel.name) ?? null);
|
|
246
|
+
}
|
|
247
|
+
const rawPerms = await promptObjectPermissions([sel.name], objExisting);
|
|
248
|
+
const { resolved, autoEnabled } = resolveObjectDependencies(rawPerms);
|
|
249
|
+
const autoLabels = autoEnabled.map((k) => OBJECT_PERM_LABEL_MAP[k] || k);
|
|
250
|
+
if (autoLabels.length > 0) {
|
|
251
|
+
console.log(` Auto-enabled dependencies: ${autoLabels.join(', ')}`);
|
|
252
|
+
}
|
|
253
|
+
changes.push({ selection: sel, permissions: resolved, autoEnabled: autoLabels });
|
|
254
|
+
}
|
|
255
|
+
for (const sel of fieldSelections) {
|
|
256
|
+
console.log();
|
|
257
|
+
const byTarget = readExistingForItem('field', sel.name, selectedTargets, parsedFiles);
|
|
258
|
+
const nonNull = new Map([...byTarget.entries()].filter(([, v]) => v !== null));
|
|
259
|
+
if (nonNull.size > 0) {
|
|
260
|
+
printExistingPermissions(sel.name, nonNull);
|
|
261
|
+
}
|
|
262
|
+
const fieldExisting = new Map();
|
|
263
|
+
for (const t of selectedTargets) {
|
|
264
|
+
fieldExisting.set(t.name, existingPerms.get(t.name)?.get(sel.name) ?? null);
|
|
265
|
+
}
|
|
266
|
+
const rawPerms = await promptFieldPermissions([sel.name], fieldExisting);
|
|
267
|
+
const { resolved, autoEnabled } = resolveFieldDependencies(rawPerms);
|
|
268
|
+
const autoLabels = autoEnabled.map((k) => FIELD_PERM_LABEL_MAP[k] || k);
|
|
269
|
+
if (autoLabels.length > 0) {
|
|
270
|
+
console.log(` Auto-enabled dependencies: ${autoLabels.join(', ')}`);
|
|
271
|
+
}
|
|
272
|
+
changes.push({ selection: sel, permissions: resolved, autoEnabled: autoLabels });
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
if (changes.length === 0) {
|
|
276
|
+
console.log('No permissions selected. Exiting.');
|
|
277
|
+
process.exit(0);
|
|
278
|
+
}
|
|
279
|
+
// Step 6: Preview with diff
|
|
280
|
+
printPreview(changes, selectedTargets, existingPerms);
|
|
281
|
+
// Step 7: Confirm and apply
|
|
282
|
+
const confirmed = await promptConfirm();
|
|
283
|
+
if (!confirmed) {
|
|
284
|
+
console.log('Cancelled.');
|
|
285
|
+
process.exit(0);
|
|
286
|
+
}
|
|
287
|
+
console.log('\nApplying changes...\n');
|
|
288
|
+
for (const target of selectedTargets) {
|
|
289
|
+
const filePath = target.filePath;
|
|
290
|
+
const cached = parsedFiles.get(target.name);
|
|
291
|
+
let parsed;
|
|
292
|
+
let indent;
|
|
293
|
+
if (cached) {
|
|
294
|
+
parsed = cached.parsed;
|
|
295
|
+
indent = cached.indent;
|
|
296
|
+
console.log(` Updating ${filePath}`);
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
parsed = createEmptyPermissionSet(target.name, target.label);
|
|
300
|
+
indent = ' ';
|
|
301
|
+
console.log(` Creating ${filePath}`);
|
|
302
|
+
}
|
|
303
|
+
for (const change of changes) {
|
|
304
|
+
if (change.selection.type === 'object') {
|
|
305
|
+
applyObjectPermission(parsed, change.selection.name, change.permissions);
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
applyFieldPermission(parsed, change.selection.name, change.permissions);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
const xml = serializePermissionSetXml(parsed, indent);
|
|
312
|
+
writePermissionSetFile(filePath, xml);
|
|
313
|
+
}
|
|
314
|
+
console.log('\nAll changes applied successfully!');
|
|
315
|
+
}
|
|
316
|
+
main().catch((err) => {
|
|
317
|
+
console.error(`\nError: ${err.message}`);
|
|
318
|
+
process.exit(1);
|
|
319
|
+
});
|
|
320
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { PermissionSetTarget } from './types.js';
|
|
2
|
+
export declare function fetchObjectList(): string[];
|
|
3
|
+
export declare function fetchFieldsForObject(objectName: string): string[];
|
|
4
|
+
export declare function discoverLocalPermissionSets(packageDirs: string[]): PermissionSetTarget[];
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { execSync } from 'node:child_process';
|
|
2
|
+
import { readdirSync, statSync } from 'node:fs';
|
|
3
|
+
import { basename, resolve } from 'node:path';
|
|
4
|
+
function runSfCommand(args) {
|
|
5
|
+
const result = execSync(`sf ${args} --json`, {
|
|
6
|
+
encoding: 'utf-8',
|
|
7
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
8
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
9
|
+
});
|
|
10
|
+
const parsed = JSON.parse(result);
|
|
11
|
+
if (parsed.status !== 0 && parsed.status !== undefined) {
|
|
12
|
+
throw new Error(`sf command failed: ${parsed.message || JSON.stringify(parsed)}`);
|
|
13
|
+
}
|
|
14
|
+
return parsed.result;
|
|
15
|
+
}
|
|
16
|
+
export function fetchObjectList() {
|
|
17
|
+
const result = runSfCommand('sobject list');
|
|
18
|
+
return result.sort();
|
|
19
|
+
}
|
|
20
|
+
export function fetchFieldsForObject(objectName) {
|
|
21
|
+
const result = runSfCommand(`sobject describe --sobject ${objectName}`);
|
|
22
|
+
return result.fields.map((f) => `${objectName}.${f.name}`).sort();
|
|
23
|
+
}
|
|
24
|
+
function scanLocalPermissionSets(packageDirs) {
|
|
25
|
+
const targets = [];
|
|
26
|
+
function walk(dir) {
|
|
27
|
+
let entries;
|
|
28
|
+
try {
|
|
29
|
+
entries = readdirSync(dir);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
for (const entry of entries) {
|
|
35
|
+
const fullPath = resolve(dir, entry);
|
|
36
|
+
try {
|
|
37
|
+
const stat = statSync(fullPath);
|
|
38
|
+
if (stat.isDirectory()) {
|
|
39
|
+
walk(fullPath);
|
|
40
|
+
}
|
|
41
|
+
else if (entry.endsWith('.permissionset-meta.xml')) {
|
|
42
|
+
const name = basename(entry, '.permissionset-meta.xml');
|
|
43
|
+
targets.push({ name, filePath: fullPath, label: name });
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
// skip inaccessible entries
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
for (const dir of packageDirs) {
|
|
52
|
+
walk(dir);
|
|
53
|
+
}
|
|
54
|
+
return targets;
|
|
55
|
+
}
|
|
56
|
+
export function discoverLocalPermissionSets(packageDirs) {
|
|
57
|
+
return scanLocalPermissionSets(packageDirs).sort((a, b) => a.name.localeCompare(b.name));
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=org-fetch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"org-fetch.js","sourceRoot":"","sources":["../src/org-fetch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ObjectPermissions, FieldPermissions, PermissionSetTarget, PermissionChange } from './types.js';
|
|
2
|
+
export declare function promptObjectSearch(objects: string[]): Promise<string[]>;
|
|
3
|
+
export declare function promptFieldSearch(objectName: string, fields: string[]): Promise<string[]>;
|
|
4
|
+
export type PermissionMode = 'bulk' | 'granular';
|
|
5
|
+
export declare function promptPermissionMode(): Promise<PermissionMode>;
|
|
6
|
+
/**
|
|
7
|
+
* Show existing permissions summary across permission sets.
|
|
8
|
+
* e.g. " Currently set — Sales_User: Read, Edit | Admin: Read"
|
|
9
|
+
*/
|
|
10
|
+
export declare function printExistingPermissions(itemName: string, existingByTarget: Map<string, ObjectPermissions | FieldPermissions>): void;
|
|
11
|
+
export declare function promptObjectPermissions(objectNames: string[], existingByTarget?: Map<string, ObjectPermissions | null>): Promise<ObjectPermissions>;
|
|
12
|
+
export declare function promptFieldPermissions(fieldNames: string[], existingByTarget?: Map<string, FieldPermissions | null>): Promise<FieldPermissions>;
|
|
13
|
+
export declare function promptPermissionSetSelection(targets: PermissionSetTarget[]): Promise<PermissionSetTarget[]>;
|
|
14
|
+
export declare function printPreview(changes: PermissionChange[], targets: PermissionSetTarget[], existingPerms: Map<string, Map<string, ObjectPermissions | FieldPermissions | null>>): void;
|
|
15
|
+
export declare function promptConfirm(): Promise<boolean>;
|