@opendesign/octopus-fig
Advanced tools
Comparing version 3.0.0-rc.18 to 3.0.0-rc.19
{ | ||
"name": "@opendesign/octopus-fig", | ||
"version": "3.0.0-rc.18", | ||
"version": "3.0.0-rc.19", | ||
"description": "Figma HTTP API format to Octopus 3+ converter.", | ||
@@ -22,2 +22,3 @@ "license": "Apache-2.0", | ||
"types:check": "tsc --noEmit", | ||
"typedoc": "typedoc --excludePrivate src/index-node.ts src/index-web.ts", | ||
"watch": "tsc -w" | ||
@@ -27,5 +28,5 @@ }, | ||
"@opendesign/figma-parser": "3.0.0-rc.13", | ||
"@opendesign/manifest-ts": "3.0.0-alpha.38", | ||
"@opendesign/manifest-ts": "3.0.0-alpha.40", | ||
"@opendesign/octopus-common": "3.0.0-rc.27", | ||
"@opendesign/octopus-ts": "3.0.0-alpha.38", | ||
"@opendesign/octopus-ts": "3.0.0-alpha.40", | ||
"@types/lodash": "^4.14.178", | ||
@@ -54,2 +55,3 @@ "@types/pino": "^6.3.3", | ||
"ts-node": "10.8.0", | ||
"typedoc": "^0.23.18", | ||
"typescript": "4.6.4" | ||
@@ -56,0 +58,0 @@ }, |
@@ -36,4 +36,4 @@ import type { OctopusFigConverter } from '../../octopus-fig-converter'; | ||
getExportedImagePath(name: string): string | undefined; | ||
setExportedPreviewPath(id: string, path: string | undefined): void; | ||
getExportedPreviewPath(id: string): string | undefined; | ||
setExportedPreviewPath(componentId: string, path: string | undefined): void; | ||
getExportedPreviewPath(componentId: string): string | undefined; | ||
setExportedComponentImageMap(componentId: string, imageIds: string[]): void; | ||
@@ -40,0 +40,0 @@ getExportedComponentImageMap(componentId: string): string[] | undefined; |
@@ -6,2 +6,3 @@ "use strict"; | ||
const services_1 = require("../../services"); | ||
const convert_1 = require("../../utils/convert"); | ||
const source_1 = require("../../utils/source"); | ||
@@ -28,7 +29,7 @@ class OctopusManifest { | ||
} | ||
setExportedPreviewPath(id, path) { | ||
this._exports.images.set(id, path); | ||
setExportedPreviewPath(componentId, path) { | ||
this._exports.previews.set(componentId, path); | ||
} | ||
getExportedPreviewPath(id) { | ||
return this._exports.images.get(id); | ||
getExportedPreviewPath(componentId) { | ||
return this._exports.previews.get(componentId); | ||
} | ||
@@ -54,9 +55,12 @@ setExportedComponentImageMap(componentId, imageIds) { | ||
setExportedLibrary(options) { | ||
const { designId: id, name, designNodeId } = options; | ||
const library = this._exports.libraries.get(id); | ||
const { designId, name, designNodeId } = options; | ||
const id = (0, convert_1.convertId)(designId); | ||
const child = { id: (0, convert_1.convertId)(designNodeId), type: 'COMPONENT' }; | ||
const library = this._exports.libraries.get(designId); | ||
if (!library) { | ||
this._exports.libraries.set(id, { id, name, children: [{ id: designNodeId, type: 'COMPONENT' }] }); | ||
const meta = { originalId: designId }; | ||
this._exports.libraries.set(designId, { id, name, meta, children: [child] }); | ||
} | ||
else { | ||
library.children = (0, common_1.push)(library.children, { id: designNodeId, type: 'COMPONENT' }); | ||
library.children = (0, common_1.push)(library.children, child); | ||
} | ||
@@ -101,5 +105,6 @@ } | ||
return this._sourceDesign.pages.map((page) => ({ | ||
id: page.id, | ||
id: (0, convert_1.convertId)(page.id), | ||
name: page.name, | ||
children: page.children.map((elem) => ({ id: elem.id, type: 'COMPONENT' })), | ||
meta: { originalId: page.id }, | ||
children: page.children.map((elem) => ({ id: (0, convert_1.convertId)(elem.id), type: 'COMPONENT' })), | ||
})); | ||
@@ -109,3 +114,4 @@ } | ||
var _a; | ||
const status = this.getExportedComponentDescriptorById(source.id); | ||
const id = source.id; | ||
const status = this.getExportedComponentDescriptorById(id); | ||
const statusValue = status ? (status.error ? 'FAILED' : 'READY') : 'PROCESSING'; | ||
@@ -168,3 +174,3 @@ return { | ||
_getVariant(id) { | ||
const component = this._sourceDesign.components[id]; | ||
const component = this._sourceDesign.getComponentById(id); | ||
if (!component) | ||
@@ -181,3 +187,3 @@ return undefined; | ||
return undefined; | ||
const of = { id: setId, name: setName, description: setDescription }; | ||
const of = { id: (0, convert_1.convertId)(setId), name: setName, meta: { originalId: setId }, description: setDescription }; | ||
const properties = this._getVariantProperties(component.name); | ||
@@ -189,4 +195,4 @@ return { of, properties, description }; | ||
return undefined; | ||
const { id, meta } = style; | ||
const { name, description, styleType } = meta; | ||
const id = (0, convert_1.convertId)(style.id); | ||
const { name, description, styleType } = style.meta; | ||
const type = (0, common_1.getMapped)(styleType, OctopusManifest.CHUNK_TYPE_MAP, undefined); | ||
@@ -198,3 +204,4 @@ if (!type) { | ||
const location = { type: 'RELATIVE', path: sourcePath }; | ||
return { id, name, description, type, location }; | ||
const meta = { originalId: style.id }; | ||
return { id, name, meta, description, type, location }; | ||
} | ||
@@ -211,6 +218,6 @@ get chunks() { | ||
var _a, _b; | ||
const id = source.id; | ||
const id = (0, convert_1.convertId)(source.id); | ||
const bounds = (_a = source.bounds) !== null && _a !== void 0 ? _a : undefined; | ||
const status = this._getStatus(source); | ||
const path = (_b = this.getExportedComponentPathById(id)) !== null && _b !== void 0 ? _b : ''; | ||
const path = (_b = this.getExportedComponentPathById(source.id)) !== null && _b !== void 0 ? _b : ''; | ||
const location = { type: 'RELATIVE', path }; | ||
@@ -220,4 +227,5 @@ const assets = this._getAssets(source); | ||
const role = (0, source_1.getRole)(source); | ||
const preview = this._getPreview(id); | ||
const variant = this._getVariant(id); | ||
const preview = this._getPreview(source.id); | ||
const variant = this._getVariant(source.id); | ||
const meta = { originalId: source.id }; | ||
return { | ||
@@ -227,2 +235,3 @@ id, | ||
role, | ||
meta, | ||
status, | ||
@@ -229,0 +238,0 @@ bounds, |
import { SourceEntity } from './source-entity'; | ||
import { SourcePage } from './source-page'; | ||
import type { RawComponents, RawComponentSets, RawDesign, RawStyles } from '../../typings/raw'; | ||
import type { RawComponent, RawComponents, RawComponentSets, RawDesign, RawStyles } from '../../typings/raw'; | ||
declare type SourceDesignOptions = { | ||
@@ -19,2 +19,3 @@ raw: RawDesign; | ||
get components(): RawComponents; | ||
getComponentById(id: string): RawComponent | undefined; | ||
get componentSets(): RawComponentSets; | ||
@@ -21,0 +22,0 @@ get styles(): RawStyles; |
@@ -32,2 +32,5 @@ "use strict"; | ||
} | ||
getComponentById(id) { | ||
return this.components[id]; | ||
} | ||
get componentSets() { | ||
@@ -34,0 +37,0 @@ var _a; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.SourcePage = void 0; | ||
const convert_1 = require("../../utils/convert"); | ||
const source_component_1 = require("./source-component"); | ||
@@ -56,3 +55,3 @@ const source_entity_1 = require("./source-entity"); | ||
var _a; | ||
return (0, convert_1.convertId)((_a = this._rawValue.id) !== null && _a !== void 0 ? _a : SourcePage.DEFAULT_ID); | ||
return (_a = this._rawValue.id) !== null && _a !== void 0 ? _a : SourcePage.DEFAULT_ID; | ||
} | ||
@@ -59,0 +58,0 @@ get name() { |
@@ -1,10 +0,42 @@ | ||
import type { DesignConverterOptions, DesignConversionResult } from './services/conversion/design-converter'; | ||
import type { DesignConversionResult } from './services/conversion/design-converter'; | ||
import type { AbstractExporter } from './services/exporters/abstract-exporter'; | ||
import type { ImageSize } from './services/general/image-size/image-size'; | ||
import type { NodeFactories, WebFactories } from './services/general/platforms'; | ||
import type { Logger } from './typings'; | ||
import type EventEmitter from 'eventemitter3'; | ||
export declare type OctopusConverterOptions = { | ||
platformFactories: WebFactories | NodeFactories; | ||
/** Optional custom Logger. If not passed, default logger will be used. */ | ||
logger?: Logger; | ||
platformFactories: WebFactories | NodeFactories; | ||
loggerEnabled?: boolean; | ||
}; | ||
export declare type DesignConverterOptions = { | ||
/** `EventEmitter` providing source data to the converter */ | ||
designEmitter: EventEmitter | null; | ||
/** Optional unique Design Identifier. If not passed, will be generated by UUIDv4. */ | ||
designId?: string; | ||
/** Optional Exporter. */ | ||
exporter?: AbstractExporter; | ||
/** OctopusManifest updating Interval (in milliseconds) */ | ||
partialUpdateInterval?: number; | ||
/** | ||
* When set to `true`, instead of `DesignConversionResult` will return `null`. | ||
* Useful when you don't care what is returned and just need the design assets to be exported. | ||
*/ | ||
skipReturn?: boolean; | ||
}; | ||
/** | ||
* Octopus Figma Converter | ||
* Main class for converting Figma designs into Octopus3. | ||
* | ||
* There are three main processing steps: | ||
* - reading source data (using _reader_) | ||
* - conversion (using `.convertDesign()` method with `EventEmitter` instance produced by reader) | ||
* - exporting (using _exporter_) | ||
* | ||
* Readers used in other Octopus converters return `SourceDesign` instance, which, actually, is object with static values inside. | ||
* In case of Figma, we have slightly different approach because of it's asynchronous origin (requesting values using HTTP). | ||
* So, to provide source data as fast as possible to the converter we use `EventEmitter` inside of Figma Reader's `SourceDesign` instance. | ||
* This makes it possible to process data almost as fast as it's downloaded from Figma's API. | ||
*/ | ||
export declare class OctopusFigConverter { | ||
@@ -11,0 +43,0 @@ private _pkg; |
@@ -8,2 +8,16 @@ "use strict"; | ||
const read_pkg_meta_1 = require("./utils/read-pkg-meta"); | ||
/** | ||
* Octopus Figma Converter | ||
* Main class for converting Figma designs into Octopus3. | ||
* | ||
* There are three main processing steps: | ||
* - reading source data (using _reader_) | ||
* - conversion (using `.convertDesign()` method with `EventEmitter` instance produced by reader) | ||
* - exporting (using _exporter_) | ||
* | ||
* Readers used in other Octopus converters return `SourceDesign` instance, which, actually, is object with static values inside. | ||
* In case of Figma, we have slightly different approach because of it's asynchronous origin (requesting values using HTTP). | ||
* So, to provide source data as fast as possible to the converter we use `EventEmitter` inside of Figma Reader's `SourceDesign` instance. | ||
* This makes it possible to process data almost as fast as it's downloaded from Figma's API. | ||
*/ | ||
class OctopusFigConverter { | ||
@@ -31,5 +45,3 @@ constructor(options) { | ||
(0, services_1.setDefaults)({ | ||
logger: { | ||
enabled: (_a = options.loggerEnabled) !== null && _a !== void 0 ? _a : true, | ||
}, | ||
logger: { enabled: (_a = options.loggerEnabled) !== null && _a !== void 0 ? _a : true }, | ||
}); | ||
@@ -36,0 +48,0 @@ if (options.logger) |
import { OctopusManifest } from '../../entities/octopus/octopus-manifest'; | ||
import type { OctopusFigConverter } from '../../octopus-fig-converter'; | ||
import type { DesignConverterOptions, OctopusFigConverter } from '../../octopus-fig-converter'; | ||
import type { Manifest } from '../../typings/manifest'; | ||
import type { Octopus } from '../../typings/octopus'; | ||
import type { AbstractExporter } from '../exporters/abstract-exporter'; | ||
import type { ImageSize } from '../general/image-size/image-size'; | ||
import type EventEmitter from 'eventemitter3'; | ||
export declare type DesignConverterOptions = { | ||
designEmitter: EventEmitter | null; | ||
designId?: string; | ||
exporter?: AbstractExporter; | ||
partialUpdateInterval?: number; | ||
skipReturn?: boolean; | ||
}; | ||
export declare type ImageSizeMap = { | ||
@@ -16,0 +7,0 @@ [key: string]: ImageSize; |
@@ -158,3 +158,3 @@ "use strict"; | ||
const previewPath = await ((_b = (_a = this._exporter) === null || _a === void 0 ? void 0 : _a.exportPreview) === null || _b === void 0 ? void 0 : _b.call(_a, preview.nodeId, preview.buffer)); | ||
(_c = this.octopusManifest) === null || _c === void 0 ? void 0 : _c.setExportedImagePath(previewId, previewPath); | ||
(_c = this.octopusManifest) === null || _c === void 0 ? void 0 : _c.setExportedPreviewPath(previewId, previewPath); | ||
if (this._shouldReturn) | ||
@@ -161,0 +161,0 @@ this._conversionResult.previews.push({ id: previewId, data: preview.buffer }); |
/// <reference types="node" /> | ||
import EventEmitter from 'events'; | ||
import { getOctopusFileName, getPreviewFileName, getSourceFileName } from '../../../utils/exporter'; | ||
import type { Manifest } from '../../../typings/manifest'; | ||
import type { RawDesign, RawLayerFrame } from '../../../typings/raw'; | ||
import type { ComponentConversionResult } from '../../conversion/design-converter'; | ||
import type { AbstractExporter } from '../abstract-exporter'; | ||
import type { DetachedPromiseControls } from '@opendesign/octopus-common/dist/utils/async'; | ||
import type { ResolvedStyle } from '@opendesign/figma-parser/lib/src/index-node'; | ||
declare type DebugExporterOptions = { | ||
/** Path to directory, where designs outputs should be exported. */ | ||
tempDir: string; | ||
/** Unique ID of the exported design. If not given, will be generated by UUIDv4. Exporter outputs will be generated into `tempDir/id` folder. */ | ||
designId?: string; | ||
tempDir: string; | ||
}; | ||
/** | ||
* Exporter created to be used in manual runs. | ||
*/ | ||
export declare class DebugExporter extends EventEmitter implements AbstractExporter { | ||
_outputDir: Promise<string>; | ||
_tempDir: string; | ||
_assetsSaves: Promise<unknown>[]; | ||
_completed: DetachedPromiseControls<void>; | ||
_manifestPath: string | undefined; | ||
private _outputDir; | ||
private _tempDir; | ||
private _assetsSaves; | ||
private _completed; | ||
private _manifestPath; | ||
static IMAGES_DIR_NAME: string; | ||
static MANIFEST_NAME: string; | ||
static getSourceFileName: typeof getSourceFileName; | ||
static getOctopusFileName: typeof getOctopusFileName; | ||
static getPreviewFileName: typeof getPreviewFileName; | ||
/** | ||
* Exports octopus assets into given `tempDir`. | ||
* @constructor | ||
* @param {DebugExporterOptions} [options] | ||
*/ | ||
constructor(options: DebugExporterOptions); | ||
@@ -22,13 +39,51 @@ private _initOutputDir; | ||
finalizeExport(): void; | ||
get manifestPath(): string | undefined; | ||
set manifestPath(path: string | undefined); | ||
exportRawDesign(raw: unknown): Promise<string>; | ||
exportRawComponent(raw: unknown, name: string): Promise<string>; | ||
exportRawChunk(raw: unknown, name: string): Promise<string>; | ||
/** | ||
* Exports given design raw data. | ||
* @param {RawDesign} raw Design raw data | ||
* @returns {Promise<string>} returns path to the exported RawDesign | ||
*/ | ||
exportRawDesign(raw: RawDesign): Promise<string>; | ||
/** | ||
* Exports raw data of given Component. | ||
* @param {RawLayerFrame} raw Component raw data | ||
* @param {string} name Name of given Component | ||
* @returns {Promise<string>} returns path to the exported RawComponent | ||
*/ | ||
exportRawComponent(raw: RawLayerFrame, name: string): Promise<string>; | ||
/** | ||
* Exports raw data of given chunk. | ||
* @param {ResolvedStyle} raw Chunk raw data | ||
* @param {string} name Name of given Chunk | ||
* @returns {Promise<string>} returns path to the exported RawChunk | ||
*/ | ||
exportRawChunk(raw: ResolvedStyle, name: string): Promise<string>; | ||
/** | ||
* Exports given OctopusComponent | ||
* @param {ComponentConversionResult} result contains converted OctopusComponent or Error if conversion failed | ||
* @param {Manifest['Component']['role']} [role] Role/Type of given OctopusComponent. | ||
* @returns {Promise<string | null>} returns path to the exported OctopusComponent or `null` if conversion failed | ||
*/ | ||
exportComponent(result: ComponentConversionResult, role: Manifest['Component']['role']): Promise<string | null>; | ||
getImagePath(name: string): string; | ||
/** | ||
* Exports given Image into folder specified in `DebugExporter.IMAGES_DIR_NAME` | ||
* @param {string} name Name of the exported Image | ||
* @param {ArrayBuffer} data Image data represented as buffer of binary data | ||
* @returns {Promise<string>} returns path to the exported Image | ||
*/ | ||
exportImage(name: string, data: ArrayBuffer): Promise<string>; | ||
/** | ||
* Exports given Image Preview into folder specified in `DebugExporter.getPreviewFileName()` | ||
* @param {string} id ID of the exported Image | ||
* @param {ArrayBuffer} data Image data represented as buffer of binary data | ||
* @returns {Promise<string>} returns path to the exported Image Preview | ||
*/ | ||
exportPreview(id: string, data: ArrayBuffer): Promise<string>; | ||
/** | ||
* Exports given converted OctopusManifest. | ||
* @param {Manifest['OctopusManifest']} manifest Given converted OctopusManifest data object. | ||
* @returns {Promise<string>} returns path to the OctopusManifest | ||
*/ | ||
exportManifest(manifest: Manifest['OctopusManifest']): Promise<string>; | ||
} | ||
export {}; |
@@ -15,3 +15,11 @@ "use strict"; | ||
const misc_1 = require("../../../utils/misc"); | ||
/** | ||
* Exporter created to be used in manual runs. | ||
*/ | ||
class DebugExporter extends events_1.default { | ||
/** | ||
* Exports octopus assets into given `tempDir`. | ||
* @constructor | ||
* @param {DebugExporterOptions} [options] | ||
*/ | ||
constructor(options) { | ||
@@ -27,3 +35,3 @@ super(); | ||
const tempPath = path_1.default.join(this._tempDir, dirName); | ||
await (0, files_1.makeDir)(path_1.default.join(tempPath, exporter_1.IMAGES_DIR_NAME)); | ||
await (0, files_1.makeDir)(path_1.default.join(tempPath, DebugExporter.IMAGES_DIR_NAME)); | ||
return tempPath; | ||
@@ -44,13 +52,12 @@ } | ||
finalizeExport() { | ||
this.emit('octopus:manifest', this.manifestPath); | ||
this.emit('octopus:manifest', this._manifestPath); | ||
this._completed.resolve(); | ||
} | ||
get manifestPath() { | ||
return this._manifestPath; | ||
} | ||
set manifestPath(path) { | ||
this._manifestPath = path; | ||
} | ||
/** | ||
* Exports given design raw data. | ||
* @param {RawDesign} raw Design raw data | ||
* @returns {Promise<string>} returns path to the exported RawDesign | ||
*/ | ||
async exportRawDesign(raw) { | ||
const rawPath = (0, exporter_1.getSourceFileName)('design'); | ||
const rawPath = DebugExporter.getSourceFileName('design'); | ||
const savedPath = await this._save(rawPath, (0, misc_1.stringify)(raw)); | ||
@@ -60,4 +67,10 @@ this.emit('raw:design', savedPath); | ||
} | ||
/** | ||
* Exports raw data of given Component. | ||
* @param {RawLayerFrame} raw Component raw data | ||
* @param {string} name Name of given Component | ||
* @returns {Promise<string>} returns path to the exported RawComponent | ||
*/ | ||
async exportRawComponent(raw, name) { | ||
const rawPath = (0, exporter_1.getSourceFileName)(name); | ||
const rawPath = DebugExporter.getSourceFileName(name); | ||
const savedPath = await this._save(rawPath, (0, misc_1.stringify)(raw)); | ||
@@ -67,4 +80,10 @@ this.emit('raw:component', savedPath); | ||
} | ||
/** | ||
* Exports raw data of given chunk. | ||
* @param {ResolvedStyle} raw Chunk raw data | ||
* @param {string} name Name of given Chunk | ||
* @returns {Promise<string>} returns path to the exported RawChunk | ||
*/ | ||
async exportRawChunk(raw, name) { | ||
const rawPath = (0, exporter_1.getSourceFileName)(name); | ||
const rawPath = DebugExporter.getSourceFileName(name); | ||
const savedPath = await this._save(rawPath, (0, misc_1.stringify)(raw)); | ||
@@ -74,2 +93,8 @@ this.emit('raw:chunk', savedPath); | ||
} | ||
/** | ||
* Exports given OctopusComponent | ||
* @param {ComponentConversionResult} result contains converted OctopusComponent or Error if conversion failed | ||
* @param {Manifest['Component']['role']} [role] Role/Type of given OctopusComponent. | ||
* @returns {Promise<string | null>} returns path to the exported OctopusComponent or `null` if conversion failed | ||
*/ | ||
async exportComponent(result, role) { | ||
@@ -80,3 +105,3 @@ if (!result.value) { | ||
} | ||
const path = (0, exporter_1.getOctopusFileName)(result.id); | ||
const path = DebugExporter.getOctopusFileName(result.id); | ||
const octopusPath = await this._save(path, (0, misc_1.stringify)(result.value)); | ||
@@ -87,4 +112,10 @@ this.emit('octopus:component', { ...result, octopusPath }, role); | ||
getImagePath(name) { | ||
return path_1.default.join(exporter_1.IMAGES_DIR_NAME, `${name}${exporter_1.IMAGE_EXTNAME}`); | ||
return path_1.default.join(DebugExporter.IMAGES_DIR_NAME, `${name}${exporter_1.IMAGE_EXTNAME}`); | ||
} | ||
/** | ||
* Exports given Image into folder specified in `DebugExporter.IMAGES_DIR_NAME` | ||
* @param {string} name Name of the exported Image | ||
* @param {ArrayBuffer} data Image data represented as buffer of binary data | ||
* @returns {Promise<string>} returns path to the exported Image | ||
*/ | ||
async exportImage(name, data) { | ||
@@ -96,4 +127,10 @@ const imagePath = this.getImagePath(name); | ||
} | ||
/** | ||
* Exports given Image Preview into folder specified in `DebugExporter.getPreviewFileName()` | ||
* @param {string} id ID of the exported Image | ||
* @param {ArrayBuffer} data Image data represented as buffer of binary data | ||
* @returns {Promise<string>} returns path to the exported Image Preview | ||
*/ | ||
async exportPreview(id, data) { | ||
const previewPath = (0, exporter_1.getPreviewFileName)(id); | ||
const previewPath = DebugExporter.getPreviewFileName(id); | ||
const savedPath = await this._save(previewPath, Buffer.from(data)); | ||
@@ -103,7 +140,17 @@ this.emit('source:preview', savedPath); | ||
} | ||
/** | ||
* Exports given converted OctopusManifest. | ||
* @param {Manifest['OctopusManifest']} manifest Given converted OctopusManifest data object. | ||
* @returns {Promise<string>} returns path to the OctopusManifest | ||
*/ | ||
async exportManifest(manifest) { | ||
this.manifestPath = await this._save(exporter_1.MANIFEST_FILE_NAME, (0, misc_1.stringify)(manifest)); | ||
return this.manifestPath; | ||
this._manifestPath = await this._save(DebugExporter.MANIFEST_NAME, (0, misc_1.stringify)(manifest)); | ||
return this._manifestPath; | ||
} | ||
} | ||
exports.DebugExporter = DebugExporter; | ||
DebugExporter.IMAGES_DIR_NAME = exporter_1.IMAGES_DIR_NAME; | ||
DebugExporter.MANIFEST_NAME = exporter_1.MANIFEST_NAME; | ||
DebugExporter.getSourceFileName = exporter_1.getSourceFileName; | ||
DebugExporter.getOctopusFileName = exporter_1.getOctopusFileName; | ||
DebugExporter.getPreviewFileName = exporter_1.getPreviewFileName; |
@@ -0,12 +1,28 @@ | ||
import { getOctopusFileName, getPreviewFileName, getSourceFileName } from '../../../utils/exporter'; | ||
import type { Manifest } from '../../../typings/manifest'; | ||
import type { RawDesign, RawLayerFrame } from '../../../typings/raw'; | ||
import type { ComponentConversionResult } from '../../conversion/design-converter'; | ||
import type { AbstractExporter } from '../abstract-exporter'; | ||
import type { DetachedPromiseControls } from '@opendesign/octopus-common/dist/utils/async'; | ||
import type { ResolvedStyle } from '@opendesign/figma-parser/lib/src/index-node'; | ||
declare type LocalExporterOptions = { | ||
/** Path to directory, where results will be exported. If not provided will use `os.tmpdir()`. */ | ||
path: string; | ||
}; | ||
/** | ||
* Exporter created to be used in automated runs. | ||
*/ | ||
export declare class LocalExporter implements AbstractExporter { | ||
_outputDir: Promise<string>; | ||
_assetsSaves: Promise<unknown>[]; | ||
_completed: DetachedPromiseControls<void>; | ||
private _outputDir; | ||
private _assetsSaves; | ||
private _completed; | ||
static IMAGES_DIR_NAME: string; | ||
static MANIFEST_NAME: string; | ||
static getSourceFileName: typeof getSourceFileName; | ||
static getOctopusFileName: typeof getOctopusFileName; | ||
static getPreviewFileName: typeof getPreviewFileName; | ||
/** | ||
* Exports octopus assets into given or system TempDir | ||
* @constructor | ||
* @param {DebugExporterOptions} [options] | ||
*/ | ||
constructor(options: LocalExporterOptions); | ||
@@ -17,11 +33,50 @@ private _initTempDir; | ||
finalizeExport(): void; | ||
exportRawDesign(raw: unknown): Promise<string>; | ||
exportRawComponent(raw: unknown, name: string): Promise<string>; | ||
exportRawChunk(raw: unknown, name: string): Promise<string>; | ||
/** | ||
* Exports given design raw data. | ||
* @param {RawDesign} raw Design raw data | ||
* @returns {Promise<string>} returns path to the exported RawDesign | ||
*/ | ||
exportRawDesign(raw: RawDesign): Promise<string>; | ||
/** | ||
* Exports raw data of given Component. | ||
* @param {RawLayerFrame} raw Component raw data | ||
* @param {string} name Name of given Component | ||
* @returns {Promise<string>} returns path to the exported RawComponent | ||
*/ | ||
exportRawComponent(raw: RawLayerFrame, name: string): Promise<string>; | ||
/** | ||
* Exports raw data of given chunk. | ||
* @param {ResolvedStyle} raw Chunk raw data | ||
* @param {string} name Name of given Chunk | ||
* @returns {Promise<string>} returns path to the exported RawChunk | ||
*/ | ||
exportRawChunk(raw: ResolvedStyle, name: string): Promise<string>; | ||
/** | ||
* Exports given OctopusComponent | ||
* @param {ComponentConversionResult} result contains converted OctopusComponent or Error if conversion failed | ||
* @returns {Promise<string | null>} returns path to the exported OctopusComponent or `null` if conversion failed | ||
*/ | ||
exportComponent(result: ComponentConversionResult): Promise<string | null>; | ||
getImagePath(name: string): string; | ||
/** | ||
* Exports given Image into folder specified in `LocalExporter.IMAGES_DIR_NAME` | ||
* @param {string} name Name of the exported Image | ||
* @param {ArrayBuffer} data Image data represented as buffer of binary data | ||
* @returns {Promise<string>} returns path to the exported Image | ||
*/ | ||
exportImage(name: string, data: ArrayBuffer): Promise<string>; | ||
/** | ||
* Exports given Image Preview into folder specified in `LocalExporter.getPreviewFileName()` | ||
* @param {string} id ID of the exported Image | ||
* @param {ArrayBuffer} data Image data represented as buffer of binary data | ||
* @returns {Promise<string>} returns path to the exported Image Preview | ||
*/ | ||
exportPreview(id: string, data: ArrayBuffer): Promise<string>; | ||
/** | ||
* Exports given converted OctopusManifest. | ||
* @param {Manifest['OctopusManifest']} manifest Given converted OctopusManifest data object. | ||
* @returns {Promise<string>} returns path to the OctopusManifest | ||
*/ | ||
exportManifest(manifest: Manifest['OctopusManifest']): Promise<string>; | ||
} | ||
export {}; |
@@ -14,3 +14,11 @@ "use strict"; | ||
const misc_1 = require("../../../utils/misc"); | ||
/** | ||
* Exporter created to be used in automated runs. | ||
*/ | ||
class LocalExporter { | ||
/** | ||
* Exports octopus assets into given or system TempDir | ||
* @constructor | ||
* @param {DebugExporterOptions} [options] | ||
*/ | ||
constructor(options) { | ||
@@ -24,3 +32,3 @@ this._outputDir = this._initTempDir(options); | ||
const dir = typeof options.path === 'string' ? options.path : tempFallback; | ||
await (0, files_1.makeDir)(path_1.default.join(dir, exporter_1.IMAGES_DIR_NAME)); | ||
await (0, files_1.makeDir)(path_1.default.join(dir, LocalExporter.IMAGES_DIR_NAME)); | ||
return dir; | ||
@@ -43,21 +51,43 @@ } | ||
} | ||
/** | ||
* Exports given design raw data. | ||
* @param {RawDesign} raw Design raw data | ||
* @returns {Promise<string>} returns path to the exported RawDesign | ||
*/ | ||
async exportRawDesign(raw) { | ||
const rawPath = (0, exporter_1.getSourceFileName)('design'); | ||
const rawPath = LocalExporter.getSourceFileName('design'); | ||
await this._save(rawPath, (0, misc_1.stringify)(raw)); | ||
return rawPath; | ||
} | ||
/** | ||
* Exports raw data of given Component. | ||
* @param {RawLayerFrame} raw Component raw data | ||
* @param {string} name Name of given Component | ||
* @returns {Promise<string>} returns path to the exported RawComponent | ||
*/ | ||
async exportRawComponent(raw, name) { | ||
const rawPath = (0, exporter_1.getSourceFileName)(name); | ||
const rawPath = LocalExporter.getSourceFileName(name); | ||
await this._save(rawPath, (0, misc_1.stringify)(raw)); | ||
return rawPath; | ||
} | ||
/** | ||
* Exports raw data of given chunk. | ||
* @param {ResolvedStyle} raw Chunk raw data | ||
* @param {string} name Name of given Chunk | ||
* @returns {Promise<string>} returns path to the exported RawChunk | ||
*/ | ||
async exportRawChunk(raw, name) { | ||
const rawPath = (0, exporter_1.getSourceFileName)(name); | ||
const rawPath = LocalExporter.getSourceFileName(name); | ||
await this._save(rawPath, (0, misc_1.stringify)(raw)); | ||
return rawPath; | ||
} | ||
/** | ||
* Exports given OctopusComponent | ||
* @param {ComponentConversionResult} result contains converted OctopusComponent or Error if conversion failed | ||
* @returns {Promise<string | null>} returns path to the exported OctopusComponent or `null` if conversion failed | ||
*/ | ||
async exportComponent(result) { | ||
if (!result.value) | ||
return null; | ||
const path = (0, exporter_1.getOctopusFileName)(result.id); | ||
const path = LocalExporter.getOctopusFileName(result.id); | ||
await this._save(path, (0, misc_1.stringify)(result.value)); | ||
@@ -67,4 +97,10 @@ return path; | ||
getImagePath(name) { | ||
return path_1.default.join(exporter_1.IMAGES_DIR_NAME, `${name}${exporter_1.IMAGE_EXTNAME}`); | ||
return path_1.default.join(LocalExporter.IMAGES_DIR_NAME, `${name}${exporter_1.IMAGE_EXTNAME}`); | ||
} | ||
/** | ||
* Exports given Image into folder specified in `LocalExporter.IMAGES_DIR_NAME` | ||
* @param {string} name Name of the exported Image | ||
* @param {ArrayBuffer} data Image data represented as buffer of binary data | ||
* @returns {Promise<string>} returns path to the exported Image | ||
*/ | ||
async exportImage(name, data) { | ||
@@ -75,14 +111,27 @@ const imagePath = this.getImagePath(name); | ||
} | ||
// getPreviewPath(id: string): string { | ||
// return getPreviewPath(id) | ||
// } | ||
/** | ||
* Exports given Image Preview into folder specified in `LocalExporter.getPreviewFileName()` | ||
* @param {string} id ID of the exported Image | ||
* @param {ArrayBuffer} data Image data represented as buffer of binary data | ||
* @returns {Promise<string>} returns path to the exported Image Preview | ||
*/ | ||
async exportPreview(id, data) { | ||
const previewPath = (0, exporter_1.getPreviewFileName)(id); | ||
const previewPath = LocalExporter.getPreviewFileName(id); | ||
await this._save(previewPath, Buffer.from(data)); | ||
return previewPath; | ||
} | ||
/** | ||
* Exports given converted OctopusManifest. | ||
* @param {Manifest['OctopusManifest']} manifest Given converted OctopusManifest data object. | ||
* @returns {Promise<string>} returns path to the OctopusManifest | ||
*/ | ||
async exportManifest(manifest) { | ||
return this._save(exporter_1.MANIFEST_FILE_NAME, (0, misc_1.stringify)(manifest)); | ||
return this._save(LocalExporter.MANIFEST_NAME, (0, misc_1.stringify)(manifest)); | ||
} | ||
} | ||
exports.LocalExporter = LocalExporter; | ||
LocalExporter.IMAGES_DIR_NAME = exporter_1.IMAGES_DIR_NAME; | ||
LocalExporter.MANIFEST_NAME = exporter_1.MANIFEST_NAME; | ||
LocalExporter.getSourceFileName = exporter_1.getSourceFileName; | ||
LocalExporter.getOctopusFileName = exporter_1.getOctopusFileName; | ||
LocalExporter.getPreviewFileName = exporter_1.getPreviewFileName; |
@@ -5,2 +5,3 @@ import type { Logger } from '@opendesign/figma-parser/lib/src/services/logger/logger'; | ||
export declare type SourceApiReaderOptions = { | ||
/** Figma design HASH ID */ | ||
designId: string; | ||
@@ -25,10 +26,28 @@ host: string; | ||
}; | ||
/** | ||
* Reader that downloads given design from Figma API and provide them through `EventEmitter` calls. | ||
*/ | ||
export declare class SourceApiReader { | ||
private _options; | ||
private _parser; | ||
/** | ||
* Downloads given Figma design and provide them through `EventEmitter` calls. | ||
* @constructor | ||
* @param {SourceApiReaderOptions} options | ||
*/ | ||
constructor(options: SourceApiReaderOptions); | ||
/** | ||
* Figma design hash. | ||
* Can be found in the URL of the design: `https://www.figma.com/file/__DESIGN_HASH__` | ||
* @returns {string} returns Figma design hash | ||
*/ | ||
get designId(): string; | ||
get getFileMeta(): Promise<import("@opendesign/figma-parser/lib/src/entities/structural/file").FileMeta>; | ||
/** | ||
* Returns `EventEmitter` which is needed in OctopusFigConverter. | ||
* @param {string[]} [ids] Optional IDs of wanted artboards. If not provided, whole design will be parsed. | ||
* @returns {EventEmitter} returns `EventEmitter` providing source data to the OctopusFigConverter | ||
*/ | ||
parse(ids?: string[]): EventEmitter; | ||
private _initParser; | ||
} |
@@ -5,3 +5,11 @@ "use strict"; | ||
const figma_parser_1 = require("@opendesign/figma-parser"); | ||
/** | ||
* Reader that downloads given design from Figma API and provide them through `EventEmitter` calls. | ||
*/ | ||
class SourceApiReader { | ||
/** | ||
* Downloads given Figma design and provide them through `EventEmitter` calls. | ||
* @constructor | ||
* @param {SourceApiReaderOptions} options | ||
*/ | ||
constructor(options) { | ||
@@ -11,2 +19,7 @@ this._options = options; | ||
} | ||
/** | ||
* Figma design hash. | ||
* Can be found in the URL of the design: `https://www.figma.com/file/__DESIGN_HASH__` | ||
* @returns {string} returns Figma design hash | ||
*/ | ||
get designId() { | ||
@@ -18,2 +31,7 @@ return this._options.designId; | ||
} | ||
/** | ||
* Returns `EventEmitter` which is needed in OctopusFigConverter. | ||
* @param {string[]} [ids] Optional IDs of wanted artboards. If not provided, whole design will be parsed. | ||
* @returns {EventEmitter} returns `EventEmitter` providing source data to the OctopusFigConverter | ||
*/ | ||
parse(ids) { | ||
@@ -20,0 +38,0 @@ return this._parser.parse(ids); |
export declare const IMAGES_DIR_NAME = "images"; | ||
export declare const IMAGE_EXTNAME = ".png"; | ||
export declare const MANIFEST_FILE_NAME = "octopus-manifest.json"; | ||
export declare const MANIFEST_NAME = "octopus-manifest.json"; | ||
export declare function getOctopusFileName(id: string): string; | ||
export declare function getPreviewFileName(id: string): string; | ||
export declare function getSourceFileName(id: string): string; |
@@ -6,7 +6,7 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getSourceFileName = exports.getPreviewFileName = exports.getOctopusFileName = exports.MANIFEST_FILE_NAME = exports.IMAGE_EXTNAME = exports.IMAGES_DIR_NAME = void 0; | ||
exports.getSourceFileName = exports.getPreviewFileName = exports.getOctopusFileName = exports.MANIFEST_NAME = exports.IMAGE_EXTNAME = exports.IMAGES_DIR_NAME = void 0; | ||
const kebabCase_1 = __importDefault(require("lodash/kebabCase")); | ||
exports.IMAGES_DIR_NAME = 'images'; | ||
exports.IMAGE_EXTNAME = '.png'; | ||
exports.MANIFEST_FILE_NAME = 'octopus-manifest.json'; | ||
exports.MANIFEST_NAME = 'octopus-manifest.json'; | ||
function getOctopusFileName(id) { | ||
@@ -13,0 +13,0 @@ return `${(0, kebabCase_1.default)(id)}-octopus.json`; |
{ | ||
"name": "@opendesign/octopus-fig", | ||
"version": "3.0.0-rc.18", | ||
"version": "3.0.0-rc.19", | ||
"description": "Figma HTTP API format to Octopus 3+ converter.", | ||
@@ -22,2 +22,3 @@ "license": "Apache-2.0", | ||
"types:check": "tsc --noEmit", | ||
"typedoc": "typedoc --excludePrivate src/index-node.ts src/index-web.ts", | ||
"watch": "tsc -w" | ||
@@ -27,5 +28,5 @@ }, | ||
"@opendesign/figma-parser": "3.0.0-rc.13", | ||
"@opendesign/manifest-ts": "3.0.0-alpha.38", | ||
"@opendesign/manifest-ts": "3.0.0-alpha.40", | ||
"@opendesign/octopus-common": "3.0.0-rc.27", | ||
"@opendesign/octopus-ts": "3.0.0-alpha.38", | ||
"@opendesign/octopus-ts": "3.0.0-alpha.40", | ||
"@types/lodash": "^4.14.178", | ||
@@ -54,2 +55,3 @@ "@types/pino": "^6.3.3", | ||
"ts-node": "10.8.0", | ||
"typedoc": "^0.23.18", | ||
"typescript": "4.6.4" | ||
@@ -56,0 +58,0 @@ }, |
@@ -20,2 +20,35 @@ # Octopus Converter for Figma | ||
--- | ||
## Usage | ||
There are three main processing steps: | ||
- reading source data (using _readers_) | ||
- conversion (using _converter_ with `EventEmitter` instance produced by reader) | ||
- exporting (using _exporters_) | ||
Readers used in other Octopus converters return `SourceDesign` instance, which, actually, is object with static values inside. In case of Figma, we have slightly different approach because of it's asynchronous origin (requesting values using HTTP). So, to provide source data as fast as possible to the converter we use `EventEmitter` inside of Figma Reader's `SourceDesign` instance. This makes it possible to process data almost as fast as it's downloaded from Figma's API. | ||
Although you can define the way of reading assets or exporting results yourself (create your own reader/exporter class), you can also choose between existing ones: | ||
Check [`examples/node/convert-api-local.ts`](./examples/node/convert-api-local.ts) for example usage in automated runs. | ||
Check [`examples/node/convert-api-debug.ts`](./examples/node/convert-api-debug.ts) for example usage in custom manual runs. | ||
Check [`examples/web/`](./examples/web/) for more details about usage in web browser. | ||
Check [`src/services/exporters/`](./src/services/exporters/) for more details about exporters. | ||
Check [`src/services/readers/`](./src/services/readers/) for more details about readers | ||
--- | ||
## Demo: Example Node | ||
Converts your Figma designs from API into Octopus3+ format. | ||
Before you start you need to add [your Figma API token](https://www.figma.com/developers/api#access-tokens) into `.env` file. | ||
Then you need to find `FIGMA_DESIGN_HASH` for the design you want to convert. | ||
You can find it in the URL of the design: `https://www.figma.com/file/__HERE__/...` | ||
#### .env demo variables | ||
@@ -33,11 +66,2 @@ | ||
--- | ||
## Demo: Example Node | ||
Converts your Figma designs from API into Octopus3+ format. | ||
Before you start you need to add [your Figma API token](https://www.figma.com/developers/api#access-tokens) into `.env` file. | ||
Then you need to find `FIGMA_DESIGN_HASH` for the design you want to convert. | ||
You can find it in the URL of the design: `https://www.figma.com/file/__HERE__/...` | ||
### yarn convert:debug | ||
@@ -70,24 +94,6 @@ | ||
## Usage | ||
## TypeDoc | ||
There are three main processing steps: | ||
Command `yarn typedoc` will generate TypeDoc documentation for public Classes into `./docs` folder | ||
- reading source data (using _readers_) | ||
- conversion (using _converter_ with `DesignEmitter` instance produced by reader) | ||
- exporting (using _exporters_) | ||
Readers in other convertors returns `SourceDesign`. But for `octopus-fig` we introduce different approach. Here we are requesting the Figma API for the data. So to make parsing quicker, instead of complete SourceDesign, we are returning `DesignEmitter`, which emits the requested data when he receives them from the Figma API. | ||
Although you can define the way of reading assets or exporting results yourself (create your own reader/exporter class), you can also choose between existing ones: | ||
Check [`examples/node/convert-api-local.ts`](./examples/node/convert-api-local.ts) for example usage in automated runs. | ||
Check [`examples/node/convert-api-debug.ts`](./examples/node/convert-api-debug.ts) for example usage in custom manual runs. | ||
Check [`examples/web/`](./examples/web/) for more details about usage in web browser. | ||
Check [`src/services/exporters/`](./src/services/exporters/) for more details about exporters. | ||
Check [`src/services/readers/`](./src/services/readers/) for more details about readers | ||
--- | ||
@@ -94,0 +100,0 @@ |
223160
5011
122
13
+ Added@opendesign/manifest-ts@3.0.0-alpha.40(transitive)
+ Added@opendesign/octopus-ts@3.0.0-alpha.40(transitive)
- Removed@opendesign/manifest-ts@3.0.0-alpha.38(transitive)
- Removed@opendesign/octopus-ts@3.0.0-alpha.38(transitive)