From 66f0b48fa4c23ef5547de6656437f2338a6447b2 Mon Sep 17 00:00:00 2001 From: Roberto Redradix Date: Thu, 31 Aug 2023 21:23:22 +0200 Subject: [PATCH] refactor(cli): difference API and internal types Take the opportunity to merge PentpotApiPage and PenpotApiObject into PenpotApiContainer to follow more closely the Penpot data model --- .../penpot-css-export/src/lib/api/helpers.ts | 14 +++---- .../penpot-css-export/src/lib/api/penpot.ts | 36 ++++++++---------- .../penpot-css-export/src/lib/api/types.ts | 30 +++++++-------- .../penpot-css-export/src/lib/config/index.ts | 3 +- .../penpot-css-export/src/lib/config/types.ts | 25 ++++++++++++ .../src/lib/config/validator.ts | 18 ++------- packages/penpot-css-export/src/lib/index.ts | 3 +- packages/penpot-css-export/src/lib/types.ts | 38 ++++++++----------- 8 files changed, 85 insertions(+), 82 deletions(-) create mode 100644 packages/penpot-css-export/src/lib/config/types.ts diff --git a/packages/penpot-css-export/src/lib/api/helpers.ts b/packages/penpot-css-export/src/lib/api/helpers.ts index fdc84f0..2311a5d 100644 --- a/packages/penpot-css-export/src/lib/api/helpers.ts +++ b/packages/penpot-css-export/src/lib/api/helpers.ts @@ -1,14 +1,14 @@ -import { PenpotComponent, PenpotObject, PenpotPage } from './types' +import { PenpotApiComponent, PenpotApiObject, PenpotApiPage } from './types' -export function isComponent(object: PenpotObject) { +export function isComponent(object: PenpotApiObject) { return object.componentRoot === true } export function getObjectShapesFromPage( - object: PenpotObject, - page: PenpotPage, -): PenpotComponent { - const objects: PenpotObject[] = [] + object: PenpotApiObject, + page: PenpotApiPage, +): PenpotApiComponent { + const objects: Record = {} const shapes = object.shapes || [] shapes?.forEach((shapeId) => { @@ -19,7 +19,7 @@ export function getObjectShapesFromPage( return } - objects.push(object) + objects[object.id] = object }) return { ...object, objects } diff --git a/packages/penpot-css-export/src/lib/api/penpot.ts b/packages/penpot-css-export/src/lib/api/penpot.ts index a48b863..4c47c18 100644 --- a/packages/penpot-css-export/src/lib/api/penpot.ts +++ b/packages/penpot-css-export/src/lib/api/penpot.ts @@ -1,16 +1,15 @@ import fetch, { RequestInit } from 'node-fetch' import { pickObjectProps } from './helpers' import type { - PenpotObject, - PenpotPage, - PenpotSettings, - FetcherOptions, PenpotApiErrorResponse, - PenpotTypography, - PenpotGetFileOptions, - PenpotFile, - PenpotColor, + PenpotApiFile, + PenpotApiObject, + PenpotApiTypography, + PenpotClientFetcherOptions, + PenpotClientGetFileOptions, + PenpotClientSettings, } from './types' +import { PenpotExportFile } from '../types' class PenpotApiError extends Error { constructor(parsedError: PenpotApiErrorResponse) { @@ -30,13 +29,13 @@ export class Penpot { private instanceBaseUrl: string private accessToken: string - constructor(settings: PenpotSettings) { + constructor(settings: PenpotClientSettings) { this.instanceBaseUrl = settings.baseUrl this.accessToken = settings.accessToken } private async fetcher( - options: FetcherOptions, + options: PenpotClientFetcherOptions, ): Promise { const { command, body } = options const config: RequestInit = { @@ -69,7 +68,7 @@ export class Penpot { return json as ResultType } - static extractObjectCssProps(object: PenpotObject) { + static extractObjectCssProps(object: PenpotApiObject) { let { textDecoration, ...styles } = object.positionData[0] const isTextObject = object.type === 'text' @@ -82,7 +81,7 @@ export class Penpot { return styles } - static getTextObjectCssProps(object: PenpotObject) { + static getTextObjectCssProps(object: PenpotApiObject) { const textCssProps = [ 'fontStyle', 'fontSize', @@ -95,13 +94,10 @@ export class Penpot { return pickObjectProps(objectCssProps, textCssProps) } - async getFile(options: PenpotGetFileOptions): Promise<{ - fileName: string - colors: Record - typographies: Record - pages: Record - }> { - const file = await this.fetcher({ + async getFile( + options: PenpotClientGetFileOptions, + ): Promise { + const file = await this.fetcher({ command: 'get-file', body: { id: options.fileId, @@ -116,7 +112,7 @@ export class Penpot { } } - static getTypographyAssetCssProps(typography: PenpotTypography) { + static getTypographyAssetCssProps(typography: PenpotApiTypography) { const textCssProps = [ 'lineHeight', 'fontStyle', diff --git a/packages/penpot-css-export/src/lib/api/types.ts b/packages/penpot-css-export/src/lib/api/types.ts index 079019a..82c32f1 100644 --- a/packages/penpot-css-export/src/lib/api/types.ts +++ b/packages/penpot-css-export/src/lib/api/types.ts @@ -1,18 +1,18 @@ -export interface PenpotSettings { +export interface PenpotClientSettings { baseUrl: string accessToken: string } -export interface FetcherOptions { +export interface PenpotClientFetcherOptions { command: string body: Record } -export interface PenpotGetFileOptions { +export interface PenpotClientGetFileOptions { fileId: string } -export interface PenpotObject { +export interface PenpotApiObject { id: string name: string type: 'text' @@ -21,14 +21,14 @@ export interface PenpotObject { shapes?: string[] } -type PenpotAsset = { +type PenpotApiAsset = { id: string name: string modifiedAt: string path: string } -export interface PenpotColor extends PenpotAsset { +export interface PenpotApiColor extends PenpotApiAsset { color: string opacity: number } @@ -42,18 +42,20 @@ type CssTextProperty = | 'letterSpacing' | 'fontFamily' -export type PenpotTypography = PenpotAsset & { +export type PenpotApiTypography = PenpotApiAsset & { fontId: string fontVariantId: string } & Record -export interface PenpotPage { +interface PenpotApiContainer { id: string name: string - objects: Record + objects: Record } +export type PenpotApiPage = PenpotApiContainer +export type PenpotApiComponent = PenpotApiContainer -export interface PenpotFile { +export interface PenpotApiFile { id: string name: string revn: number @@ -61,9 +63,9 @@ export interface PenpotFile { data: { id: string version: number - colors?: Record - typographies?: Record - pagesIndex?: Record + colors?: Record + typographies?: Record + pagesIndex?: Record } } @@ -71,5 +73,3 @@ export interface PenpotApiErrorResponse { type: string code: string } - -export type PenpotComponent = PenpotObject & { objects: PenpotObject[] } diff --git a/packages/penpot-css-export/src/lib/config/index.ts b/packages/penpot-css-export/src/lib/config/index.ts index 318a6d0..d90d35b 100644 --- a/packages/penpot-css-export/src/lib/config/index.ts +++ b/packages/penpot-css-export/src/lib/config/index.ts @@ -1,5 +1,6 @@ -import { Config, UserConfig, FileConfig, UserFileConfig } from '../types' +import { UserConfig, UserFileConfig } from '../types' +import { Config, FileConfig } from './types' export { validateUserConfig } from './validator' function normalizePenpotExportUserFileConfig( diff --git a/packages/penpot-css-export/src/lib/config/types.ts b/packages/penpot-css-export/src/lib/config/types.ts new file mode 100644 index 0000000..94ea3c2 --- /dev/null +++ b/packages/penpot-css-export/src/lib/config/types.ts @@ -0,0 +1,25 @@ +export interface PagesConfig { + output: string + pageId: string +} + +export interface TypographiesConfig { + output: string +} + +export interface ColorsConfig { + output: string +} + +export interface FileConfig { + fileId: string + colors: ColorsConfig[] + typographies: TypographiesConfig[] + pages: PagesConfig[] +} + +export interface Config { + instance: string + accessToken: string + files: FileConfig[] +} diff --git a/packages/penpot-css-export/src/lib/config/validator.ts b/packages/penpot-css-export/src/lib/config/validator.ts index a5368e7..c461368 100644 --- a/packages/penpot-css-export/src/lib/config/validator.ts +++ b/packages/penpot-css-export/src/lib/config/validator.ts @@ -1,4 +1,6 @@ -import { PagesConfig, ColorsConfig, TypographiesConfig } from '../types' +import { UserFileConfig, UserConfig } from '../types' + +import { PagesConfig, ColorsConfig, TypographiesConfig } from './types' class FileIdConfigError extends Error { constructor() { @@ -26,20 +28,6 @@ class PageIdConfigError extends Error { } } -export type UserFileConfig = { - fileId: string -} & ( - | { colors: ColorsConfig[] } - | { typographies: TypographiesConfig[] } - | { pages: PagesConfig[] } -) - -export interface UserConfig { - instance?: string - accessToken: string - files: UserFileConfig[] -} - function validateUserColorsConfig( colorsConfig: object, index: number, diff --git a/packages/penpot-css-export/src/lib/index.ts b/packages/penpot-css-export/src/lib/index.ts index 3a040ac..5ada011 100644 --- a/packages/penpot-css-export/src/lib/index.ts +++ b/packages/penpot-css-export/src/lib/index.ts @@ -83,7 +83,8 @@ export async function generateCssFromConfig( .map((object) => getObjectShapesFromPage(object, page)) for (const component of components) { - for (const object of component.objects) { + for (const objectId in component.objects) { + const object = component.objects[objectId] if (object.type === 'text') { const cssProps = Penpot.getTextObjectCssProps(object) const selector = textToCssClassSelector( diff --git a/packages/penpot-css-export/src/lib/types.ts b/packages/penpot-css-export/src/lib/types.ts index 5f94039..a26ee10 100644 --- a/packages/penpot-css-export/src/lib/types.ts +++ b/packages/penpot-css-export/src/lib/types.ts @@ -1,15 +1,13 @@ -export interface PagesConfig { - output: string - pageId: string -} - -export interface TypographiesConfig { - output: string -} - -export interface ColorsConfig { - output: string -} +import type { + PenpotApiPage, + PenpotApiTypography, + PenpotApiColor, +} from './api/types' +import type { + ColorsConfig, + PagesConfig, + TypographiesConfig, +} from './config/types' export type UserFileConfig = { fileId: string @@ -25,17 +23,11 @@ export interface UserConfig { files: UserFileConfig[] } -export interface FileConfig { - fileId: string - colors: ColorsConfig[] - typographies: TypographiesConfig[] - pages: PagesConfig[] -} - -export interface Config { - instance: string - accessToken: string - files: FileConfig[] +export interface PenpotExportFile { + fileName: string + colors: Record + typographies: Record + pages: Record } export interface CSSClassDefinition {