figmanage 1.0.0 → 1.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.
Files changed (97) 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/components.d.ts +3 -0
  9. package/dist/cli/components.js +82 -0
  10. package/dist/cli/compound-commands.d.ts +14 -0
  11. package/dist/cli/compound-commands.js +291 -0
  12. package/dist/cli/export.d.ts +3 -0
  13. package/dist/cli/export.js +51 -0
  14. package/dist/cli/files.d.ts +3 -0
  15. package/dist/cli/files.js +156 -0
  16. package/dist/cli/helpers.d.ts +7 -0
  17. package/dist/cli/helpers.js +43 -0
  18. package/dist/cli/index.js +65 -89
  19. package/dist/cli/libraries.d.ts +3 -0
  20. package/dist/cli/libraries.js +26 -0
  21. package/dist/cli/navigate.d.ts +3 -0
  22. package/dist/cli/navigate.js +192 -0
  23. package/dist/cli/org.d.ts +3 -0
  24. package/dist/cli/org.js +227 -0
  25. package/dist/cli/permissions.d.ts +3 -0
  26. package/dist/cli/permissions.js +133 -0
  27. package/dist/cli/projects.d.ts +3 -0
  28. package/dist/cli/projects.js +110 -0
  29. package/dist/cli/reading.d.ts +3 -0
  30. package/dist/cli/reading.js +51 -0
  31. package/dist/cli/teams.d.ts +3 -0
  32. package/dist/cli/teams.js +56 -0
  33. package/dist/cli/variables.d.ts +3 -0
  34. package/dist/cli/variables.js +80 -0
  35. package/dist/cli/versions.d.ts +3 -0
  36. package/dist/cli/versions.js +46 -0
  37. package/dist/cli/webhooks.d.ts +3 -0
  38. package/dist/cli/webhooks.js +100 -0
  39. package/dist/cli/whoami.js +3 -2
  40. package/dist/index.js +1 -1
  41. package/dist/operations/analytics.d.ts +10 -0
  42. package/dist/operations/analytics.js +15 -0
  43. package/dist/operations/branching.d.ts +24 -0
  44. package/dist/operations/branching.js +41 -0
  45. package/dist/operations/comments.d.ts +43 -0
  46. package/dist/operations/comments.js +65 -0
  47. package/dist/operations/components.d.ts +24 -0
  48. package/dist/operations/components.js +30 -0
  49. package/dist/operations/compound-manager.d.ts +101 -0
  50. package/dist/operations/compound-manager.js +629 -0
  51. package/dist/operations/compound.d.ts +102 -0
  52. package/dist/operations/compound.js +595 -0
  53. package/dist/operations/export.d.ts +19 -0
  54. package/dist/operations/export.js +27 -0
  55. package/dist/operations/files.d.ts +55 -0
  56. package/dist/operations/files.js +89 -0
  57. package/dist/operations/libraries.d.ts +5 -0
  58. package/dist/operations/libraries.js +10 -0
  59. package/dist/operations/navigate.d.ts +99 -0
  60. package/dist/operations/navigate.js +266 -0
  61. package/dist/operations/org.d.ts +95 -0
  62. package/dist/operations/org.js +205 -0
  63. package/dist/operations/permissions.d.ts +59 -0
  64. package/dist/operations/permissions.js +112 -0
  65. package/dist/operations/projects.d.ts +29 -0
  66. package/dist/operations/projects.js +40 -0
  67. package/dist/operations/reading.d.ts +12 -0
  68. package/dist/operations/reading.js +20 -0
  69. package/dist/operations/teams.d.ts +17 -0
  70. package/dist/operations/teams.js +17 -0
  71. package/dist/operations/variables.d.ts +17 -0
  72. package/dist/operations/variables.js +39 -0
  73. package/dist/operations/versions.d.ts +23 -0
  74. package/dist/operations/versions.js +27 -0
  75. package/dist/operations/webhooks.d.ts +25 -0
  76. package/dist/operations/webhooks.js +38 -0
  77. package/dist/tools/analytics.js +6 -16
  78. package/dist/tools/branching.js +7 -36
  79. package/dist/tools/comments.js +9 -56
  80. package/dist/tools/components.js +7 -19
  81. package/dist/tools/compound-manager.js +21 -644
  82. package/dist/tools/compound.js +32 -566
  83. package/dist/tools/export.js +4 -23
  84. package/dist/tools/files.js +21 -68
  85. package/dist/tools/libraries.js +4 -11
  86. package/dist/tools/navigate.js +23 -246
  87. package/dist/tools/org.js +29 -245
  88. package/dist/tools/permissions.js +18 -97
  89. package/dist/tools/projects.js +8 -27
  90. package/dist/tools/reading.js +5 -15
  91. package/dist/tools/teams.js +8 -16
  92. package/dist/tools/variables.js +13 -30
  93. package/dist/tools/versions.js +6 -24
  94. package/dist/tools/webhooks.js +7 -24
  95. package/package.json +1 -1
  96. package/dist/cli/commands.d.ts +0 -47
  97. package/dist/cli/commands.js +0 -1204
