figmanage 1.0.1 → 1.2.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.
Files changed (98) hide show
  1. package/README.md +74 -59
  2. package/dist/cli/analytics.d.ts +3 -0
  3. package/dist/cli/analytics.js +48 -0
  4. package/dist/cli/branching.d.ts +3 -0
  5. package/dist/cli/branching.js +56 -0
  6. package/dist/cli/comments.d.ts +3 -0
  7. package/dist/cli/comments.js +86 -0
  8. package/dist/cli/completion.d.ts +7 -0
  9. package/dist/cli/completion.js +160 -0
  10. package/dist/cli/components.d.ts +3 -0
  11. package/dist/cli/components.js +82 -0
  12. package/dist/cli/compound-commands.d.ts +14 -0
  13. package/dist/cli/compound-commands.js +291 -0
  14. package/dist/cli/export.d.ts +3 -0
  15. package/dist/cli/export.js +51 -0
  16. package/dist/cli/files.d.ts +3 -0
  17. package/dist/cli/files.js +156 -0
  18. package/dist/cli/format.js +147 -2
  19. package/dist/cli/helpers.d.ts +7 -0
  20. package/dist/cli/helpers.js +43 -0
  21. package/dist/cli/index.js +68 -89
  22. package/dist/cli/libraries.d.ts +3 -0
  23. package/dist/cli/libraries.js +26 -0
  24. package/dist/cli/navigate.d.ts +3 -0
  25. package/dist/cli/navigate.js +192 -0
  26. package/dist/cli/org.d.ts +3 -0
  27. package/dist/cli/org.js +227 -0
  28. package/dist/cli/permissions.d.ts +3 -0
  29. package/dist/cli/permissions.js +133 -0
  30. package/dist/cli/projects.d.ts +3 -0
  31. package/dist/cli/projects.js +110 -0
  32. package/dist/cli/reading.d.ts +3 -0
  33. package/dist/cli/reading.js +51 -0
  34. package/dist/cli/teams.d.ts +3 -0
  35. package/dist/cli/teams.js +56 -0
  36. package/dist/cli/variables.d.ts +3 -0
  37. package/dist/cli/variables.js +80 -0
  38. package/dist/cli/versions.d.ts +3 -0
  39. package/dist/cli/versions.js +46 -0
  40. package/dist/cli/webhooks.d.ts +3 -0
  41. package/dist/cli/webhooks.js +100 -0
  42. package/dist/operations/analytics.d.ts +10 -0
  43. package/dist/operations/analytics.js +15 -0
  44. package/dist/operations/branching.d.ts +24 -0
  45. package/dist/operations/branching.js +41 -0
  46. package/dist/operations/comments.d.ts +43 -0
  47. package/dist/operations/comments.js +65 -0
  48. package/dist/operations/components.d.ts +24 -0
  49. package/dist/operations/components.js +30 -0
  50. package/dist/operations/compound-manager.d.ts +101 -0
  51. package/dist/operations/compound-manager.js +629 -0
  52. package/dist/operations/compound.d.ts +102 -0
  53. package/dist/operations/compound.js +595 -0
  54. package/dist/operations/export.d.ts +19 -0
  55. package/dist/operations/export.js +27 -0
  56. package/dist/operations/files.d.ts +55 -0
  57. package/dist/operations/files.js +89 -0
  58. package/dist/operations/libraries.d.ts +5 -0
  59. package/dist/operations/libraries.js +10 -0
  60. package/dist/operations/navigate.d.ts +99 -0
  61. package/dist/operations/navigate.js +266 -0
  62. package/dist/operations/org.d.ts +95 -0
  63. package/dist/operations/org.js +205 -0
  64. package/dist/operations/permissions.d.ts +59 -0
  65. package/dist/operations/permissions.js +112 -0
  66. package/dist/operations/projects.d.ts +29 -0
  67. package/dist/operations/projects.js +40 -0
  68. package/dist/operations/reading.d.ts +12 -0
  69. package/dist/operations/reading.js +20 -0
  70. package/dist/operations/teams.d.ts +17 -0
  71. package/dist/operations/teams.js +17 -0
  72. package/dist/operations/variables.d.ts +17 -0
  73. package/dist/operations/variables.js +39 -0
  74. package/dist/operations/versions.d.ts +23 -0
  75. package/dist/operations/versions.js +27 -0
  76. package/dist/operations/webhooks.d.ts +25 -0
  77. package/dist/operations/webhooks.js +38 -0
  78. package/dist/tools/analytics.js +6 -16
  79. package/dist/tools/branching.js +7 -36
  80. package/dist/tools/comments.js +9 -56
  81. package/dist/tools/components.js +7 -19
  82. package/dist/tools/compound-manager.js +21 -644
  83. package/dist/tools/compound.js +32 -566
  84. package/dist/tools/export.js +4 -23
  85. package/dist/tools/files.js +21 -68
  86. package/dist/tools/libraries.js +4 -11
  87. package/dist/tools/navigate.js +23 -246
  88. package/dist/tools/org.js +29 -245
  89. package/dist/tools/permissions.js +18 -97
  90. package/dist/tools/projects.js +8 -27
  91. package/dist/tools/reading.js +5 -15
  92. package/dist/tools/teams.js +8 -16
  93. package/dist/tools/variables.js +13 -30
  94. package/dist/tools/versions.js +6 -24
  95. package/dist/tools/webhooks.js +7 -24
  96. package/package.json +1 -1
  97. package/dist/cli/commands.d.ts +0 -47
  98. package/dist/cli/commands.js +0 -1204
