figmanage 1.2.9 → 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/README.md +10 -8
- 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/mcp.js +18 -6
- 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/setup.d.ts +10 -0
- package/dist/tools/setup.js +181 -0
- 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/org.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { listAdmins, listOrgTeams, seatUsage, listTeamMembers, billingOverview, listInvoices, orgDomains, aiCreditUsage, exportMembers, listOrgMembers, contractRates, changeSeat, } from '../operations/org.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 orgCommand() {
|
|
6
7
|
const org = new Command('org')
|
|
@@ -21,7 +22,7 @@ export function orgCommand() {
|
|
|
21
22
|
output(result, options);
|
|
22
23
|
}
|
|
23
24
|
catch (e) {
|
|
24
|
-
error(e
|
|
25
|
+
error(formatApiError(e));
|
|
25
26
|
process.exit(1);
|
|
26
27
|
}
|
|
27
28
|
});
|
|
@@ -41,7 +42,7 @@ export function orgCommand() {
|
|
|
41
42
|
output(result, options);
|
|
42
43
|
}
|
|
43
44
|
catch (e) {
|
|
44
|
-
error(e
|
|
45
|
+
error(formatApiError(e));
|
|
45
46
|
process.exit(1);
|
|
46
47
|
}
|
|
47
48
|
});
|
|
@@ -61,7 +62,7 @@ export function orgCommand() {
|
|
|
61
62
|
output(result, options);
|
|
62
63
|
}
|
|
63
64
|
catch (e) {
|
|
64
|
-
error(e
|
|
65
|
+
error(formatApiError(e));
|
|
65
66
|
process.exit(1);
|
|
66
67
|
}
|
|
67
68
|
});
|
|
@@ -76,7 +77,7 @@ export function orgCommand() {
|
|
|
76
77
|
output(result, options);
|
|
77
78
|
}
|
|
78
79
|
catch (e) {
|
|
79
|
-
error(e
|
|
80
|
+
error(formatApiError(e));
|
|
80
81
|
process.exit(1);
|
|
81
82
|
}
|
|
82
83
|
});
|
|
@@ -92,7 +93,7 @@ export function orgCommand() {
|
|
|
92
93
|
output(result, options);
|
|
93
94
|
}
|
|
94
95
|
catch (e) {
|
|
95
|
-
error(e
|
|
96
|
+
error(formatApiError(e));
|
|
96
97
|
process.exit(1);
|
|
97
98
|
}
|
|
98
99
|
});
|
|
@@ -108,7 +109,7 @@ export function orgCommand() {
|
|
|
108
109
|
output(result, options);
|
|
109
110
|
}
|
|
110
111
|
catch (e) {
|
|
111
|
-
error(e
|
|
112
|
+
error(formatApiError(e));
|
|
112
113
|
process.exit(1);
|
|
113
114
|
}
|
|
114
115
|
});
|
|
@@ -124,7 +125,7 @@ export function orgCommand() {
|
|
|
124
125
|
output(result, options);
|
|
125
126
|
}
|
|
126
127
|
catch (e) {
|
|
127
|
-
error(e
|
|
128
|
+
error(formatApiError(e));
|
|
128
129
|
process.exit(1);
|
|
129
130
|
}
|
|
130
131
|
});
|
|
@@ -139,7 +140,7 @@ export function orgCommand() {
|
|
|
139
140
|
output(result, options);
|
|
140
141
|
}
|
|
141
142
|
catch (e) {
|
|
142
|
-
error(e
|
|
143
|
+
error(formatApiError(e));
|
|
143
144
|
process.exit(1);
|
|
144
145
|
}
|
|
145
146
|
});
|
|
@@ -155,7 +156,7 @@ export function orgCommand() {
|
|
|
155
156
|
output({ message: msg }, options);
|
|
156
157
|
}
|
|
157
158
|
catch (e) {
|
|
158
|
-
error(e
|
|
159
|
+
error(formatApiError(e));
|
|
159
160
|
process.exit(1);
|
|
160
161
|
}
|
|
161
162
|
});
|
|
@@ -175,7 +176,7 @@ export function orgCommand() {
|
|
|
175
176
|
output(result, options);
|
|
176
177
|
}
|
|
177
178
|
catch (e) {
|
|
178
|
-
error(e
|
|
179
|
+
error(formatApiError(e));
|
|
179
180
|
process.exit(1);
|
|
180
181
|
}
|
|
181
182
|
});
|
|
@@ -191,7 +192,7 @@ export function orgCommand() {
|
|
|
191
192
|
output(result, options);
|
|
192
193
|
}
|
|
193
194
|
catch (e) {
|
|
194
|
-
error(e
|
|
195
|
+
error(formatApiError(e));
|
|
195
196
|
process.exit(1);
|
|
196
197
|
}
|
|
197
198
|
});
|
|
@@ -218,7 +219,7 @@ export function orgCommand() {
|
|
|
218
219
|
}
|
|
219
220
|
}
|
|
220
221
|
catch (e) {
|
|
221
|
-
error(e
|
|
222
|
+
error(formatApiError(e));
|
|
222
223
|
process.exit(1);
|
|
223
224
|
}
|
|
224
225
|
});
|
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
|
package/dist/mcp.js
CHANGED
|
@@ -5,6 +5,7 @@ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
|
|
|
5
5
|
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
6
6
|
import { loadAuthConfig, hasPat, hasCookie } from './auth/client.js';
|
|
7
7
|
import { registerTools } from './tools/register.js';
|
|
8
|
+
import { registerSetupTools } from './tools/setup.js';
|
|
8
9
|
// Import tool modules (side-effect: registers via defineTool)
|
|
9
10
|
import './tools/navigate.js';
|
|
10
11
|
import './tools/files.js';
|
|
@@ -64,16 +65,27 @@ export async function startMcpServer() {
|
|
|
64
65
|
const config = loadAuthConfig();
|
|
65
66
|
const readOnly = process.env.FIGMA_READ_ONLY === '1' || process.env.FIGMA_READ_ONLY === 'true';
|
|
66
67
|
const enabledToolsets = parseToolsets(process.env.FIGMA_TOOLSETS);
|
|
67
|
-
if (!hasPat(config) && !hasCookie(config)) {
|
|
68
|
-
console.error('No auth configured. Set FIGMA_PAT for public API access, or ' +
|
|
69
|
-
'FIGMA_AUTH_COOKIE + FIGMA_USER_ID for internal API access.');
|
|
70
|
-
process.exit(1);
|
|
71
|
-
}
|
|
72
68
|
const server = new McpServer({
|
|
73
69
|
name: 'figmanage',
|
|
74
70
|
version: '0.1.0',
|
|
75
71
|
});
|
|
76
|
-
|
|
72
|
+
const fullyConfigured = hasPat(config) && hasCookie(config);
|
|
73
|
+
if (fullyConfigured) {
|
|
74
|
+
registerTools(server, config, enabledToolsets, readOnly);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
// No auth or partial auth: register setup tools.
|
|
78
|
+
// If env vars provide some auth, also register whatever tools are available.
|
|
79
|
+
if (hasPat(config) || hasCookie(config)) {
|
|
80
|
+
registerTools(server, config, enabledToolsets, readOnly);
|
|
81
|
+
}
|
|
82
|
+
registerSetupTools(server, () => {
|
|
83
|
+
// Re-load config after setup wrote credentials to disk
|
|
84
|
+
const newConfig = loadAuthConfig();
|
|
85
|
+
registerTools(server, newConfig, enabledToolsets, readOnly);
|
|
86
|
+
server.server.sendToolListChanged();
|
|
87
|
+
});
|
|
88
|
+
}
|
|
77
89
|
const httpPort = parseHttpPort(process.argv);
|
|
78
90
|
if (httpPort) {
|
|
79
91
|
// Bearer token auth for HTTP transport
|
|
@@ -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 };
|