@animaapp/anima-sdk 0.3.11 → 0.4.3

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.
@@ -0,0 +1,533 @@
1
+ import { Component } from '@figma/rest-api-spec';
2
+ import { ComponentSet } from '@figma/rest-api-spec';
3
+ import { FigmaRestApi } from '@animaapp/http-client-figma';
4
+ import { GetFileResponse } from '@figma/rest-api-spec';
5
+ import { Node as Node_2 } from '@figma/rest-api-spec';
6
+ import { Style } from '@figma/rest-api-spec';
7
+
8
+ export declare class Anima {
9
+ #private;
10
+ constructor({ auth, apiBaseAddress, }?: {
11
+ auth?: Auth;
12
+ apiBaseAddress?: string;
13
+ path?: string;
14
+ });
15
+ protected hasAuth(): boolean;
16
+ set auth(auth: Auth);
17
+ protected get headers(): Record<string, string>;
18
+ generateCode(params: GetCodeParams, handler?: GetCodeHandler): Promise<AnimaSDKResult>;
19
+ /**
20
+ * @experimental
21
+ * This API is experimental and may change or be removed in future releases.
22
+ * Link2Code (l2c) flow.
23
+ */
24
+ generateLink2Code(params: GetLink2CodeParams, handler?: GetLink2CodeHandler): Promise<AnimaSDKResult>;
25
+ }
26
+
27
+ export declare type AnimaFiles = Record<string, {
28
+ content: string;
29
+ isBinary: boolean;
30
+ }>;
31
+
32
+ export declare type AnimaSDKResult = BaseResult & {
33
+ files: AnimaFiles;
34
+ assets?: Array<{
35
+ name: string;
36
+ url: string;
37
+ }>;
38
+ };
39
+
40
+ export declare type AssetsStorage = {
41
+ strategy: "host";
42
+ } | {
43
+ strategy: "external";
44
+ url: string;
45
+ };
46
+
47
+ export declare type Auth = {
48
+ token: string;
49
+ teamId: string;
50
+ } | {
51
+ token: string;
52
+ userId?: string;
53
+ };
54
+
55
+ export declare type BaseResult = {
56
+ sessionId: string;
57
+ figmaFileName: string;
58
+ figmaSelectedFrameName: string;
59
+ tokenUsage: number;
60
+ };
61
+
62
+ export declare class CodegenError extends Error {
63
+ status?: number;
64
+ detail?: unknown;
65
+ constructor({ name, reason, status, detail, }: {
66
+ name: string;
67
+ reason: CodegenErrorReason | CodegenRouteErrorReason | SDKErrorReason;
68
+ status?: number;
69
+ detail?: unknown;
70
+ });
71
+ }
72
+
73
+ /**
74
+ * Codegen errors from the worker
75
+ */
76
+ export declare type CodegenErrorReason = "Selected node type is not supported" | "Invisible group nodes are unsupported" | "Selected node is a page with multiple children" | "There is no node with the given id" | "Invalid Figma token" | "Anima API connection error" | "Figma token expired" | "Invalid user token" | "Figma file not found" | "Figma rate limit exceeded" | "Figma selection too large" | "Invalid responsive page node type" | "Unknown";
77
+
78
+ export declare type CodegenResult = BaseResult & {
79
+ files: Record<string, {
80
+ code: string;
81
+ type: "code";
82
+ }>;
83
+ };
84
+
85
+ /**
86
+ * Codegen errors from the "/codegen" route
87
+ */
88
+ export declare type CodegenRouteErrorReason = "Missing Authorization header" | "Invalid Authorization header" | "Missing teamId" | "Internal server error" | "Forbidden, no team access" | "Requested Usage Exceeds Limit" | "Not all frames id from responsive pages are mentioned on the nodes id list" | "Too many screens to import" | "Invalid Anima token";
89
+
90
+ export declare type CodegenSettings = {
91
+ language?: "typescript" | "javascript";
92
+ model?: string;
93
+ framework: "react" | "html";
94
+ styling: "plain_css" | "css_modules" | "styled_components" | "tailwind" | "sass" | "scss" | "inline_styles";
95
+ uiLibrary?: "mui" | "antd" | "radix" | "shadcn";
96
+ responsivePages?: Array<{
97
+ name: string;
98
+ framesId: string[];
99
+ }>;
100
+ enableTranslation?: boolean;
101
+ enableUILibraryTheming?: boolean;
102
+ enableCompactStructure?: boolean;
103
+ enableAutoSplit?: boolean;
104
+ autoSplitThreshold?: number;
105
+ disableMarkedForExport?: boolean;
106
+ enableDisplayScreenModelId?: boolean;
107
+ enableGeneratePackageLock?: boolean;
108
+ };
109
+
110
+ /**
111
+ * Creates a Server-Sent Events (SSE) `Response` that forwards all messages from the code generation stream.
112
+ *
113
+ * But, if the first message indicates an error (e.g., connection failed), the function returns a 500 response with the error message.
114
+ *
115
+ * @param {Anima} anima - The Anima instance to use for creating the data stream.
116
+ * @param {GetCodeParams} params - The parameters for the code generation request.
117
+ * @returns {Promise<Response>} - A promise that resolves to an HTTP response.
118
+ */
119
+ export declare const createCodegenResponseEventStream: (anima: Anima, params: GetCodeParams) => Promise<Response>;
120
+
121
+ /**
122
+ * Start the code generation and creates a ReadableStream to output its result.
123
+ *
124
+ * The stream is closed when the codegen ends.
125
+ *
126
+ * @param {Anima} anima - An Anima service instance to generate the code from.
127
+ * @param {GetCodeParams} params - Parameters required for the code generation process.
128
+ * @returns {ReadableStream<StreamCodgenMessage>} - A ReadableStream that emits messages related to the code generation process.
129
+ */
130
+ export declare const createCodegenStream: (anima: Anima, params: GetCodeParams) => ReadableStream<StreamCodgenMessage>;
131
+
132
+ /**
133
+ * Creates a Server-Sent Events (SSE) `Response` that forwards all messages from the URL to code generation stream.
134
+ *
135
+ * But, if the first message indicates an error (e.g., connection failed), the function returns a 500 response with the error message.
136
+ *
137
+ * @param {Anima} anima - The Anima instance to use for creating the data stream.
138
+ * @param {GetLink2CodeParams} params - The parameters for the URL to code generation request.
139
+ * @returns {Promise<Response>} - A promise that resolves to an HTTP response.
140
+ */
141
+ export declare const createLink2CodeResponseEventStream: (anima: Anima, params: GetLink2CodeParams) => Promise<Response>;
142
+
143
+ /**
144
+ * @experimental
145
+ * This API is experimental and may change or be removed in future releases.
146
+ * Link2Code (l2c) stream flow.
147
+ *
148
+ * Start the URL to code generation and creates a ReadableStream to output its result.
149
+ *
150
+ * The stream is closed when the URL to code generation ends.
151
+ *
152
+ * @param {Anima} anima - An Anima service instance to generate the code from.
153
+ * @param {GetLink2CodeParams} params - Parameters required for the URL to code generation process.
154
+ * @returns {ReadableStream<StreamL2CMessage>} - A ReadableStream that emits messages related to the URL to code generation process.
155
+ */
156
+ export declare const createLink2CodeStream: (anima: Anima, params: GetLink2CodeParams) => ReadableStream<StreamL2CMessage>;
157
+
158
+ export declare type FigmaApiError = {
159
+ cause: {
160
+ message?: string;
161
+ body: {
162
+ err: string;
163
+ status: number;
164
+ };
165
+ };
166
+ };
167
+
168
+ export declare type FigmaApiErrorType = "FigmaTokenIssue" | "RateLimitExceeded" | "NotFound" | "UnknownFigmaApiException" | "RequestTooLarge";
169
+
170
+ export declare type FigmaNode = Node_2;
171
+
172
+ export declare type FigmaPage = {
173
+ id: string;
174
+ name: string;
175
+ };
176
+
177
+ export declare class FigmaTokenIssue extends Error {
178
+ fileKey: string;
179
+ reason: string;
180
+ constructor({ fileKey, reason, cause, }: {
181
+ fileKey: string;
182
+ reason: string;
183
+ cause?: unknown;
184
+ });
185
+ }
186
+
187
+ export declare const findChildrenNode: (node: FigmaNode, targetNodeId: string) => FigmaNode | null;
188
+
189
+ export declare const formatToFigmaLink: ({ fileKey, nodeId, duplicate, }: {
190
+ fileKey: string;
191
+ nodeId: string;
192
+ duplicate?: boolean;
193
+ }) => URL;
194
+
195
+ export declare type GeneratingCodePayload = {
196
+ status: "success" | "running" | "failure";
197
+ progress: number;
198
+ files: AnimaFiles;
199
+ };
200
+
201
+ export declare type GetCodeHandler = ((message: SSECodgenMessage) => void) | {
202
+ onQueueing?: () => void;
203
+ onStart?: ({ sessionId }: {
204
+ sessionId: string;
205
+ }) => void;
206
+ onPreCodegen?: ({ message }: {
207
+ message: string;
208
+ }) => void;
209
+ onAssetsUploaded?: () => void;
210
+ onAssetsList?: ({ assets, }: {
211
+ assets: Array<{
212
+ name: string;
213
+ url: string;
214
+ }>;
215
+ }) => void;
216
+ onFigmaMetadata?: ({ figmaFileName, figmaSelectedFrameName, }: {
217
+ figmaFileName: string;
218
+ figmaSelectedFrameName: string;
219
+ }) => void;
220
+ onGeneratingCode?: ({ status, progress, files, }: {
221
+ status: "success" | "running" | "failure";
222
+ progress: number;
223
+ files: AnimaFiles;
224
+ }) => void;
225
+ onCodegenCompleted?: () => void;
226
+ };
227
+
228
+ export declare type GetCodeParams = {
229
+ fileKey: string;
230
+ figmaToken?: string;
231
+ nodesId: string[];
232
+ assetsStorage?: AssetsStorage;
233
+ settings: CodegenSettings;
234
+ tracking?: TrackingInfos;
235
+ };
236
+
237
+ export declare const getFigmaApiErrorType: (error: Error) => FigmaApiErrorType;
238
+
239
+ export declare const getFigmaFile: ({ fileKey, authToken, figmaRestApi, params, }: GetFilePagesParams) => Promise<GetFileResponse>;
240
+
241
+ export declare const getFileNodes: ({ fileKey, authToken, nodeIds, figmaRestApi, params, }: GetFileNodesParams) => Promise<{
242
+ [key: string]: {
243
+ document: Node_2;
244
+ components: {
245
+ [key: string]: Component;
246
+ };
247
+ componentSets: {
248
+ [key: string]: ComponentSet;
249
+ };
250
+ schemaVersion: number;
251
+ styles: {
252
+ [key: string]: Style;
253
+ };
254
+ };
255
+ }>;
256
+
257
+ export declare type GetFileNodesParams = {
258
+ fileKey: string;
259
+ authToken?: string;
260
+ nodeIds: string[];
261
+ figmaRestApi?: FigmaRestApi;
262
+ params?: Record<string, string | number>;
263
+ };
264
+
265
+ export declare type GetFilePagesParams = {
266
+ fileKey: string;
267
+ authToken?: string;
268
+ figmaRestApi?: FigmaRestApi;
269
+ params?: Record<string, string | number | undefined>;
270
+ };
271
+
272
+ export declare type GetFilePagesResult = FigmaPage[] | undefined;
273
+
274
+ export declare type GetFileParams = {
275
+ fileKey: string;
276
+ authToken?: string;
277
+ figmaRestApi?: FigmaRestApi;
278
+ };
279
+
280
+ export declare type GetLink2CodeHandler = ((message: SSEL2CMessage) => void) | {
281
+ onQueueing?: () => void;
282
+ onStart?: ({ sessionId }: {
283
+ sessionId: string;
284
+ }) => void;
285
+ onAssetsUploaded?: () => void;
286
+ onAssetsList?: ({ assets, }: {
287
+ assets: Array<{
288
+ name: string;
289
+ url: string;
290
+ }>;
291
+ }) => void;
292
+ onGeneratingCode?: ({ status, progress, files, }: {
293
+ status: "success" | "running" | "failure";
294
+ progress: number;
295
+ files: AnimaFiles;
296
+ }) => void;
297
+ onCodegenCompleted?: () => void;
298
+ };
299
+
300
+ export declare type GetLink2CodeParams = {
301
+ params: L2CParams;
302
+ assetsStorage?: AssetsStorage;
303
+ tracking?: TrackingInfos;
304
+ };
305
+
306
+ export declare const getRelatedScreenFiles: ({ files, screenPath, }: {
307
+ files: AnimaFiles;
308
+ screenPath?: string;
309
+ }) => AnimaFiles;
310
+
311
+ declare type InvalidNodeForCodegenReason = "Selected node is a page with multiple children" | "There is no node with the given id" | "Selected node type is not supported";
312
+
313
+ export declare const isFigmaTokenIssue: (error: Error) => boolean;
314
+
315
+ /**
316
+ * Check if the pair "design" + "node id" are valid for code generation.
317
+ */
318
+ export declare const isNodeCodegenCompatible: (design: GetFileResponse, nodeId: string) => ValidateNodeForCodegenResult;
319
+
320
+ export declare const isNotFound: (error: Error) => boolean;
321
+
322
+ export declare const isRateLimitExceeded: (error: Error) => boolean;
323
+
324
+ export declare const isRequestTooLarge: (error: Error) => boolean;
325
+
326
+ export declare const isUnknownFigmaApiException: (error: Error) => boolean;
327
+
328
+ export declare const isValidFigmaUrl: (figmaLink: string) => [hasCorrectPrefix: boolean, fileKey: string, nodeId: string];
329
+
330
+ export declare type L2CParams = {
331
+ input: L2CParamsInput;
332
+ conventions: L2CParamsConvention;
333
+ assetsStorage: L2CParamsAssetsStorage;
334
+ };
335
+
336
+ export declare type L2CParamsAssetsStorage = L2CParamsBundledAssetsStorage;
337
+
338
+ export declare type L2CParamsBundledAssetsStorage = {
339
+ type: 'bundled';
340
+ referencePath?: string;
341
+ };
342
+
343
+ export declare type L2CParamsConvention = L2CParamsHtmlConvention | L2CParamsReactConvention;
344
+
345
+ export declare type L2CParamsFramework = 'html' | 'react';
346
+
347
+ export declare type L2CParamsHtmlConvention = {
348
+ framework: 'html';
349
+ styling: L2CParamsStyling;
350
+ };
351
+
352
+ export declare type L2CParamsInput = L2CParamsUrlInput;
353
+
354
+ export declare type L2CParamsLanguage = 'typescript';
355
+
356
+ export declare type L2CParamsReactConvention = {
357
+ framework: 'react';
358
+ language: L2CParamsLanguage;
359
+ styling: L2CParamsStyling;
360
+ };
361
+
362
+ export declare type L2CParamsStyling = 'tailwind' | 'inline-styles';
363
+
364
+ export declare type L2CParamsUrlInput = {
365
+ type: 'url';
366
+ url: string;
367
+ };
368
+
369
+ export declare class NotFound extends Error {
370
+ fileKey: string;
371
+ constructor({ fileKey, cause }: {
372
+ fileKey: string;
373
+ cause?: unknown;
374
+ });
375
+ }
376
+
377
+ export declare class RateLimitExceeded extends Error {
378
+ fileKey: string;
379
+ constructor({ fileKey, cause }: {
380
+ fileKey: string;
381
+ cause?: unknown;
382
+ });
383
+ }
384
+
385
+ export declare class RequestTooLarge extends Error {
386
+ fileKey: string;
387
+ constructor({ fileKey, cause }: {
388
+ fileKey: string;
389
+ cause?: unknown;
390
+ });
391
+ }
392
+
393
+ export declare class ResponseError extends Error {
394
+ response: Response;
395
+ constructor(message: string, res: Response);
396
+ }
397
+
398
+ /**
399
+ * Errors from the SDK
400
+ */
401
+ export declare type SDKErrorReason = "Invalid body payload" | "No code generated" | "Connection closed before the 'done' message" | "Response body is null";
402
+
403
+ export declare type SSECodegenMessageErrorPayload = {
404
+ errorName: string;
405
+ task?: string;
406
+ reason: CodegenErrorReason;
407
+ sentryTraceId?: string;
408
+ };
409
+
410
+ export declare type SSECodgenMessage = {
411
+ type: "queueing";
412
+ } | {
413
+ type: "start";
414
+ sessionId: string;
415
+ } | {
416
+ type: "pre_codegen";
417
+ message: string;
418
+ } | {
419
+ type: "figma_metadata";
420
+ figmaFileName: string;
421
+ figmaSelectedFrameName: string;
422
+ } | {
423
+ type: "generating_code";
424
+ payload: GeneratingCodePayload;
425
+ } | {
426
+ type: "codegen_completed";
427
+ } | {
428
+ type: "assets_uploaded";
429
+ } | {
430
+ type: "assets_list";
431
+ payload: {
432
+ assets: Array<{
433
+ name: string;
434
+ url: string;
435
+ }>;
436
+ };
437
+ } | {
438
+ type: "aborted";
439
+ } | {
440
+ type: "error";
441
+ payload: SSECodgenMessageErrorPayload;
442
+ } | {
443
+ type: "done";
444
+ payload: {
445
+ sessionId: string;
446
+ tokenUsage: number;
447
+ };
448
+ };
449
+
450
+ export declare type SSECodgenMessageErrorPayload = {
451
+ errorName: string;
452
+ task?: string;
453
+ reason: CodegenErrorReason;
454
+ };
455
+
456
+ export declare type SSEL2CMessage = {
457
+ type: 'queueing';
458
+ } | {
459
+ type: 'start';
460
+ sessionId: string;
461
+ } | {
462
+ type: 'generating_code';
463
+ payload: GeneratingCodePayload;
464
+ } | {
465
+ type: 'generation_completed';
466
+ } | {
467
+ type: 'assets_uploaded';
468
+ } | {
469
+ type: 'assets_list';
470
+ payload: {
471
+ assets: Array<{
472
+ name: string;
473
+ url: string;
474
+ }>;
475
+ };
476
+ } | {
477
+ type: 'aborted';
478
+ } | {
479
+ type: 'error';
480
+ payload: SSECodegenMessageErrorPayload;
481
+ } | {
482
+ type: 'done';
483
+ payload: {
484
+ sessionId: string;
485
+ tokenUsage: number;
486
+ };
487
+ };
488
+
489
+ export declare type StreamCodgenMessage = StreamMessage<SSECodgenMessage>;
490
+
491
+ declare type StreamErrorPayload = {
492
+ name: string;
493
+ message: CodegenErrorReason;
494
+ status?: number;
495
+ detail?: unknown;
496
+ errorPayload?: SSECodegenMessageErrorPayload;
497
+ };
498
+
499
+ export declare type StreamL2CMessage = StreamMessage<SSEL2CMessage>;
500
+
501
+ export declare type StreamMessage<T> = Exclude<T, {
502
+ type: "error";
503
+ }> | {
504
+ type: "error";
505
+ payload: StreamErrorPayload;
506
+ };
507
+
508
+ export declare type TrackingInfos = {
509
+ externalId: string;
510
+ };
511
+
512
+ export declare class UnknownFigmaApiException extends Error {
513
+ fileKey: string;
514
+ constructor({ fileKey, cause }: {
515
+ fileKey: string;
516
+ cause: unknown;
517
+ });
518
+ }
519
+
520
+ declare type ValidateNodeForCodegenResult = {
521
+ isValid: true;
522
+ node: FigmaNode;
523
+ note?: "Selected node is a page with a single valid children - returning it instead";
524
+ } | {
525
+ isValid: false;
526
+ reason: InvalidNodeForCodegenReason;
527
+ };
528
+
529
+ export declare const validateSettings: (obj: unknown) => CodegenSettings;
530
+
531
+ export declare const wrapFigmaApiError: (error: FigmaApiError, fileKey: string) => Error;
532
+
533
+ export { }