@@ -0,0 +1,19 @@
1
+ import type { AuthConfig } from '../auth/client.js';
2
+ export interface ExportedImage {
3
+ node_id: string;
4
+ url: string | null;
5
+ }
6
+ export interface ImageFill {
7
+ image_ref: string;
8
+ url: string;
9
+ }
10
+ export declare function exportNodes(config: AuthConfig, params: {
11
+ file_key: string;
12
+ node_ids: string[];
13
+ format?: string;
14
+ scale?: number;
15
+ }): Promise<ExportedImage[]>;
16
+ export declare function getImageFills(config: AuthConfig, params: {
17
+ file_key: string;
18
+ }): Promise<ImageFill[]>;
19
+ //# sourceMappingURL=export.d.ts.map
@@ -0,0 +1,27 @@
1
+ import { publicClient } from '../clients/public-api.js';
2
+ export async function exportNodes(config, params) {
3
+ const queryParams = {
4
+ ids: params.node_ids.join(','),
5
+ format: params.format || 'png',
6
+ };
7
+ if (params.scale)
8
+ queryParams.scale = String(Math.min(Math.max(params.scale, 0.01), 4));
9
+ const res = await publicClient(config).get(`/v1/images/${params.file_key}`, { params: queryParams });
10
+ const images = res.data?.images || {};
11
+ const err = res.data?.err;
12
+ if (err)
13
+ throw new Error(`Export error: ${err}`);
14
+ return Object.entries(images).map(([nodeId, url]) => ({
15
+ node_id: nodeId,
16
+ url: url,
17
+ }));
18
+ }
19
+ export async function getImageFills(config, params) {
20
+ const res = await publicClient(config).get(`/v1/files/${params.file_key}/images`);
21
+ const images = res.data?.meta?.images || res.data?.images || {};
22
+ return Object.entries(images).map(([ref, url]) => ({
23
+ image_ref: ref,
24
+ url: url,
25
+ }));
26
+ }
27
+ //# sourceMappingURL=export.js.map
@@ -0,0 +1,55 @@
1
+ import type { AuthConfig } from '../auth/client.js';
2
+ export interface CreatedFile {
3
+ key: string;
4
+ name: string;
5
+ editor_type: string;
6
+ url: string;
7
+ }
8
+ export interface DuplicatedFile {
9
+ key: string;
10
+ name: string;
11
+ url: string;
12
+ }
13
+ export interface MoveResult {
14
+ succeeded: number;
15
+ failed: number;
16
+ errors?: Record<string, unknown>;
17
+ }
18
+ export declare function createFile(config: AuthConfig, params: {
19
+ project_id: string;
20
+ editor_type?: string;
21
+ org_id?: string;
22
+ }): Promise<CreatedFile>;
23
+ export declare function renameFile(config: AuthConfig, params: {
24
+ file_key: string;
25
+ name: string;
26
+ }): Promise<void>;
27
+ export declare function moveFiles(config: AuthConfig, params: {
28
+ file_keys: string[];
29
+ destination_project_id: string;
30
+ }): Promise<MoveResult>;
31
+ export declare function duplicateFile(config: AuthConfig, params: {
32
+ file_key: string;
33
+ project_id?: string;
34
+ }): Promise<DuplicatedFile>;
35
+ export declare function trashFiles(config: AuthConfig, params: {
36
+ file_keys: string[];
37
+ }): Promise<{
38
+ succeeded: number;
39
+ }>;
40
+ export declare function restoreFiles(config: AuthConfig, params: {
41
+ file_keys: string[];
42
+ }): Promise<MoveResult>;
43
+ export declare function favoriteFile(config: AuthConfig, params: {
44
+ file_key: string;
45
+ favorited?: boolean;
46
+ }): Promise<{
47
+ favorited: boolean;
48
+ }>;
49
+ export declare function setLinkAccess(config: AuthConfig, params: {
50
+ file_key: string;
51
+ link_access?: string;
52
+ }): Promise<{
53
+ link_access: string;
54
+ }>;
55
+ //# sourceMappingURL=files.d.ts.map
@@ -0,0 +1,89 @@
1
+ import { internalClient } from '../clients/internal-api.js';
2
+ import { resolveOrgId } from '../tools/register.js';
3
+ export async function createFile(config, params) {
4
+ const res = await internalClient(config).post('/api/files/create', {
5
+ folder_id: params.project_id,
6
+ org_id: resolveOrgId(config, params.org_id),
7
+ editor_type: params.editor_type || 'design',
8
+ });
9
+ const f = res.data?.meta?.fig_file || res.data?.meta || res.data;
10
+ return {
11
+ key: f.key,
12
+ name: f.name,
13
+ editor_type: f.editor_type,
14
+ url: `https://www.figma.com/design/${f.key}`,
15
+ };
16
+ }
17
+ export async function renameFile(config, params) {
18
+ await internalClient(config).put(`/api/files/${params.file_key}`, {
19
+ key: params.file_key,
20
+ name: params.name,
21
+ });
22
+ }
23
+ export async function moveFiles(config, params) {
24
+ const files = params.file_keys.map(key => ({
25
+ key,
26
+ folder_id: params.destination_project_id,
27
+ is_multi_move: params.file_keys.length > 1,
28
+ restore_files: false,
29
+ }));
30
+ const res = await internalClient(config).put('/api/files_batch', { files });
31
+ const data = res.data?.meta || res.data;
32
+ const succeeded = Object.keys(data.success || {}).length;
33
+ const failed = Object.keys(data.errors || {}).length;
34
+ return {
35
+ succeeded,
36
+ failed,
37
+ errors: failed > 0 ? data.errors : undefined,
38
+ };
39
+ }
40
+ export async function duplicateFile(config, params) {
41
+ const res = await internalClient(config).post(`/api/multiplayer/${params.file_key}/copy`, null, {
42
+ headers: { 'Content-Length': '0' },
43
+ params: params.project_id ? { folder_id: params.project_id } : undefined,
44
+ });
45
+ const f = res.data?.meta?.fig_file || res.data?.meta || res.data;
46
+ return {
47
+ key: f.key,
48
+ name: f.name,
49
+ url: `https://www.figma.com/design/${f.key}`,
50
+ };
51
+ }
52
+ export async function trashFiles(config, params) {
53
+ const files = params.file_keys.map(key => ({ key }));
54
+ const res = await internalClient(config).delete('/api/files_batch', {
55
+ data: { files, trashed: true },
56
+ });
57
+ const data = res.data?.meta || res.data;
58
+ const succeeded = Object.keys(data.success || {}).length;
59
+ return { succeeded };
60
+ }
61
+ export async function restoreFiles(config, params) {
62
+ const files = params.file_keys.map(key => ({ key }));
63
+ const res = await internalClient(config).post('/api/files_batch/restore', { files });
64
+ const data = res.data?.meta || res.data;
65
+ const succeeded = Object.keys(data?.success || {}).length || params.file_keys.length;
66
+ const failed = Object.keys(data?.errors || {}).length;
67
+ return {
68
+ succeeded,
69
+ failed,
70
+ errors: failed > 0 ? data.errors : undefined,
71
+ };
72
+ }
73
+ export async function favoriteFile(config, params) {
74
+ const isFavorited = params.favorited !== false;
75
+ await internalClient(config).put('/api/favorited_resources', {
76
+ resource_type: 'file',
77
+ resource_id_or_key: params.file_key,
78
+ is_favorited: isFavorited,
79
+ });
80
+ return { favorited: isFavorited };
81
+ }
82
+ export async function setLinkAccess(config, params) {
83
+ const res = await internalClient(config).put(`/api/files/${params.file_key}`, {
84
+ link_access: params.link_access || 'inherit',
85
+ });
86
+ const newAccess = res.data?.meta?.link_access || params.link_access || 'inherit';
87
+ return { link_access: newAccess };
88
+ }
89
+ //# sourceMappingURL=files.js.map
@@ -0,0 +1,5 @@
1
+ import type { AuthConfig } from '../auth/client.js';
2
+ export declare function listOrgLibraries(config: AuthConfig, params: {
3
+ org_id?: string;
4
+ }): Promise<any>;
5
+ //# sourceMappingURL=libraries.d.ts.map
@@ -0,0 +1,10 @@
1
+ import { internalClient } from '../clients/internal-api.js';
2
+ import { requireOrgId } from '../tools/register.js';
3
+ export async function listOrgLibraries(config, params) {
4
+ const orgId = requireOrgId(config, params.org_id);
5
+ const res = await internalClient(config).get('/api/design_systems/libraries', {
6
+ params: { org_id: orgId, include_sharing_group_info: true },
7
+ });
8
+ return res.data;
9
+ }
10
+ //# sourceMappingURL=libraries.js.map
@@ -0,0 +1,99 @@
1
+ import type { AuthConfig } from '../auth/client.js';
2
+ import type { AuthStatus } from '../types/figma.js';
3
+ export interface AuthCheckResult {
4
+ status: AuthStatus;
5
+ formatted: string;
6
+ }
7
+ export interface OrgListEntry {
8
+ id: string;
9
+ name: string;
10
+ active: boolean;
11
+ }
12
+ export interface SwitchOrgResult {
13
+ previous: string;
14
+ current: {
15
+ id: string;
16
+ name: string;
17
+ };
18
+ }
19
+ export interface Team {
20
+ id: string;
21
+ name: string;
22
+ }
23
+ export interface Project {
24
+ id: string;
25
+ name: string;
26
+ }
27
+ export interface FileEntry {
28
+ key: string;
29
+ name: string;
30
+ last_modified?: string;
31
+ thumbnail_url?: string;
32
+ editor_type?: string;
33
+ }
34
+ export interface FileListResult {
35
+ files: FileEntry[];
36
+ pagination?: {
37
+ has_more: boolean;
38
+ hint: string;
39
+ };
40
+ }
41
+ export interface RecentFile {
42
+ key: string;
43
+ name: string;
44
+ team_id?: string;
45
+ folder_id?: string;
46
+ editor_type?: string;
47
+ last_touched?: string;
48
+ url: string;
49
+ }
50
+ export interface SearchResult {
51
+ key: string;
52
+ name: string;
53
+ editor_type?: string;
54
+ team_id?: string;
55
+ folder_id?: string;
56
+ last_modified?: string;
57
+ url: string;
58
+ }
59
+ export interface FileInfo {
60
+ key: string;
61
+ name: string;
62
+ last_modified?: string;
63
+ updated_at?: string;
64
+ editor_type?: string;
65
+ folder_id?: string;
66
+ team_id?: string;
67
+ link_access?: string;
68
+ url: string;
69
+ }
70
+ export interface Favorite {
71
+ key: string;
72
+ name: string;
73
+ type?: string;
74
+ }
75
+ export declare function checkAuthStatus(config: AuthConfig): Promise<AuthCheckResult>;
76
+ export declare function listOrgs(config: AuthConfig): Promise<OrgListEntry[]>;
77
+ export declare function switchOrg(config: AuthConfig, params: {
78
+ org: string;
79
+ }): Promise<SwitchOrgResult>;
80
+ export declare function listTeams(config: AuthConfig): Promise<Team[]>;
81
+ export declare function listProjects(config: AuthConfig, params: {
82
+ team_id: string;
83
+ }): Promise<Project[]>;
84
+ export declare function listFiles(config: AuthConfig, params: {
85
+ project_id: string;
86
+ page_size?: number;
87
+ page_token?: string;
88
+ }): Promise<FileListResult>;
89
+ export declare function listRecentFiles(config: AuthConfig): Promise<RecentFile[]>;
90
+ export declare function search(config: AuthConfig, params: {
91
+ query: string;
92
+ sort?: string;
93
+ org_id?: string;
94
+ }): Promise<SearchResult[]>;
95
+ export declare function getFileInfo(config: AuthConfig, params: {
96
+ file_key: string;
97
+ }): Promise<FileInfo>;
98
+ export declare function listFavorites(config: AuthConfig): Promise<Favorite[]>;
99
+ //# sourceMappingURL=navigate.d.ts.map
@@ -0,0 +1,266 @@
1
+ import { hasCookie, hasPat } from '../auth/client.js';
2
+ import { publicClient } from '../clients/public-api.js';
3
+ import { internalClient } from '../clients/internal-api.js';
4
+ import { checkAuth, formatAuthStatus } from '../auth/health.js';
5
+ function requireOrgId(config, explicit) {
6
+ const id = explicit || config.orgId;
7
+ if (!id)
8
+ throw new Error('Org context required. Run list_orgs to see available workspaces, or set FIGMA_ORG_ID.');
9
+ if (!/^[\w.:-]+$/.test(id))
10
+ throw new Error('Invalid org ID format');
11
+ return id;
12
+ }
13
+ export async function checkAuthStatus(config) {
14
+ const status = await checkAuth(config);
15
+ const formatted = formatAuthStatus(status, config);
16
+ return { status, formatted };
17
+ }
18
+ export async function listOrgs(config) {
19
+ const api = internalClient(config);
20
+ const res = await api.get('/api/user/state');
21
+ let orgs = (res.data?.meta?.orgs || [])
22
+ .filter((o) => o && o.id)
23
+ .map((o) => ({ id: String(o.id), name: o.name || String(o.id) }));
24
+ // Fallback: meta.orgs is empty for non-admin users.
25
+ // Extract unique org_ids from meta.roles instead.
26
+ if (orgs.length === 0) {
27
+ const roles = res.data?.meta?.roles || [];
28
+ const orgIds = [...new Set(roles
29
+ .map((r) => r.org_id)
30
+ .filter((id) => id != null)
31
+ .map(String))];
32
+ // Also include config.orgId if not already covered
33
+ if (config.orgId && !orgIds.includes(config.orgId)) {
34
+ orgIds.push(config.orgId);
35
+ }
36
+ // Resolve names via domain lookup
37
+ orgs = await Promise.all(orgIds.map(async (id) => {
38
+ let name = id;
39
+ try {
40
+ const domRes = await api.get(`/api/orgs/${id}/domains`);
41
+ const domains = domRes.data?.meta || [];
42
+ if (Array.isArray(domains) && domains.length > 0) {
43
+ name = domains[0].domain || id;
44
+ }
45
+ }
46
+ catch { /* domain lookup optional */ }
47
+ return { id, name };
48
+ }));
49
+ }
50
+ // Merge with any existing registry entries (preserves names from setup)
51
+ if (config.orgs && config.orgs.length > 0) {
52
+ for (const existing of config.orgs) {
53
+ if (!orgs.find(o => o.id === existing.id)) {
54
+ orgs.push(existing);
55
+ }
56
+ else {
57
+ // Prefer stored name over ID-only fallback
58
+ const entry = orgs.find(o => o.id === existing.id);
59
+ if (entry.name === entry.id && existing.name !== existing.id) {
60
+ entry.name = existing.name;
61
+ }
62
+ }
63
+ }
64
+ }
65
+ if (orgs.length === 0)
66
+ return [];
67
+ return orgs.map(o => ({
68
+ id: o.id,
69
+ name: o.name,
70
+ active: o.id === config.orgId,
71
+ }));
72
+ }
73
+ export async function switchOrg(config, params) {
74
+ // Ensure we have an org list
75
+ if (!config.orgs || config.orgs.length === 0) {
76
+ const res = await internalClient(config).get('/api/user/state');
77
+ const orgs = (res.data?.meta?.orgs || []).map((o) => ({
78
+ id: String(o.id),
79
+ name: o.name,
80
+ }));
81
+ if (orgs.length > 0)
82
+ config.orgs = orgs;
83
+ }
84
+ if (!config.orgs || config.orgs.length === 0) {
85
+ throw new Error('No workspaces found. You may be on a free/starter plan.');
86
+ }
87
+ // Try exact ID match first
88
+ let match = config.orgs.find(o => o.id === params.org);
89
+ // Then case-insensitive substring match on name
90
+ if (!match) {
91
+ const lower = params.org.toLowerCase();
92
+ const matches = config.orgs.filter(o => o.name.toLowerCase().includes(lower));
93
+ if (matches.length === 1) {
94
+ match = matches[0];
95
+ }
96
+ else if (matches.length > 1) {
97
+ const names = matches.map(o => `${o.name} (${o.id})`).join(', ');
98
+ throw new Error(`Ambiguous: "${params.org}" matches multiple workspaces: ${names}. Be more specific or use the org ID.`);
99
+ }
100
+ }
101
+ if (!match) {
102
+ const available = config.orgs.map(o => `${o.name} (${o.id})`).join(', ');
103
+ throw new Error(`No workspace matching "${params.org}". Available: ${available}`);
104
+ }
105
+ const previousId = config.orgId;
106
+ const previousOrg = config.orgs.find(o => o.id === previousId);
107
+ const previousLabel = previousOrg ? `${previousOrg.name} (${previousId})` : (previousId || 'none');
108
+ return {
109
+ previous: previousLabel,
110
+ current: { id: match.id, name: match.name },
111
+ };
112
+ }
113
+ export async function listTeams(config) {
114
+ if (config.orgId) {
115
+ const res = await internalClient(config).get(`/api/orgs/${config.orgId}/teams`);
116
+ const data = res.data?.meta || res.data;
117
+ return (data.teams || (Array.isArray(data) ? data : [])).map((t) => ({
118
+ id: String(t.id),
119
+ name: t.name,
120
+ }));
121
+ }
122
+ // Fallback: get teams from user/state
123
+ const res = await internalClient(config).get('/api/user/state');
124
+ return (res.data?.meta?.teams || []).map((t) => ({
125
+ id: String(t.id),
126
+ name: t.name,
127
+ }));
128
+ }
129
+ export async function listProjects(config, params) {
130
+ if (hasCookie(config)) {
131
+ const res = await internalClient(config).get(`/api/teams/${params.team_id}/folders`);
132
+ const rows = res.data?.meta?.folder_rows || res.data || [];
133
+ return (Array.isArray(rows) ? rows : []).map((p) => ({
134
+ id: String(p.id),
135
+ name: p.name || p.path,
136
+ }));
137
+ }
138
+ else {
139
+ const res = await publicClient(config).get(`/v1/teams/${params.team_id}/projects`);
140
+ return (res.data.projects || []).map((p) => ({
141
+ id: String(p.id),
142
+ name: p.name,
143
+ }));
144
+ }
145
+ }
146
+ export async function listFiles(config, params) {
147
+ // Prefer public API when PAT available -- returns keys compatible
148
+ // with all public endpoints (versions, comments, export).
149
+ if (hasPat(config)) {
150
+ const res = await publicClient(config).get(`/v1/projects/${params.project_id}/files`);
151
+ const files = (res.data.files || []).map((f) => ({
152
+ key: f.key,
153
+ name: f.name,
154
+ last_modified: f.last_modified,
155
+ thumbnail_url: f.thumbnail_url,
156
+ }));
157
+ return { files };
158
+ }
159
+ else {
160
+ const pageSize = Math.min(params.page_size || 25, 100);
161
+ const urlParams = new URLSearchParams({
162
+ folderId: params.project_id,
163
+ sort_column: 'touched_at',
164
+ sort_order: 'desc',
165
+ page_size: String(pageSize),
166
+ file_type: '',
167
+ });
168
+ if (params.page_token)
169
+ urlParams.set('before', params.page_token);
170
+ const res = await internalClient(config).get(`/api/folders/${params.project_id}/paginated_files?${urlParams}`);
171
+ const meta = res.data?.meta || res.data;
172
+ const files = (meta.files || meta.results || []).map((f) => ({
173
+ key: f.key,
174
+ name: f.name,
175
+ last_modified: f.touched_at || f.updated_at || f.last_modified,
176
+ editor_type: f.editor_type,
177
+ }));
178
+ const pagination = res.data?.pagination;
179
+ const result = { files };
180
+ if (pagination?.next_page || files.length === pageSize) {
181
+ result.pagination = {
182
+ has_more: true,
183
+ hint: `To get the next page, call list_files again with page_token="${pagination?.next_page || files[files.length - 1]?.last_modified || ''}"`,
184
+ };
185
+ }
186
+ return result;
187
+ }
188
+ }
189
+ export async function listRecentFiles(config) {
190
+ const res = await internalClient(config).get('/api/recent_files');
191
+ return (res.data?.meta?.recent_files || []).map((f) => ({
192
+ key: f.key,
193
+ name: f.name,
194
+ team_id: f.team_id,
195
+ folder_id: f.folder_id,
196
+ editor_type: f.editor_type,
197
+ last_touched: f.touched_at,
198
+ url: f.url || `https://www.figma.com/design/${f.key}`,
199
+ }));
200
+ }
201
+ export async function search(config, params) {
202
+ const orgId = requireOrgId(config, params.org_id);
203
+ const apiParams = {
204
+ query: params.query,
205
+ sort: params.sort || 'relevancy',
206
+ desc: 'true',
207
+ is_global: 'true',
208
+ org_id: orgId,
209
+ current_org_id: orgId,
210
+ plan_type: 'org',
211
+ };
212
+ const res = await internalClient(config).get('/api/search/file_browser_preview', { params: apiParams });
213
+ const meta = res.data?.meta;
214
+ const categories = Array.isArray(meta) ? meta : [];
215
+ const fileCategory = categories.find((c) => c.search_model_type === 'files') || categories[0];
216
+ const rawResults = fileCategory?.results || [];
217
+ return rawResults.map((r) => {
218
+ const m = r.model || r;
219
+ return {
220
+ key: m.key,
221
+ name: m.name,
222
+ editor_type: m.editor_type,
223
+ team_id: m.team_id ? String(m.team_id) : undefined,
224
+ folder_id: m.folder_id ? String(m.folder_id) : undefined,
225
+ last_modified: m.touched_at,
226
+ url: m.url || `https://www.figma.com/design/${m.key}`,
227
+ };
228
+ });
229
+ }
230
+ export async function getFileInfo(config, params) {
231
+ if (hasPat(config)) {
232
+ const res = await publicClient(config).get(`/v1/files/${params.file_key}/meta`);
233
+ const f = res.data.file || res.data;
234
+ return {
235
+ key: f.key || params.file_key,
236
+ name: f.name,
237
+ last_modified: f.lastModified || f.last_modified,
238
+ editor_type: f.editorType || f.editor_type,
239
+ url: `https://www.figma.com/design/${params.file_key}`,
240
+ };
241
+ }
242
+ else {
243
+ const res = await internalClient(config).get(`/api/files/${params.file_key}`);
244
+ const f = res.data?.meta || res.data;
245
+ return {
246
+ key: f.key || params.file_key,
247
+ name: f.name,
248
+ updated_at: f.updated_at,
249
+ editor_type: f.editor_type,
250
+ folder_id: f.folder_id ? String(f.folder_id) : undefined,
251
+ team_id: f.team_id ? String(f.team_id) : undefined,
252
+ link_access: f.link_access,
253
+ url: f.url || `https://www.figma.com/design/${params.file_key}`,
254
+ };
255
+ }
256
+ }
257
+ export async function listFavorites(config) {
258
+ const res = await internalClient(config).get('/api/user/favorited_resources');
259
+ const data = res.data?.meta || res.data;
260
+ return (Array.isArray(data) ? data : data.favorites || data.resources || []).map((f) => ({
261
+ key: f.key || f.file_key || f.id,
262
+ name: f.name,
263
+ type: f.resource_type || f.type,
264
+ }));
265
+ }
266
+ //# sourceMappingURL=navigate.js.map
@@ -0,0 +1,95 @@
1
+ import type { AuthConfig } from '../auth/client.js';
2
+ export declare const SEAT_HIERARCHY: Record<string, number>;
3
+ export declare const SEAT_LABELS: Record<string, string>;
4
+ export declare const PAID_STATUSES: Record<string, Record<string, string>>;
5
+ export declare const SEAT_KEY_TO_TYPE: Record<string, string>;
6
+ export interface Admin {
7
+ user_id: string;
8
+ email: string | undefined;
9
+ name: string | undefined;
10
+ permission: string;
11
+ seat_type: string | null;
12
+ is_email_validated: boolean;
13
+ license_admin: boolean;
14
+ }
15
+ export declare function listAdmins(config: AuthConfig, params: {
16
+ org_id?: string;
17
+ include_license_admins?: boolean;
18
+ }): Promise<Admin[]>;
19
+ export interface OrgTeam {
20
+ id: string;
21
+ name: string;
22
+ member_count: number | null;
23
+ project_count: number | null;
24
+ access_level: string | null;
25
+ }
26
+ export declare function listOrgTeams(config: AuthConfig, params: {
27
+ org_id?: string;
28
+ include_secret_teams?: boolean;
29
+ }): Promise<OrgTeam[]>;
30
+ export declare function seatUsage(config: AuthConfig, params: {
31
+ org_id?: string;
32
+ search_query?: string;
33
+ }): Promise<any>;
34
+ export interface TeamMember {
35
+ id: string;
36
+ name: string;
37
+ email: string;
38
+ img_url: string;
39
+ last_active: string | null;
40
+ team_role: number | null;
41
+ permission: string | null;
42
+ seat_type: string | null;
43
+ }
44
+ export declare function listTeamMembers(config: AuthConfig, params: {
45
+ team_id: string;
46
+ }): Promise<TeamMember[]>;
47
+ export declare function billingOverview(config: AuthConfig, params: {
48
+ org_id?: string;
49
+ }): Promise<any>;
50
+ export declare function listInvoices(config: AuthConfig, params: {
51
+ org_id?: string;
52
+ }): Promise<Record<string, any>>;
53
+ export declare function orgDomains(config: AuthConfig, params: {
54
+ org_id?: string;
55
+ }): Promise<Record<string, any>>;
56
+ export declare function aiCreditUsage(config: AuthConfig, params: {
57
+ plan_id: string;
58
+ }): Promise<any>;
59
+ export declare function exportMembers(config: AuthConfig, params: {
60
+ org_id?: string;
61
+ }): Promise<string>;
62
+ export interface OrgMember {
63
+ org_user_id: string;
64
+ user_id: string;
65
+ email: string | undefined;
66
+ name: string | undefined;
67
+ permission: string;
68
+ seat_type: string | null;
69
+ last_active: string | null;
70
+ }
71
+ export declare function listOrgMembers(config: AuthConfig, params: {
72
+ org_id?: string;
73
+ search_query?: string;
74
+ }): Promise<OrgMember[]>;
75
+ export interface ContractRate {
76
+ product: string;
77
+ monthly_cents: number;
78
+ monthly_dollars: string;
79
+ }
80
+ export declare function contractRates(config: AuthConfig, params: {
81
+ org_id?: string;
82
+ }): Promise<ContractRate[]>;
83
+ export interface ChangeSeatResult {
84
+ user: string | undefined;
85
+ email: string | undefined;
86
+ old_seat: string;
87
+ new_seat: string;
88
+ }
89
+ export declare function changeSeat(config: AuthConfig, params: {
90
+ user_id: string;
91
+ seat_type: string;
92
+ org_id?: string;
93
+ confirm?: boolean;
94
+ }): Promise<ChangeSeatResult | string>;
95
+ //# sourceMappingURL=org.d.ts.map