Skip to content

Commit

Permalink
fix: import figma files in batches instead of imposing an arbitratry …
Browse files Browse the repository at this point in the history
…limit
  • Loading branch information
roperzh committed Nov 14, 2019
1 parent 6be5280 commit fb0ef03
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 14 deletions.
38 changes: 24 additions & 14 deletions packages/designfile/src/exporters/figma.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import path from 'path';
import url from 'url';
import {Exportable, OAutheable} from '.';
import {chunk} from '../helpers/arrayUtils';
import {createFolders, sanitizeFileName} from '../helpers/ioUtils';
import {downloadFile, performGetRequestWithBearerToken} from '../helpers/request';
import {UniqueNameResolver} from '../helpers/uniqueNameResolver';
Expand All @@ -9,7 +10,7 @@ const FIGMA_HOST = 'figma.com';
const API_BASE = 'https://api.figma.com/v1/';
const IS_FIGMA_FILE_RE = /\.figma$/;
const FIGMA_DEFAULT_FILENAME = 'Untitled';
const MAX_ITEMS_TO_IMPORT = 100;
const IMPORT_BATCH_SIZE = 100;
let token = '';

const enum ValidType {
Expand Down Expand Up @@ -46,7 +47,11 @@ export interface FigmaProject {

export interface FigmaImageResponse {
err: null|string;
images: {[key: string]: string};
images: FigmaImagesURL;
}

export interface FigmaImagesURL {
[key: string]: string;
}

/**
Expand Down Expand Up @@ -82,29 +87,34 @@ const getSVGContents = (elements: FigmaNode[], outFolder: string) => {
* @param id ID of the Figma file
*/
export const getSVGLinks = async (elements: FigmaNode[], id: string, authToken: string) => {
let ids = elements.map((element) => element.id);
const ids = chunk(elements.map((element) => element.id), IMPORT_BATCH_SIZE);

if (ids.length === 0) {
if (ids[0].length === 0) {
throw new Error(
"It looks like the Figma document you imported doesn't have any exportable elements." +
'Try adding some and re-syncing.',
);
}

// TODO: instead of limiting the max number of items to import, import them in batches
if (ids.length > MAX_ITEMS_TO_IMPORT) {
ids = ids.slice(0, MAX_ITEMS_TO_IMPORT);
}
const chunkedResponse = await Promise.all(ids.map(async (idsChunk) => {
const params = new url.URLSearchParams([
['format', 'svg'],
['ids', idsChunk.join(',')],
['svg_include_id', 'true'],
]);

const params = new url.URLSearchParams([['format', 'svg'], ['ids', ids.join(',')], ['svg_include_id', 'true']]);
const {images} = await performGetRequestWithBearerToken<FigmaImageResponse>(
`${API_BASE}images/${id}?${params.toString()}`,
token,
);

const svgLinks = await performGetRequestWithBearerToken<FigmaImageResponse>(
`${API_BASE}images/${id}?${params.toString()}`,
token,
);
return images;
}));

const imageResponse: FigmaImagesURL = Object.assign({}, ...chunkedResponse);

return elements.map((element) => {
return Object.assign(element, {svgURL: svgLinks.images[element.id]}) as FigmaNode;
return Object.assign(element, {svgURL: imageResponse[element.id]}) as FigmaNode;
});
};

Expand Down
10 changes: 10 additions & 0 deletions packages/designfile/src/helpers/arrayUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export const chunk = <T>(arr: T[], chunkSize: number) => {
const temp = arr.slice(0);
const results = [];

while (temp.length) {
results.push(temp.splice(0, chunkSize));
}

return results;
};
11 changes: 11 additions & 0 deletions packages/designfile/test/helpers/arrayUtils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as arrayUtils from '../../src/helpers/arrayUtils';

describe('arrayUtils', () => {
describe('#chunk', () => {
test('', () => {
expect(arrayUtils.chunk([1, 2, 3], 3)).toEqual([[1, 2, 3]]);
expect(arrayUtils.chunk([1, 2, 3], 2)).toEqual([[1, 2], [3]]);
expect(arrayUtils.chunk([1, 2, 3], 1)).toEqual([[1], [2], [3]]);
});
});
});

0 comments on commit fb0ef03

Please sign in to comment.