figmanage 1.3.0 → 1.3.1
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/dist/cli/analytics.js +3 -2
- package/dist/cli/branching.js +9 -3
- package/dist/cli/comments.js +10 -4
- package/dist/cli/components.js +21 -4
- package/dist/cli/compound-commands.js +13 -12
- package/dist/cli/export.js +3 -2
- package/dist/cli/files.js +14 -8
- package/dist/cli/helpers.d.ts +1 -0
- package/dist/cli/helpers.js +10 -0
- package/dist/cli/libraries.js +2 -1
- package/dist/cli/navigate.js +11 -10
- package/dist/cli/org.js +13 -12
- package/dist/cli/permissions.js +13 -7
- package/dist/cli/projects.js +12 -6
- package/dist/cli/reading.js +3 -2
- package/dist/cli/teams.js +9 -3
- package/dist/cli/variables.js +29 -7
- package/dist/cli/versions.js +3 -2
- package/dist/cli/webhooks.js +14 -4
- package/dist/helpers.d.ts +11 -0
- package/dist/helpers.js +41 -0
- package/dist/operations/analytics.js +1 -1
- package/dist/operations/components.d.ts +8 -2
- package/dist/operations/components.js +4 -2
- package/dist/operations/compound-manager.js +8 -9
- package/dist/operations/compound.d.ts +3 -0
- package/dist/operations/compound.js +14 -8
- package/dist/operations/files.js +1 -1
- package/dist/operations/libraries.js +1 -1
- package/dist/operations/org.js +1 -1
- package/dist/operations/reading.js +2 -0
- package/dist/operations/teams.js +1 -1
- package/dist/operations/variables.js +11 -0
- package/dist/operations/webhooks.d.ts +4 -1
- package/dist/operations/webhooks.js +2 -1
- package/dist/tools/analytics.js +6 -5
- package/dist/tools/branching.js +7 -6
- package/dist/tools/comments.js +14 -9
- package/dist/tools/components.js +24 -15
- package/dist/tools/compound-manager.js +10 -7
- package/dist/tools/compound.js +34 -22
- package/dist/tools/export.js +6 -5
- package/dist/tools/files.js +13 -12
- package/dist/tools/libraries.js +6 -3
- package/dist/tools/navigate.js +29 -18
- package/dist/tools/org.js +25 -24
- package/dist/tools/permissions.js +14 -11
- package/dist/tools/projects.js +10 -9
- package/dist/tools/reading.js +11 -7
- package/dist/tools/register.d.ts +8 -2
- package/dist/tools/register.js +9 -14
- package/dist/tools/teams.js +7 -6
- package/dist/tools/variables.js +12 -8
- package/dist/tools/versions.js +6 -5
- package/dist/tools/webhooks.js +15 -12
- package/package.json +1 -1
package/dist/cli/permissions.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { getPermissions, setPermissions, share, revokeAccess, listRoleRequests, approveRoleRequest, denyRoleRequest, } from '../operations/permissions.js';
|
|
3
3
|
import { output, error } from './format.js';
|
|
4
|
+
import { formatApiError } from '../helpers.js';
|
|
4
5
|
import { requireCookie } from './helpers.js';
|
|
5
6
|
export function permissionsCommand() {
|
|
6
7
|
const permissions = new Command('permissions')
|
|
@@ -19,7 +20,7 @@ export function permissionsCommand() {
|
|
|
19
20
|
output(result, options);
|
|
20
21
|
}
|
|
21
22
|
catch (e) {
|
|
22
|
-
error(e
|
|
23
|
+
error(formatApiError(e));
|
|
23
24
|
process.exit(1);
|
|
24
25
|
}
|
|
25
26
|
});
|
|
@@ -39,7 +40,7 @@ export function permissionsCommand() {
|
|
|
39
40
|
output({ message: msg }, options);
|
|
40
41
|
}
|
|
41
42
|
catch (e) {
|
|
42
|
-
error(e
|
|
43
|
+
error(formatApiError(e));
|
|
43
44
|
process.exit(1);
|
|
44
45
|
}
|
|
45
46
|
});
|
|
@@ -60,7 +61,7 @@ export function permissionsCommand() {
|
|
|
60
61
|
output(result, options);
|
|
61
62
|
}
|
|
62
63
|
catch (e) {
|
|
63
|
-
error(e
|
|
64
|
+
error(formatApiError(e));
|
|
64
65
|
process.exit(1);
|
|
65
66
|
}
|
|
66
67
|
});
|
|
@@ -71,6 +72,11 @@ export function permissionsCommand() {
|
|
|
71
72
|
.action(async (resourceType, resourceId, userId, options) => {
|
|
72
73
|
try {
|
|
73
74
|
const config = requireCookie();
|
|
75
|
+
const { confirmAction } = await import('./helpers.js');
|
|
76
|
+
if (!await confirmAction(`Revoke ${userId}'s access to ${resourceType} ${resourceId}?`)) {
|
|
77
|
+
console.log('Cancelled.');
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
74
80
|
const msg = await revokeAccess(config, {
|
|
75
81
|
resource_type: resourceType,
|
|
76
82
|
resource_id: resourceId,
|
|
@@ -79,7 +85,7 @@ export function permissionsCommand() {
|
|
|
79
85
|
output({ message: msg }, options);
|
|
80
86
|
}
|
|
81
87
|
catch (e) {
|
|
82
|
-
error(e
|
|
88
|
+
error(formatApiError(e));
|
|
83
89
|
process.exit(1);
|
|
84
90
|
}
|
|
85
91
|
});
|
|
@@ -94,7 +100,7 @@ export function permissionsCommand() {
|
|
|
94
100
|
output(result, options);
|
|
95
101
|
}
|
|
96
102
|
catch (e) {
|
|
97
|
-
error(e
|
|
103
|
+
error(formatApiError(e));
|
|
98
104
|
process.exit(1);
|
|
99
105
|
}
|
|
100
106
|
});
|
|
@@ -109,7 +115,7 @@ export function permissionsCommand() {
|
|
|
109
115
|
output({ message: msg }, options);
|
|
110
116
|
}
|
|
111
117
|
catch (e) {
|
|
112
|
-
error(e
|
|
118
|
+
error(formatApiError(e));
|
|
113
119
|
process.exit(1);
|
|
114
120
|
}
|
|
115
121
|
});
|
|
@@ -124,7 +130,7 @@ export function permissionsCommand() {
|
|
|
124
130
|
output({ message: msg }, options);
|
|
125
131
|
}
|
|
126
132
|
catch (e) {
|
|
127
|
-
error(e
|
|
133
|
+
error(formatApiError(e));
|
|
128
134
|
process.exit(1);
|
|
129
135
|
}
|
|
130
136
|
});
|
package/dist/cli/projects.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { createProject, renameProject, moveProject, trashProject, restoreProject, setProjectDescription, } from '../operations/projects.js';
|
|
3
3
|
import { output, error } from './format.js';
|
|
4
|
+
import { formatApiError } from '../helpers.js';
|
|
4
5
|
import { requireCookie } from './helpers.js';
|
|
5
6
|
export function projectsCommand() {
|
|
6
7
|
const projects = new Command('projects')
|
|
@@ -17,7 +18,7 @@ export function projectsCommand() {
|
|
|
17
18
|
output(result, options);
|
|
18
19
|
}
|
|
19
20
|
catch (e) {
|
|
20
|
-
error(e
|
|
21
|
+
error(formatApiError(e));
|
|
21
22
|
process.exit(1);
|
|
22
23
|
}
|
|
23
24
|
});
|
|
@@ -33,7 +34,7 @@ export function projectsCommand() {
|
|
|
33
34
|
output({ renamed: projectId, name: options.name }, options);
|
|
34
35
|
}
|
|
35
36
|
catch (e) {
|
|
36
|
-
error(e
|
|
37
|
+
error(formatApiError(e));
|
|
37
38
|
process.exit(1);
|
|
38
39
|
}
|
|
39
40
|
});
|
|
@@ -52,7 +53,7 @@ export function projectsCommand() {
|
|
|
52
53
|
output({ moved: projectId, destination_team_id: options.destination }, options);
|
|
53
54
|
}
|
|
54
55
|
catch (e) {
|
|
55
|
-
error(e
|
|
56
|
+
error(formatApiError(e));
|
|
56
57
|
process.exit(1);
|
|
57
58
|
}
|
|
58
59
|
});
|
|
@@ -63,11 +64,16 @@ export function projectsCommand() {
|
|
|
63
64
|
.action(async (projectId, options) => {
|
|
64
65
|
try {
|
|
65
66
|
const config = requireCookie();
|
|
67
|
+
const { confirmAction } = await import('./helpers.js');
|
|
68
|
+
if (!await confirmAction(`Trash project ${projectId} and all its files?`)) {
|
|
69
|
+
console.log('Cancelled.');
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
66
72
|
await trashProject(config, { project_id: projectId });
|
|
67
73
|
output({ trashed: projectId }, options);
|
|
68
74
|
}
|
|
69
75
|
catch (e) {
|
|
70
|
-
error(e
|
|
76
|
+
error(formatApiError(e));
|
|
71
77
|
process.exit(1);
|
|
72
78
|
}
|
|
73
79
|
});
|
|
@@ -82,7 +88,7 @@ export function projectsCommand() {
|
|
|
82
88
|
output({ restored: projectId }, options);
|
|
83
89
|
}
|
|
84
90
|
catch (e) {
|
|
85
|
-
error(e
|
|
91
|
+
error(formatApiError(e));
|
|
86
92
|
process.exit(1);
|
|
87
93
|
}
|
|
88
94
|
});
|
|
@@ -101,7 +107,7 @@ export function projectsCommand() {
|
|
|
101
107
|
output({ updated: projectId }, options);
|
|
102
108
|
}
|
|
103
109
|
catch (e) {
|
|
104
|
-
error(e
|
|
110
|
+
error(formatApiError(e));
|
|
105
111
|
process.exit(1);
|
|
106
112
|
}
|
|
107
113
|
});
|
package/dist/cli/reading.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { getFile, getNodes } from '../operations/reading.js';
|
|
3
3
|
import { output, error } from './format.js';
|
|
4
|
+
import { formatApiError } from '../helpers.js';
|
|
4
5
|
import { requirePat } from './helpers.js';
|
|
5
6
|
export function readingCommand() {
|
|
6
7
|
const reading = new Command('reading')
|
|
@@ -22,7 +23,7 @@ export function readingCommand() {
|
|
|
22
23
|
output(result, options);
|
|
23
24
|
}
|
|
24
25
|
catch (e) {
|
|
25
|
-
error(e
|
|
26
|
+
error(formatApiError(e));
|
|
26
27
|
process.exit(1);
|
|
27
28
|
}
|
|
28
29
|
});
|
|
@@ -42,7 +43,7 @@ export function readingCommand() {
|
|
|
42
43
|
output(result, options);
|
|
43
44
|
}
|
|
44
45
|
catch (e) {
|
|
45
|
-
error(e
|
|
46
|
+
error(formatApiError(e));
|
|
46
47
|
process.exit(1);
|
|
47
48
|
}
|
|
48
49
|
});
|
package/dist/cli/teams.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { createTeam, renameTeam, deleteTeam } from '../operations/teams.js';
|
|
3
3
|
import { output, error } from './format.js';
|
|
4
|
+
import { formatApiError } from '../helpers.js';
|
|
4
5
|
import { requireCookie } from './helpers.js';
|
|
5
6
|
export function teamsCommand() {
|
|
6
7
|
const teams = new Command('teams')
|
|
@@ -17,7 +18,7 @@ export function teamsCommand() {
|
|
|
17
18
|
output(result, options);
|
|
18
19
|
}
|
|
19
20
|
catch (e) {
|
|
20
|
-
error(e
|
|
21
|
+
error(formatApiError(e));
|
|
21
22
|
process.exit(1);
|
|
22
23
|
}
|
|
23
24
|
});
|
|
@@ -32,7 +33,7 @@ export function teamsCommand() {
|
|
|
32
33
|
output({ message: msg }, options);
|
|
33
34
|
}
|
|
34
35
|
catch (e) {
|
|
35
|
-
error(e
|
|
36
|
+
error(formatApiError(e));
|
|
36
37
|
process.exit(1);
|
|
37
38
|
}
|
|
38
39
|
});
|
|
@@ -43,11 +44,16 @@ export function teamsCommand() {
|
|
|
43
44
|
.action(async (teamId, options) => {
|
|
44
45
|
try {
|
|
45
46
|
const config = requireCookie();
|
|
47
|
+
const { confirmAction } = await import('./helpers.js');
|
|
48
|
+
if (!await confirmAction(`Permanently delete team ${teamId}? All projects and files will be lost.`)) {
|
|
49
|
+
console.log('Cancelled.');
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
46
52
|
const msg = await deleteTeam(config, { team_id: teamId });
|
|
47
53
|
output({ message: msg }, options);
|
|
48
54
|
}
|
|
49
55
|
catch (e) {
|
|
50
|
-
error(e
|
|
56
|
+
error(formatApiError(e));
|
|
51
57
|
process.exit(1);
|
|
52
58
|
}
|
|
53
59
|
});
|
package/dist/cli/variables.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { listLocalVariables, listPublishedVariables, updateVariables, isEnterpriseScopeError, ENTERPRISE_ERROR, } from '../operations/variables.js';
|
|
3
3
|
import { output, error } from './format.js';
|
|
4
|
+
import { formatApiError } from '../helpers.js';
|
|
4
5
|
import { requirePat } from './helpers.js';
|
|
5
6
|
export function variablesCommand() {
|
|
6
7
|
const variables = new Command('variables')
|
|
@@ -13,6 +14,10 @@ export function variablesCommand() {
|
|
|
13
14
|
try {
|
|
14
15
|
const config = requirePat();
|
|
15
16
|
const result = await listLocalVariables(config, { file_key: fileKey });
|
|
17
|
+
if (Object.keys(result.variables ?? {}).length === 0 && Object.keys(result.variableCollections ?? {}).length === 0) {
|
|
18
|
+
console.log('No variables found.');
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
16
21
|
output(result, options);
|
|
17
22
|
}
|
|
18
23
|
catch (e) {
|
|
@@ -20,7 +25,7 @@ export function variablesCommand() {
|
|
|
20
25
|
error(ENTERPRISE_ERROR);
|
|
21
26
|
}
|
|
22
27
|
else {
|
|
23
|
-
error(e
|
|
28
|
+
error(formatApiError(e));
|
|
24
29
|
}
|
|
25
30
|
process.exit(1);
|
|
26
31
|
}
|
|
@@ -33,6 +38,10 @@ export function variablesCommand() {
|
|
|
33
38
|
try {
|
|
34
39
|
const config = requirePat();
|
|
35
40
|
const result = await listPublishedVariables(config, { file_key: fileKey });
|
|
41
|
+
if (Object.keys(result.variables ?? {}).length === 0 && Object.keys(result.variableCollections ?? {}).length === 0) {
|
|
42
|
+
console.log('No published variables found.');
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
36
45
|
output(result, options);
|
|
37
46
|
}
|
|
38
47
|
catch (e) {
|
|
@@ -40,7 +49,7 @@ export function variablesCommand() {
|
|
|
40
49
|
error(ENTERPRISE_ERROR);
|
|
41
50
|
}
|
|
42
51
|
else {
|
|
43
|
-
error(e
|
|
52
|
+
error(formatApiError(e));
|
|
44
53
|
}
|
|
45
54
|
process.exit(1);
|
|
46
55
|
}
|
|
@@ -56,12 +65,25 @@ export function variablesCommand() {
|
|
|
56
65
|
.action(async (fileKey, options) => {
|
|
57
66
|
try {
|
|
58
67
|
const config = requirePat();
|
|
68
|
+
const variableCollections = options.variableCollections ? JSON.parse(options.variableCollections) : undefined;
|
|
69
|
+
const variableModes = options.variableModes ? JSON.parse(options.variableModes) : undefined;
|
|
70
|
+
const variables = options.variables ? JSON.parse(options.variables) : undefined;
|
|
71
|
+
const variableModeValues = options.variableModeValues ? JSON.parse(options.variableModeValues) : undefined;
|
|
72
|
+
const allOps = [...(variables || []), ...(variableCollections || []), ...(variableModes || []), ...(variableModeValues || [])];
|
|
73
|
+
const hasDeletes = allOps.some((op) => op.action === 'DELETE');
|
|
74
|
+
if (hasDeletes) {
|
|
75
|
+
const { confirmAction } = await import('./helpers.js');
|
|
76
|
+
if (!await confirmAction('This includes DELETE operations that cannot be undone. Continue?')) {
|
|
77
|
+
console.log('Cancelled.');
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
59
81
|
const result = await updateVariables(config, {
|
|
60
82
|
file_key: fileKey,
|
|
61
|
-
variable_collections:
|
|
62
|
-
variable_modes:
|
|
63
|
-
variables:
|
|
64
|
-
variable_mode_values:
|
|
83
|
+
variable_collections: variableCollections,
|
|
84
|
+
variable_modes: variableModes,
|
|
85
|
+
variables: variables,
|
|
86
|
+
variable_mode_values: variableModeValues,
|
|
65
87
|
});
|
|
66
88
|
output(result, options);
|
|
67
89
|
}
|
|
@@ -70,7 +92,7 @@ export function variablesCommand() {
|
|
|
70
92
|
error(ENTERPRISE_ERROR);
|
|
71
93
|
}
|
|
72
94
|
else {
|
|
73
|
-
error(e
|
|
95
|
+
error(formatApiError(e));
|
|
74
96
|
}
|
|
75
97
|
process.exit(1);
|
|
76
98
|
}
|
package/dist/cli/versions.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { listVersions, createVersion } from '../operations/versions.js';
|
|
3
3
|
import { output, error } from './format.js';
|
|
4
|
+
import { formatApiError } from '../helpers.js';
|
|
4
5
|
import { requirePat, requireCookie } from './helpers.js';
|
|
5
6
|
export function versionsCommand() {
|
|
6
7
|
const versions = new Command('versions')
|
|
@@ -16,7 +17,7 @@ export function versionsCommand() {
|
|
|
16
17
|
output(result, options);
|
|
17
18
|
}
|
|
18
19
|
catch (e) {
|
|
19
|
-
error(e
|
|
20
|
+
error(formatApiError(e));
|
|
20
21
|
process.exit(1);
|
|
21
22
|
}
|
|
22
23
|
});
|
|
@@ -37,7 +38,7 @@ export function versionsCommand() {
|
|
|
37
38
|
output(result, options);
|
|
38
39
|
}
|
|
39
40
|
catch (e) {
|
|
40
|
-
error(e
|
|
41
|
+
error(formatApiError(e));
|
|
41
42
|
process.exit(1);
|
|
42
43
|
}
|
|
43
44
|
});
|
package/dist/cli/webhooks.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { listWebhooks, createWebhook, updateWebhook, deleteWebhook, } from '../operations/webhooks.js';
|
|
3
3
|
import { output, error } from './format.js';
|
|
4
|
+
import { formatApiError } from '../helpers.js';
|
|
4
5
|
import { requirePat } from './helpers.js';
|
|
5
6
|
const VALID_EVENT_TYPES = [
|
|
6
7
|
'FILE_UPDATE',
|
|
@@ -21,10 +22,14 @@ export function webhooksCommand() {
|
|
|
21
22
|
try {
|
|
22
23
|
const config = requirePat();
|
|
23
24
|
const result = await listWebhooks(config, { team_id: teamId });
|
|
25
|
+
if (result.webhooks.length === 0) {
|
|
26
|
+
console.log('No webhooks found.');
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
24
29
|
output(result, options);
|
|
25
30
|
}
|
|
26
31
|
catch (e) {
|
|
27
|
-
error(e
|
|
32
|
+
error(formatApiError(e));
|
|
28
33
|
process.exit(1);
|
|
29
34
|
}
|
|
30
35
|
});
|
|
@@ -49,7 +54,7 @@ export function webhooksCommand() {
|
|
|
49
54
|
output(result, options);
|
|
50
55
|
}
|
|
51
56
|
catch (e) {
|
|
52
|
-
error(e
|
|
57
|
+
error(formatApiError(e));
|
|
53
58
|
process.exit(1);
|
|
54
59
|
}
|
|
55
60
|
});
|
|
@@ -76,7 +81,7 @@ export function webhooksCommand() {
|
|
|
76
81
|
output(result, options);
|
|
77
82
|
}
|
|
78
83
|
catch (e) {
|
|
79
|
-
error(e
|
|
84
|
+
error(formatApiError(e));
|
|
80
85
|
process.exit(1);
|
|
81
86
|
}
|
|
82
87
|
});
|
|
@@ -87,11 +92,16 @@ export function webhooksCommand() {
|
|
|
87
92
|
.action(async (webhookId, options) => {
|
|
88
93
|
try {
|
|
89
94
|
const config = requirePat();
|
|
95
|
+
const { confirmAction } = await import('./helpers.js');
|
|
96
|
+
if (!await confirmAction(`Delete webhook ${webhookId}?`)) {
|
|
97
|
+
console.log('Cancelled.');
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
90
100
|
await deleteWebhook(config, { webhook_id: webhookId });
|
|
91
101
|
output({ deleted: webhookId }, options);
|
|
92
102
|
}
|
|
93
103
|
catch (e) {
|
|
94
|
-
error(e
|
|
104
|
+
error(formatApiError(e));
|
|
95
105
|
process.exit(1);
|
|
96
106
|
}
|
|
97
107
|
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { AuthConfig } from './auth/client.js';
|
|
2
|
+
/**
|
|
3
|
+
* Extract actionable error info from Figma API errors.
|
|
4
|
+
* Includes response body when available, maps common status codes.
|
|
5
|
+
*/
|
|
6
|
+
export declare function formatApiError(e: any): string;
|
|
7
|
+
/** Resolve an org ID from explicit param or config. Returns undefined if neither set. */
|
|
8
|
+
export declare function resolveOrgId(config: AuthConfig, explicit?: string): string | undefined;
|
|
9
|
+
/** Require an org ID, throwing with guidance if missing. */
|
|
10
|
+
export declare function requireOrgId(config: AuthConfig, explicit?: string): string;
|
|
11
|
+
//# sourceMappingURL=helpers.d.ts.map
|
package/dist/helpers.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract actionable error info from Figma API errors.
|
|
3
|
+
* Includes response body when available, maps common status codes.
|
|
4
|
+
*/
|
|
5
|
+
export function formatApiError(e) {
|
|
6
|
+
const status = e.response?.status;
|
|
7
|
+
if (!status)
|
|
8
|
+
return e.message || 'Unknown error';
|
|
9
|
+
const body = e.response?.data;
|
|
10
|
+
const detail = typeof body === 'string'
|
|
11
|
+
? body
|
|
12
|
+
: body?.message || body?.err || body?.error || '';
|
|
13
|
+
const statusMessages = {
|
|
14
|
+
400: 'Bad request',
|
|
15
|
+
401: 'Authentication expired or invalid. Re-run setup.',
|
|
16
|
+
403: 'Insufficient permissions for this action',
|
|
17
|
+
404: 'Resource not found. Check the ID.',
|
|
18
|
+
409: 'Conflict -- resource may already exist or be in use',
|
|
19
|
+
429: 'Rate limited. Try again in a moment.',
|
|
20
|
+
500: 'Figma server error. Try again later.',
|
|
21
|
+
};
|
|
22
|
+
const base = statusMessages[status] || `HTTP ${status}`;
|
|
23
|
+
return detail ? `${base}: ${detail}` : base;
|
|
24
|
+
}
|
|
25
|
+
/** Resolve an org ID from explicit param or config. Returns undefined if neither set. */
|
|
26
|
+
export function resolveOrgId(config, explicit) {
|
|
27
|
+
const id = explicit || config.orgId;
|
|
28
|
+
if (id && !/^[\w.:-]+$/.test(id))
|
|
29
|
+
throw new Error('Invalid org ID format');
|
|
30
|
+
return id;
|
|
31
|
+
}
|
|
32
|
+
/** Require an org ID, throwing with guidance if missing. */
|
|
33
|
+
export function requireOrgId(config, explicit) {
|
|
34
|
+
const id = explicit || config.orgId;
|
|
35
|
+
if (!id)
|
|
36
|
+
throw new Error('Org context required. Run list_orgs to see available workspaces, or set FIGMA_ORG_ID.');
|
|
37
|
+
if (!/^[\w.:-]+$/.test(id))
|
|
38
|
+
throw new Error('Invalid org ID format');
|
|
39
|
+
return id;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { internalClient } from '../clients/internal-api.js';
|
|
2
|
-
import { requireOrgId } from '../
|
|
2
|
+
import { requireOrgId } from '../helpers.js';
|
|
3
3
|
export async function libraryUsage(config, params) {
|
|
4
4
|
const lookback = params.days ?? 30;
|
|
5
5
|
const end_ts = Math.floor(Date.now() / 1000);
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import type { AuthConfig } from '../auth/client.js';
|
|
2
2
|
export declare function listFileComponents(config: AuthConfig, params: {
|
|
3
3
|
file_key: string;
|
|
4
|
-
}): Promise<
|
|
4
|
+
}): Promise<{
|
|
5
|
+
count: number;
|
|
6
|
+
components: any[];
|
|
7
|
+
}>;
|
|
5
8
|
export declare function listFileStyles(config: AuthConfig, params: {
|
|
6
9
|
file_key: string;
|
|
7
|
-
}): Promise<
|
|
10
|
+
}): Promise<{
|
|
11
|
+
count: number;
|
|
12
|
+
styles: any[];
|
|
13
|
+
}>;
|
|
8
14
|
export declare function listTeamComponents(config: AuthConfig, params: {
|
|
9
15
|
team_id: string;
|
|
10
16
|
page_size?: number;
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { publicClient } from '../clients/public-api.js';
|
|
2
2
|
export async function listFileComponents(config, params) {
|
|
3
3
|
const res = await publicClient(config).get(`/v1/files/${params.file_key}/components`);
|
|
4
|
-
|
|
4
|
+
const components = res.data?.meta?.components || [];
|
|
5
|
+
return { count: components.length, components };
|
|
5
6
|
}
|
|
6
7
|
export async function listFileStyles(config, params) {
|
|
7
8
|
const res = await publicClient(config).get(`/v1/files/${params.file_key}/styles`);
|
|
8
|
-
|
|
9
|
+
const styles = res.data?.meta?.styles || [];
|
|
10
|
+
return { count: styles.length, styles };
|
|
9
11
|
}
|
|
10
12
|
export async function listTeamComponents(config, params) {
|
|
11
13
|
const queryParams = { page_size: params.page_size ?? 30 };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { internalClient } from '../clients/internal-api.js';
|
|
2
|
-
import { requireOrgId } from '../
|
|
2
|
+
import { requireOrgId, formatApiError } from '../helpers.js';
|
|
3
3
|
import { levelName } from './compound.js';
|
|
4
4
|
// -- Shared helpers --
|
|
5
5
|
const BATCH_SIZE = 5;
|
|
@@ -241,7 +241,7 @@ export async function offboardUser(config, params) {
|
|
|
241
241
|
actions.push({ action: 'transfer_ownership', status: 'done', detail: `${file.file_name} -> ${transfer_to}` });
|
|
242
242
|
}
|
|
243
243
|
catch (e) {
|
|
244
|
-
actions.push({ action: 'transfer_ownership', status: 'failed', detail: `${file.file_name}: ${e
|
|
244
|
+
actions.push({ action: 'transfer_ownership', status: 'failed', detail: `${file.file_name}: ${formatApiError(e)}` });
|
|
245
245
|
}
|
|
246
246
|
}
|
|
247
247
|
}
|
|
@@ -257,7 +257,7 @@ export async function offboardUser(config, params) {
|
|
|
257
257
|
}
|
|
258
258
|
}
|
|
259
259
|
catch (e) {
|
|
260
|
-
actions.push({ action: 'revoke_file', status: 'failed', detail: `${file.file_name}: ${e
|
|
260
|
+
actions.push({ action: 'revoke_file', status: 'failed', detail: `${file.file_name}: ${formatApiError(e)}` });
|
|
261
261
|
}
|
|
262
262
|
}
|
|
263
263
|
// Step C: Revoke project access
|
|
@@ -312,7 +312,7 @@ export async function offboardUser(config, params) {
|
|
|
312
312
|
actions.push({ action: 'downgrade_seat', status: 'done', detail: `${user.seat_type} -> viewer` });
|
|
313
313
|
}
|
|
314
314
|
catch (e) {
|
|
315
|
-
actions.push({ action: 'downgrade_seat', status: 'failed', detail: e
|
|
315
|
+
actions.push({ action: 'downgrade_seat', status: 'failed', detail: formatApiError(e) });
|
|
316
316
|
}
|
|
317
317
|
}
|
|
318
318
|
const succeeded = actions.filter(a => a.status === 'done').length;
|
|
@@ -421,7 +421,7 @@ export async function onboardUser(config, params) {
|
|
|
421
421
|
}
|
|
422
422
|
}
|
|
423
423
|
catch (e) {
|
|
424
|
-
seatChange = { status: 'failed', note: `Seat change failed: ${e
|
|
424
|
+
seatChange = { status: 'failed', note: `Seat change failed: ${formatApiError(e)}` };
|
|
425
425
|
}
|
|
426
426
|
}
|
|
427
427
|
else if (seat_type && !confirm) {
|
|
@@ -482,7 +482,7 @@ export async function quarterlyDesignOpsReport(config, params) {
|
|
|
482
482
|
}
|
|
483
483
|
catch (e) {
|
|
484
484
|
membersComplete = false;
|
|
485
|
-
errors.push(`members: pagination stopped at page ${page + 1} of ${maxPages}, fetched ${allMembers.length} members (${e
|
|
485
|
+
errors.push(`members: pagination stopped at page ${page + 1} of ${maxPages}, fetched ${allMembers.length} members (${formatApiError(e)})`);
|
|
486
486
|
break;
|
|
487
487
|
}
|
|
488
488
|
}
|
|
@@ -609,6 +609,8 @@ export async function quarterlyDesignOpsReport(config, params) {
|
|
|
609
609
|
highlights.push(`${totalInsertions} library component insertions across ${libraryAdoption.length} library/libraries.`);
|
|
610
610
|
}
|
|
611
611
|
const result = {
|
|
612
|
+
highlights,
|
|
613
|
+
...(errors.length > 0 ? { errors } : {}),
|
|
612
614
|
period: {
|
|
613
615
|
start: periodStart.toISOString().split('T')[0],
|
|
614
616
|
end: now.toISOString().split('T')[0],
|
|
@@ -628,10 +630,7 @@ export async function quarterlyDesignOpsReport(config, params) {
|
|
|
628
630
|
teams,
|
|
629
631
|
billing,
|
|
630
632
|
library_adoption: libraryAdoption,
|
|
631
|
-
highlights,
|
|
632
633
|
};
|
|
633
|
-
if (errors.length > 0)
|
|
634
|
-
result.errors = errors;
|
|
635
634
|
return result;
|
|
636
635
|
}
|
|
637
636
|
//# sourceMappingURL=compound-manager.js.map
|
|
@@ -29,7 +29,9 @@ export declare function organizeProject(config: AuthConfig, params: {
|
|
|
29
29
|
file_keys: string[];
|
|
30
30
|
target_project_id: string;
|
|
31
31
|
}): Promise<{
|
|
32
|
+
target_project_id: string;
|
|
32
33
|
moved: number;
|
|
34
|
+
moved_file_keys: string[];
|
|
33
35
|
failed: number;
|
|
34
36
|
errors: any;
|
|
35
37
|
}>;
|
|
@@ -87,6 +89,7 @@ export declare function branchCleanup(config: AuthConfig, params: {
|
|
|
87
89
|
active_branches: any[];
|
|
88
90
|
dry_run: boolean;
|
|
89
91
|
archived: boolean;
|
|
92
|
+
archived_count: number;
|
|
90
93
|
recommendations: string[];
|
|
91
94
|
}>;
|
|
92
95
|
//# sourceMappingURL=compound.d.ts.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { hasPat, hasCookie } from '../auth/client.js';
|
|
2
2
|
import { publicClient } from '../clients/public-api.js';
|
|
3
3
|
import { internalClient } from '../clients/internal-api.js';
|
|
4
|
-
import { requireOrgId } from '../
|
|
4
|
+
import { requireOrgId, formatApiError } from '../helpers.js';
|
|
5
5
|
// -- Shared helpers --
|
|
6
6
|
const BATCH_SIZE = 5;
|
|
7
7
|
async function batchProcess(items, fn) {
|
|
@@ -32,7 +32,7 @@ export async function fileSummary(config, params) {
|
|
|
32
32
|
api.get(`/v1/files/${params.file_key}/comments`),
|
|
33
33
|
]);
|
|
34
34
|
if (fileResult.status === 'rejected') {
|
|
35
|
-
throw new Error(`Failed to fetch file: ${fileResult.reason
|
|
35
|
+
throw new Error(`Failed to fetch file: ${formatApiError(fileResult.reason)}`);
|
|
36
36
|
}
|
|
37
37
|
const fileData = fileResult.value.data;
|
|
38
38
|
const pages = (fileData.document?.children || []).map((c) => c.name);
|
|
@@ -78,11 +78,11 @@ export async function workspaceOverview(config, params) {
|
|
|
78
78
|
delete billing.shipping_address;
|
|
79
79
|
const errors = [];
|
|
80
80
|
if (teamsResult.status === 'rejected')
|
|
81
|
-
errors.push(`teams: ${teamsResult.reason
|
|
81
|
+
errors.push(`teams: ${formatApiError(teamsResult.reason)}`);
|
|
82
82
|
if (seatsResult.status === 'rejected')
|
|
83
|
-
errors.push(`seats: ${seatsResult.reason
|
|
83
|
+
errors.push(`seats: ${formatApiError(seatsResult.reason)}`);
|
|
84
84
|
if (billingResult.status === 'rejected')
|
|
85
|
-
errors.push(`billing: ${billingResult.reason
|
|
85
|
+
errors.push(`billing: ${formatApiError(billingResult.reason)}`);
|
|
86
86
|
const overview = { teams, seats, billing };
|
|
87
87
|
if (errors.length > 0)
|
|
88
88
|
overview.errors = errors;
|
|
@@ -104,7 +104,7 @@ export async function openComments(config, params) {
|
|
|
104
104
|
commentResults.push({ file_key: f.key, file_name: f.name, comments });
|
|
105
105
|
}
|
|
106
106
|
catch (e) {
|
|
107
|
-
commentResults.push({ file_key: f.key, file_name: f.name, comments: [], error: e
|
|
107
|
+
commentResults.push({ file_key: f.key, file_name: f.name, comments: [], error: formatApiError(e) });
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
110
|
const filesWithComments = commentResults
|
|
@@ -180,6 +180,8 @@ export async function cleanupStaleFiles(config, params) {
|
|
|
180
180
|
data: { files: staleFiles.map((f) => ({ key: f.key })), trashed: true },
|
|
181
181
|
});
|
|
182
182
|
result.trashed = true;
|
|
183
|
+
result.trashed_count = staleFiles.length;
|
|
184
|
+
result.trashed_file_keys = staleFiles.map((f) => f.key);
|
|
183
185
|
}
|
|
184
186
|
}
|
|
185
187
|
return result;
|
|
@@ -199,7 +201,9 @@ export async function organizeProject(config, params) {
|
|
|
199
201
|
const moved = Object.keys(data?.success || {}).length;
|
|
200
202
|
const failed = Object.keys(data?.errors || {}).length;
|
|
201
203
|
return {
|
|
204
|
+
target_project_id: params.target_project_id,
|
|
202
205
|
moved: moved || (failed === 0 ? params.file_keys.length : 0),
|
|
206
|
+
moved_file_keys: params.file_keys,
|
|
203
207
|
failed,
|
|
204
208
|
errors: data?.errors || {},
|
|
205
209
|
};
|
|
@@ -230,7 +234,7 @@ export async function setupProjectStructure(config, params) {
|
|
|
230
234
|
created.push({ id: folderId, name: project.name, description: project.description || null });
|
|
231
235
|
}
|
|
232
236
|
catch (e) {
|
|
233
|
-
failed.push({ name: project.name, error: e
|
|
237
|
+
failed.push({ name: project.name, error: formatApiError(e) });
|
|
234
238
|
}
|
|
235
239
|
}
|
|
236
240
|
return { created, failed };
|
|
@@ -265,7 +269,7 @@ export async function seatOptimization(config, params) {
|
|
|
265
269
|
}
|
|
266
270
|
catch (e) {
|
|
267
271
|
membersComplete = false;
|
|
268
|
-
warnings.push(`members: pagination stopped at page ${page + 1}, fetched ${allMembers.length} members (${e
|
|
272
|
+
warnings.push(`members: pagination stopped at page ${page + 1}, fetched ${allMembers.length} members (${formatApiError(e)})`);
|
|
269
273
|
break;
|
|
270
274
|
}
|
|
271
275
|
}
|
|
@@ -584,6 +588,7 @@ export async function branchCleanup(config, params) {
|
|
|
584
588
|
});
|
|
585
589
|
archived = true;
|
|
586
590
|
}
|
|
591
|
+
const archived_count = archived ? staleBranches.length : 0;
|
|
587
592
|
const recommendations = [];
|
|
588
593
|
if (staleBranches.length > 0) {
|
|
589
594
|
recommendations.push(`${staleBranches.length} branch(es) stale for ${days_stale}+ days. ${dry_run ? 'Set dry_run=false to archive.' : 'Archived.'}`);
|
|
@@ -606,6 +611,7 @@ export async function branchCleanup(config, params) {
|
|
|
606
611
|
active_branches: activeBranches,
|
|
607
612
|
dry_run,
|
|
608
613
|
archived,
|
|
614
|
+
archived_count,
|
|
609
615
|
recommendations,
|
|
610
616
|
};
|
|
611
617
|
}
|