@@ -0,0 +1,205 @@
1
+ import { internalClient } from '../clients/internal-api.js';
2
+ import { requireOrgId } from '../tools/register.js';
3
+ // -- Seat constants --
4
+ export const SEAT_HIERARCHY = {
5
+ view: 0,
6
+ collab: 1,
7
+ dev: 2,
8
+ full: 3,
9
+ };
10
+ export const SEAT_LABELS = {
11
+ view: 'Viewer (free)',
12
+ collab: 'Collaborator ($5/mo)',
13
+ dev: 'Developer ($25/mo)',
14
+ full: 'Full ($55/mo)',
15
+ };
16
+ export const PAID_STATUSES = {
17
+ full: { expert: 'full' },
18
+ dev: { developer: 'full' },
19
+ collab: { collaborator: 'full' },
20
+ view: { collaborator: 'starter', developer: 'starter', expert: 'starter' },
21
+ };
22
+ export const SEAT_KEY_TO_TYPE = {
23
+ expert: 'full',
24
+ developer: 'dev',
25
+ collaborator: 'collab',
26
+ };
27
+ export async function listAdmins(config, params) {
28
+ const orgId = requireOrgId(config, params.org_id);
29
+ const res = await internalClient(config).get(`/api/orgs/${orgId}/admins`, { params: { include_license_admins: params.include_license_admins ?? false } });
30
+ return (res.data?.meta || []).map((a) => ({
31
+ user_id: a.user_id,
32
+ email: a.user?.email,
33
+ name: a.user?.handle,
34
+ permission: a.permission,
35
+ seat_type: a.active_seat_type?.key || null,
36
+ is_email_validated: a.is_email_validated,
37
+ license_admin: a.license_admin,
38
+ }));
39
+ }
40
+ export async function listOrgTeams(config, params) {
41
+ const orgId = requireOrgId(config, params.org_id);
42
+ const res = await internalClient(config).get(`/api/orgs/${orgId}/teams`, {
43
+ params: {
44
+ include_member_count: true,
45
+ include_project_count: true,
46
+ include_top_members: true,
47
+ include_secret_teams: params.include_secret_teams ?? false,
48
+ },
49
+ });
50
+ const teams = res.data?.meta || res.data;
51
+ return (Array.isArray(teams) ? teams : []).map((t) => ({
52
+ id: String(t.id),
53
+ name: t.name,
54
+ member_count: t.member_count ?? null,
55
+ project_count: t.project_count ?? null,
56
+ access_level: t.access_level ?? null,
57
+ }));
58
+ }
59
+ export async function seatUsage(config, params) {
60
+ const orgId = requireOrgId(config, params.org_id);
61
+ const reqParams = {};
62
+ if (params.search_query)
63
+ reqParams.search_query = params.search_query;
64
+ const res = await internalClient(config).get(`/api/orgs/${orgId}/org_users/filter_counts`, { params: reqParams });
65
+ return res.data?.meta || res.data;
66
+ }
67
+ export async function listTeamMembers(config, params) {
68
+ const res = await internalClient(config).get(`/api/teams/${params.team_id}/members`);
69
+ return (res.data?.meta || res.data || []).map((m) => ({
70
+ id: m.id,
71
+ name: m.name,
72
+ email: m.email,
73
+ img_url: m.img_url,
74
+ last_active: m.last_active,
75
+ team_role: m.team_role?.level || null,
76
+ permission: m.team_user?.permission || null,
77
+ seat_type: m.seat_type || null,
78
+ }));
79
+ }
80
+ export async function billingOverview(config, params) {
81
+ const orgId = requireOrgId(config, params.org_id);
82
+ const res = await internalClient(config).get(`/api/orgs/${orgId}/billing_data`);
83
+ const data = res.data?.meta || res.data;
84
+ const { shipping_address, ...billing } = data;
85
+ return billing;
86
+ }
87
+ export async function listInvoices(config, params) {
88
+ const orgId = requireOrgId(config, params.org_id);
89
+ const client = internalClient(config);
90
+ const [openResult, upcomingResult] = await Promise.allSettled([
91
+ client.get(`/api/plans/organization/${orgId}/invoices/open`),
92
+ client.get(`/api/plans/organization/${orgId}/invoices/upcoming`),
93
+ ]);
94
+ const response = {};
95
+ if (openResult.status === 'fulfilled')
96
+ response.open = openResult.value.data;
97
+ else
98
+ response.open_error = 'Failed to fetch open invoices';
99
+ if (upcomingResult.status === 'fulfilled')
100
+ response.upcoming = upcomingResult.value.data;
101
+ else
102
+ response.upcoming_error = 'Failed to fetch upcoming invoices';
103
+ return response;
104
+ }
105
+ export async function orgDomains(config, params) {
106
+ const orgId = requireOrgId(config, params.org_id);
107
+ const client = internalClient(config);
108
+ const [domainsResult, ssoResult] = await Promise.allSettled([
109
+ client.get(`/api/orgs/${orgId}/domains`),
110
+ client.get(`/api/org/${orgId}/org_saml_config`),
111
+ ]);
112
+ const response = {};
113
+ if (domainsResult.status === 'fulfilled')
114
+ response.domains = domainsResult.value.data;
115
+ else
116
+ response.domains_error = 'Failed to fetch domains';
117
+ if (ssoResult.status === 'fulfilled')
118
+ response.sso = ssoResult.value.data;
119
+ else
120
+ response.sso_error = 'SSO config not available';
121
+ return response;
122
+ }
123
+ export async function aiCreditUsage(config, params) {
124
+ const res = await internalClient(config).get(`/api/plans/${params.plan_id}/ai_credits/plan_usage_summary`);
125
+ return res.data;
126
+ }
127
+ export async function exportMembers(config, params) {
128
+ const orgId = requireOrgId(config, params.org_id);
129
+ await internalClient(config).post(`/api/orgs/${orgId}/export_members`);
130
+ return 'CSV export queued. It will be emailed to the org admin.';
131
+ }
132
+ export async function listOrgMembers(config, params) {
133
+ const orgId = requireOrgId(config, params.org_id);
134
+ const reqParams = {};
135
+ if (params.search_query)
136
+ reqParams.search_query = params.search_query;
137
+ const res = await internalClient(config).get(`/api/v2/orgs/${orgId}/org_users`, { params: reqParams });
138
+ const users = res.data?.meta?.users || res.data?.meta || res.data || [];
139
+ return (Array.isArray(users) ? users : []).map((m) => ({
140
+ org_user_id: String(m.id),
141
+ user_id: m.user_id,
142
+ email: m.user?.email,
143
+ name: m.user?.handle,
144
+ permission: m.permission,
145
+ seat_type: m.active_seat_type?.key || null,
146
+ last_active: m.last_seen || null,
147
+ }));
148
+ }
149
+ export async function contractRates(config, params) {
150
+ const orgId = requireOrgId(config, params.org_id);
151
+ const res = await internalClient(config).get(`/api/pricing/contract_rates`, { params: { plan_parent_id: orgId, plan_type: 'organization' } });
152
+ const seatProducts = new Set(['expert', 'developer', 'collaborator']);
153
+ const prices = res.data?.meta?.product_prices || [];
154
+ return prices
155
+ .filter((r) => seatProducts.has(r.billable_product_key))
156
+ .map((r) => ({
157
+ product: r.billable_product_key,
158
+ monthly_cents: r.amount,
159
+ monthly_dollars: (r.amount / 100).toFixed(2),
160
+ }));
161
+ }
162
+ export async function changeSeat(config, params) {
163
+ const orgId = requireOrgId(config, params.org_id);
164
+ const res = await internalClient(config).get(`/api/v2/orgs/${orgId}/org_users`, {
165
+ params: params.user_id.includes('@') ? { search_query: params.user_id } : {},
166
+ });
167
+ const users = res.data?.meta?.users || res.data?.meta || res.data || [];
168
+ const members = Array.isArray(users) ? users : [];
169
+ const member = members.find((m) => params.user_id.includes('@')
170
+ ? m.user?.email === params.user_id
171
+ : String(m.user_id) === String(params.user_id));
172
+ if (!member)
173
+ throw new Error(`User not found: ${params.user_id}`);
174
+ if (String(member.user_id) === String(config.userId)) {
175
+ throw new Error('Cannot change your own seat type. Use the Figma admin panel.');
176
+ }
177
+ const currentKey = member.active_seat_type?.key || null;
178
+ const currentType = currentKey ? (SEAT_KEY_TO_TYPE[currentKey] || 'view') : 'view';
179
+ if (currentType === params.seat_type) {
180
+ return `Already on ${SEAT_LABELS[params.seat_type]} seat. No change needed.`;
181
+ }
182
+ const isUpgrade = (SEAT_HIERARCHY[params.seat_type] ?? 0) > (SEAT_HIERARCHY[currentType] ?? 0);
183
+ if (isUpgrade && !params.confirm) {
184
+ throw new Error(`Upgrading from ${SEAT_LABELS[currentType]} to ${SEAT_LABELS[params.seat_type]} will increase billing. ` +
185
+ `Set confirm: true to authorize.`);
186
+ }
187
+ await internalClient(config).put(`/api/orgs/${orgId}/org_users`, {
188
+ org_user_ids: [String(member.id)],
189
+ paid_statuses: PAID_STATUSES[params.seat_type],
190
+ entry_point: 'members_tab',
191
+ seat_increase_authorized: 'true',
192
+ seat_swap_intended: 'false',
193
+ latest_ou_update: member.updated_at,
194
+ showing_billing_groups: 'true',
195
+ }, {
196
+ 'axios-retry': { retries: 0 },
197
+ });
198
+ return {
199
+ user: member.user?.handle || member.user?.email,
200
+ email: member.user?.email,
201
+ old_seat: SEAT_LABELS[currentType],
202
+ new_seat: SEAT_LABELS[params.seat_type],
203
+ };
204
+ }
205
+ //# sourceMappingURL=org.js.map
@@ -0,0 +1,59 @@
1
+ import type { AuthConfig } from '../auth/client.js';
2
+ export declare const LEVEL_MAP: Record<string, number>;
3
+ export declare const LEVEL_NAMES: Record<number, string>;
4
+ export declare function levelName(level: number): string;
5
+ export declare function getRoles(config: AuthConfig, resourceType: string, resourceId: string): Promise<any[]>;
6
+ export interface PermissionUser {
7
+ role_id: string;
8
+ user_id: string | undefined;
9
+ handle: string | undefined;
10
+ email: string | undefined;
11
+ role: string;
12
+ level: number;
13
+ pending: boolean;
14
+ }
15
+ export declare function getPermissions(config: AuthConfig, params: {
16
+ resource_type: string;
17
+ resource_id: string;
18
+ }): Promise<PermissionUser[]>;
19
+ export declare function setPermissions(config: AuthConfig, params: {
20
+ resource_type: string;
21
+ resource_id: string;
22
+ user_id: string;
23
+ role: string;
24
+ }): Promise<string>;
25
+ export interface ShareResult {
26
+ email: string;
27
+ role: string;
28
+ resource_type: string;
29
+ resource_id: string;
30
+ role_id?: string;
31
+ }
32
+ export declare function share(config: AuthConfig, params: {
33
+ resource_type: string;
34
+ resource_id: string;
35
+ email: string;
36
+ role?: string;
37
+ }): Promise<ShareResult>;
38
+ export declare function revokeAccess(config: AuthConfig, params: {
39
+ resource_type: string;
40
+ resource_id: string;
41
+ user_id: string;
42
+ }): Promise<string>;
43
+ export interface RoleRequest {
44
+ notification_id: string;
45
+ email: string | undefined;
46
+ action: string | undefined;
47
+ file_name: string | undefined;
48
+ pending: boolean;
49
+ is_unread: boolean;
50
+ created_at: string | undefined;
51
+ }
52
+ export declare function listRoleRequests(config: AuthConfig): Promise<RoleRequest[]>;
53
+ export declare function approveRoleRequest(config: AuthConfig, params: {
54
+ notification_id: string;
55
+ }): Promise<string>;
56
+ export declare function denyRoleRequest(config: AuthConfig, params: {
57
+ notification_id: string;
58
+ }): Promise<string>;
59
+ //# sourceMappingURL=permissions.d.ts.map
@@ -0,0 +1,112 @@
1
+ import { internalClient } from '../clients/internal-api.js';
2
+ export const LEVEL_MAP = { owner: 999, editor: 300, viewer: 100 };
3
+ export const LEVEL_NAMES = { 999: 'owner', 300: 'editor', 100: 'viewer' };
4
+ export function levelName(level) {
5
+ return LEVEL_NAMES[level] || `level:${level}`;
6
+ }
7
+ export async function getRoles(config, resourceType, resourceId) {
8
+ const res = await internalClient(config).get(`/api/roles/${resourceType}/${resourceId}`);
9
+ const meta = res.data?.meta;
10
+ return Array.isArray(meta) ? meta : [];
11
+ }
12
+ export async function getPermissions(config, params) {
13
+ const roles = await getRoles(config, params.resource_type, params.resource_id);
14
+ return roles.map((r) => ({
15
+ role_id: String(r.id),
16
+ user_id: r.user_id ? String(r.user_id) : undefined,
17
+ handle: r.user?.handle,
18
+ email: r.user?.email || r.pending_email,
19
+ role: levelName(r.level),
20
+ level: r.level,
21
+ pending: !!r.pending_email,
22
+ }));
23
+ }
24
+ export async function setPermissions(config, params) {
25
+ const roles = await getRoles(config, params.resource_type, params.resource_id);
26
+ const target = roles.find((r) => String(r.user_id) === params.user_id);
27
+ if (!target) {
28
+ throw new Error(`User ${params.user_id} has no role on this ${params.resource_type}. Use share to invite them first.`);
29
+ }
30
+ const level = LEVEL_MAP[params.role];
31
+ await internalClient(config).put(`/api/roles/${target.id}`, { level });
32
+ return `Set ${params.role} (level ${level}) for user ${params.user_id} on ${params.resource_type} ${params.resource_id}`;
33
+ }
34
+ export async function share(config, params) {
35
+ const role = params.role || 'viewer';
36
+ const level = LEVEL_MAP[role];
37
+ const res = await internalClient(config).post('/api/invites', {
38
+ resource_type: params.resource_type,
39
+ resource_id_or_key: params.resource_id,
40
+ emails: [params.email],
41
+ level,
42
+ });
43
+ const invites = res.data?.meta?.invites || [];
44
+ const roleId = invites[0]?.id;
45
+ return {
46
+ email: params.email,
47
+ role,
48
+ resource_type: params.resource_type,
49
+ resource_id: params.resource_id,
50
+ role_id: roleId ? String(roleId) : undefined,
51
+ };
52
+ }
53
+ export async function revokeAccess(config, params) {
54
+ const roles = await getRoles(config, params.resource_type, params.resource_id);
55
+ const target = roles.find((r) => String(r.user_id) === params.user_id);
56
+ if (!target) {
57
+ throw new Error(`User ${params.user_id} has no role on this ${params.resource_type}.`);
58
+ }
59
+ await internalClient(config).delete(`/api/roles/${target.id}`);
60
+ return `Revoked access for user ${params.user_id} on ${params.resource_type} ${params.resource_id}`;
61
+ }
62
+ export async function listRoleRequests(config) {
63
+ const res = await internalClient(config).get('/api/user_notifications/server_driven/plan', {
64
+ params: { current_plan_id: '-1', app_version: '1', client_type: 'web' },
65
+ });
66
+ const notifications = res.data?.meta || [];
67
+ return (Array.isArray(notifications) ? notifications : [])
68
+ .filter((n) => n.notification_type === 'FileRoleRequestCreatedNotif')
69
+ .map((n) => {
70
+ const title = n.preferred_attachments?.[0]?.body?.title || [];
71
+ const subtitle = n.preferred_attachments?.[0]?.body?.subtitle || [];
72
+ const email = title[0]?.html_text?.replace(/<[^>]+>/g, '') || undefined;
73
+ const action = subtitle[0]?.html_text || undefined;
74
+ const fileName = subtitle[2]?.html_text || undefined;
75
+ const hasActions = !!n.preferred_attachments?.[0]?.actions;
76
+ return {
77
+ notification_id: n.notification_id,
78
+ email,
79
+ action,
80
+ file_name: fileName,
81
+ pending: hasActions,
82
+ is_unread: n.is_unread,
83
+ created_at: n.preferred_attachments?.[0]?.body?.created_at,
84
+ };
85
+ });
86
+ }
87
+ export async function approveRoleRequest(config, params) {
88
+ const res = await internalClient(config).put('/api/user_notifications/accept', {
89
+ id: params.notification_id,
90
+ medium: 'web',
91
+ appVersion: '1',
92
+ clientType: 'web',
93
+ });
94
+ const notif = res.data?.meta?.notification;
95
+ const locals = notif?.locals || {};
96
+ let msg = `Approved access request ${params.notification_id}`;
97
+ if (locals.file_name)
98
+ msg += ` for ${locals.file_name}`;
99
+ if (locals.user_id)
100
+ msg += ` (user ${locals.user_id})`;
101
+ return msg;
102
+ }
103
+ export async function denyRoleRequest(config, params) {
104
+ await internalClient(config).put('/api/user_notifications/reject', {
105
+ id: params.notification_id,
106
+ medium: 'web',
107
+ appVersion: '1',
108
+ clientType: 'web',
109
+ });
110
+ return `Declined access request ${params.notification_id}`;
111
+ }
112
+ //# sourceMappingURL=permissions.js.map
@@ -0,0 +1,29 @@
1
+ import type { AuthConfig } from '../auth/client.js';
2
+ export interface CreatedProject {
3
+ id: string;
4
+ name: string;
5
+ team_id: string;
6
+ }
7
+ export declare function createProject(config: AuthConfig, params: {
8
+ team_id: string;
9
+ name: string;
10
+ }): Promise<CreatedProject>;
11
+ export declare function renameProject(config: AuthConfig, params: {
12
+ project_id: string;
13
+ name: string;
14
+ }): Promise<void>;
15
+ export declare function moveProject(config: AuthConfig, params: {
16
+ project_id: string;
17
+ destination_team_id: string;
18
+ }): Promise<void>;
19
+ export declare function trashProject(config: AuthConfig, params: {
20
+ project_id: string;
21
+ }): Promise<void>;
22
+ export declare function restoreProject(config: AuthConfig, params: {
23
+ project_id: string;
24
+ }): Promise<void>;
25
+ export declare function setProjectDescription(config: AuthConfig, params: {
26
+ project_id: string;
27
+ description: string;
28
+ }): Promise<void>;
29
+ //# sourceMappingURL=projects.d.ts.map
@@ -0,0 +1,40 @@
1
+ import { internalClient } from '../clients/internal-api.js';
2
+ export async function createProject(config, params) {
3
+ const res = await internalClient(config).post('/api/folders', {
4
+ team_id: params.team_id,
5
+ path: params.name,
6
+ sharing_audience_control: 'org_view',
7
+ team_access: 'team_edit',
8
+ });
9
+ const meta = res.data?.meta;
10
+ const p = Array.isArray(meta) ? meta[0] : (meta?.folder || meta || res.data);
11
+ return {
12
+ id: String(p.id),
13
+ name: p.name || p.path || params.name,
14
+ team_id: params.team_id,
15
+ };
16
+ }
17
+ export async function renameProject(config, params) {
18
+ await internalClient(config).put('/api/folders/rename', {
19
+ folder_id: params.project_id,
20
+ name: params.name,
21
+ });
22
+ }
23
+ export async function moveProject(config, params) {
24
+ await internalClient(config).put('/api/folders/move', {
25
+ folder_id: params.project_id,
26
+ team_id: params.destination_team_id,
27
+ });
28
+ }
29
+ export async function trashProject(config, params) {
30
+ await internalClient(config).put(`/api/folders/trash/${params.project_id}`);
31
+ }
32
+ export async function restoreProject(config, params) {
33
+ await internalClient(config).put(`/api/folders/restore/${params.project_id}`);
34
+ }
35
+ export async function setProjectDescription(config, params) {
36
+ await internalClient(config).put(`/api/folders/${params.project_id}/description`, {
37
+ description: params.description,
38
+ });
39
+ }
40
+ //# sourceMappingURL=projects.js.map
@@ -0,0 +1,12 @@
1
+ import type { AuthConfig } from '../auth/client.js';
2
+ export declare function getFile(config: AuthConfig, params: {
3
+ file_key: string;
4
+ depth?: number;
5
+ node_id?: string;
6
+ }): Promise<any>;
7
+ export declare function getNodes(config: AuthConfig, params: {
8
+ file_key: string;
9
+ node_ids: string[];
10
+ depth?: number;
11
+ }): Promise<any>;
12
+ //# sourceMappingURL=reading.d.ts.map
@@ -0,0 +1,20 @@
1
+ import { publicClient } from '../clients/public-api.js';
2
+ export async function getFile(config, params) {
3
+ const queryParams = {};
4
+ if (params.depth !== undefined)
5
+ queryParams.depth = String(params.depth);
6
+ if (params.node_id)
7
+ queryParams['node-id'] = params.node_id;
8
+ const res = await publicClient(config).get(`/v1/files/${params.file_key}`, { params: queryParams });
9
+ return res.data;
10
+ }
11
+ export async function getNodes(config, params) {
12
+ const queryParams = {
13
+ ids: params.node_ids.join(','),
14
+ };
15
+ if (params.depth !== undefined)
16
+ queryParams.depth = String(params.depth);
17
+ const res = await publicClient(config).get(`/v1/files/${params.file_key}/nodes`, { params: queryParams });
18
+ return res.data;
19
+ }
20
+ //# sourceMappingURL=reading.js.map
@@ -0,0 +1,17 @@
1
+ import type { AuthConfig } from '../auth/client.js';
2
+ export interface CreatedTeam {
3
+ id: string;
4
+ name: string;
5
+ }
6
+ export declare function createTeam(config: AuthConfig, params: {
7
+ name: string;
8
+ org_id?: string;
9
+ }): Promise<CreatedTeam>;
10
+ export declare function renameTeam(config: AuthConfig, params: {
11
+ team_id: string;
12
+ name: string;
13
+ }): Promise<string>;
14
+ export declare function deleteTeam(config: AuthConfig, params: {
15
+ team_id: string;
16
+ }): Promise<string>;
17
+ //# sourceMappingURL=teams.d.ts.map
@@ -0,0 +1,17 @@
1
+ import { internalClient } from '../clients/internal-api.js';
2
+ import { requireOrgId } from '../tools/register.js';
3
+ export async function createTeam(config, params) {
4
+ const orgId = requireOrgId(config, params.org_id);
5
+ const res = await internalClient(config).post('/api/teams/create', { team_name: params.name, org_id: orgId, sharing_audience_control: 'org_view' });
6
+ const team = res.data?.meta?.team || res.data?.meta || res.data;
7
+ return { id: String(team.id), name: team.name };
8
+ }
9
+ export async function renameTeam(config, params) {
10
+ await internalClient(config).put(`/api/teams/${params.team_id}`, { name: params.name });
11
+ return `Team ${params.team_id} renamed to "${params.name}".`;
12
+ }
13
+ export async function deleteTeam(config, params) {
14
+ await internalClient(config).delete(`/api/teams/${params.team_id}`);
15
+ return `Team ${params.team_id} deleted.`;
16
+ }
17
+ //# sourceMappingURL=teams.js.map
@@ -0,0 +1,17 @@
1
+ import type { AuthConfig } from '../auth/client.js';
2
+ export declare const ENTERPRISE_ERROR = "Variables API requires Figma Enterprise plan. The file_variables:read/write scopes are not available on standard plans.";
3
+ export declare function isEnterpriseScopeError(e: any): boolean;
4
+ export declare function listLocalVariables(config: AuthConfig, params: {
5
+ file_key: string;
6
+ }): Promise<Record<string, any>>;
7
+ export declare function listPublishedVariables(config: AuthConfig, params: {
8
+ file_key: string;
9
+ }): Promise<Record<string, any>>;
10
+ export declare function updateVariables(config: AuthConfig, params: {
11
+ file_key: string;
12
+ variable_collections?: Record<string, any>[];
13
+ variable_modes?: Record<string, any>[];
14
+ variables?: Record<string, any>[];
15
+ variable_mode_values?: Record<string, any>[];
16
+ }): Promise<any>;
17
+ //# sourceMappingURL=variables.d.ts.map
@@ -0,0 +1,39 @@
1
+ import { publicClient } from '../clients/public-api.js';
2
+ export const ENTERPRISE_ERROR = 'Variables API requires Figma Enterprise plan. The file_variables:read/write scopes are not available on standard plans.';
3
+ export function isEnterpriseScopeError(e) {
4
+ if (e.response?.status !== 403)
5
+ return false;
6
+ const data = e.response?.data;
7
+ if (typeof data !== 'object' || !data)
8
+ return false;
9
+ const msg = String(data.message || data.error || data.err || '');
10
+ return msg.toLowerCase().includes('scope');
11
+ }
12
+ export async function listLocalVariables(config, params) {
13
+ const res = await publicClient(config).get(`/v1/files/${params.file_key}/variables/local`);
14
+ return res.data?.meta ?? {};
15
+ }
16
+ export async function listPublishedVariables(config, params) {
17
+ const res = await publicClient(config).get(`/v1/files/${params.file_key}/variables/published`);
18
+ return res.data?.meta ?? {};
19
+ }
20
+ export async function updateVariables(config, params) {
21
+ if (!params.variable_collections?.length &&
22
+ !params.variable_modes?.length &&
23
+ !params.variables?.length &&
24
+ !params.variable_mode_values?.length) {
25
+ throw new Error('At least one operation array is required.');
26
+ }
27
+ const body = {};
28
+ if (params.variable_collections)
29
+ body.variableCollections = params.variable_collections;
30
+ if (params.variable_modes)
31
+ body.variableModes = params.variable_modes;
32
+ if (params.variables)
33
+ body.variables = params.variables;
34
+ if (params.variable_mode_values)
35
+ body.variableModeValues = params.variable_mode_values;
36
+ const res = await publicClient(config).post(`/v1/files/${params.file_key}/variables`, body);
37
+ return res.data;
38
+ }
39
+ //# sourceMappingURL=variables.js.map
@@ -0,0 +1,23 @@
1
+ import type { AuthConfig } from '../auth/client.js';
2
+ export interface Version {
3
+ id: string;
4
+ label: string | null;
5
+ description: string | null;
6
+ created_at: string;
7
+ user: string | null;
8
+ }
9
+ export interface CreatedVersion {
10
+ id: string | null;
11
+ label: string;
12
+ description: string | null;
13
+ created_at: string | null;
14
+ }
15
+ export declare function listVersions(config: AuthConfig, params: {
16
+ file_key: string;
17
+ }): Promise<Version[]>;
18
+ export declare function createVersion(config: AuthConfig, params: {
19
+ file_key: string;
20
+ title: string;
21
+ description?: string;
22
+ }): Promise<CreatedVersion>;
23
+ //# sourceMappingURL=versions.d.ts.map
@@ -0,0 +1,27 @@
1
+ import { publicClient } from '../clients/public-api.js';
2
+ import { internalClient } from '../clients/internal-api.js';
3
+ export async function listVersions(config, params) {
4
+ const res = await publicClient(config).get(`/v1/files/${params.file_key}/versions`);
5
+ const versions = res.data?.versions || [];
6
+ return versions.map((v) => ({
7
+ id: v.id,
8
+ label: v.label || null,
9
+ description: v.description || null,
10
+ created_at: v.created_at,
11
+ user: v.user?.handle || v.user?.id || null,
12
+ }));
13
+ }
14
+ export async function createVersion(config, params) {
15
+ const res = await internalClient(config).post(`/api/multiplayer/${params.file_key}/create_savepoint`, {
16
+ label: params.title,
17
+ description: params.description || '',
18
+ });
19
+ const v = res.data?.meta || {};
20
+ return {
21
+ id: v.id || null,
22
+ label: v.label || params.title,
23
+ description: v.description || null,
24
+ created_at: v.created_at || null,
25
+ };
26
+ }
27
+ //# sourceMappingURL=versions.js.map
@@ -0,0 +1,25 @@
1
+ import type { AuthConfig } from '../auth/client.js';
2
+ export type WebhookEventType = 'FILE_UPDATE' | 'FILE_DELETE' | 'FILE_VERSION_UPDATE' | 'LIBRARY_PUBLISH' | 'FILE_COMMENT' | 'PING';
3
+ export type WebhookStatus = 'ACTIVE' | 'PAUSED';
4
+ export declare function listWebhooks(config: AuthConfig, params: {
5
+ team_id: string;
6
+ }): Promise<any[]>;
7
+ export declare function createWebhook(config: AuthConfig, params: {
8
+ team_id: string;
9
+ event_type: WebhookEventType;
10
+ endpoint: string;
11
+ passcode: string;
12
+ description?: string;
13
+ }): Promise<Record<string, any>>;
14
+ export declare function updateWebhook(config: AuthConfig, params: {
15
+ webhook_id: string;
16
+ event_type?: WebhookEventType;
17
+ endpoint?: string;
18
+ passcode?: string;
19
+ description?: string;
20
+ status?: WebhookStatus;
21
+ }): Promise<Record<string, any>>;
22
+ export declare function deleteWebhook(config: AuthConfig, params: {
23
+ webhook_id: string;
24
+ }): Promise<void>;
25
+ //# sourceMappingURL=webhooks.d.ts.map