diff --git a/README.md b/README.md index 8bd3f05..3ebe9a0 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ require('dotenv').config() * @type {import('penpot-css-export').Config} */ const config = { + instance: process.env.PENPOT_BASE_URL || undefined, accessToken: process.env.PENPOT_ACCESS_TOKEN, pages: [ { diff --git a/packages/demo/penpot-css-export.config.js b/packages/demo/penpot-css-export.config.js index 1539c46..8ba5d81 100644 --- a/packages/demo/penpot-css-export.config.js +++ b/packages/demo/penpot-css-export.config.js @@ -4,6 +4,7 @@ require('dotenv').config() * @type {import('penpot-css-export').Config} */ const config = { + instance: process.env.PENPOT_BASE_URL || undefined, accessToken: process.env.PENPOT_ACCESS_TOKEN, colors: [ { diff --git a/packages/penpot-css-export/src/lib/api/penpot.ts b/packages/penpot-css-export/src/lib/api/penpot.ts index d76a8b4..60ab4cc 100644 --- a/packages/penpot-css-export/src/lib/api/penpot.ts +++ b/packages/penpot-css-export/src/lib/api/penpot.ts @@ -33,9 +33,11 @@ class PenpotApiUnknownError extends Error { } export class Penpot { + private instanceBaseUrl: string private accessToken: string constructor(settings: PenpotSettings) { + this.instanceBaseUrl = settings.baseUrl this.accessToken = settings.accessToken } @@ -54,7 +56,7 @@ export class Penpot { } const response = await fetch( - `https://design.penpot.app/api/rpc/command/${command}`, + `${this.instanceBaseUrl}/api/rpc/command/${command}`, config, ) diff --git a/packages/penpot-css-export/src/lib/api/types.ts b/packages/penpot-css-export/src/lib/api/types.ts index 3f72925..3176621 100644 --- a/packages/penpot-css-export/src/lib/api/types.ts +++ b/packages/penpot-css-export/src/lib/api/types.ts @@ -1,4 +1,5 @@ export interface PenpotSettings { + baseUrl: string accessToken: string } diff --git a/packages/penpot-css-export/src/lib/config.ts b/packages/penpot-css-export/src/lib/config.ts index 50bd3b6..afd4a2d 100644 --- a/packages/penpot-css-export/src/lib/config.ts +++ b/packages/penpot-css-export/src/lib/config.ts @@ -1,6 +1,7 @@ import { Config, PagesConfig } from './types' const BASE_CONFIG: Omit = { + instance: 'https://design.penpot.app', accessToken: '', } @@ -16,6 +17,12 @@ class MissingAccessTokenError extends Error { } } +class InvalidInstanceUrlError extends Error { + constructor() { + super('Invalid .instance URL in penpot export config.') + } +} + class MissingOutputPathError extends Error { constructor(index: number) { super(`Missing or empty .path in penpot export config at index ${index}.`) @@ -47,6 +54,22 @@ export function validateAndNormalizePenpotExportConfig(config: Config): Config { colors: [], } + if (config.instance != null) { + try { + new URL(config.instance) + } catch (error) { + if (error instanceof TypeError) { + throw new InvalidInstanceUrlError() + } + + throw error + } + + normalizedConfig.instance = config.instance.endsWith('/') + ? config.instance.slice(0, -1) + : config.instance + } + for (const [index, colorsConfig] of config.colors.entries()) { const { output, fileId } = colorsConfig diff --git a/packages/penpot-css-export/src/lib/index.ts b/packages/penpot-css-export/src/lib/index.ts index c99af49..043810a 100644 --- a/packages/penpot-css-export/src/lib/index.ts +++ b/packages/penpot-css-export/src/lib/index.ts @@ -13,7 +13,10 @@ export async function generateCssFromConfig( rootProjectPath: string, ) { const validatedConfig = validateAndNormalizePenpotExportConfig(config) - const penpot = new Penpot({ accessToken: config.accessToken }) + const penpot = new Penpot({ + baseUrl: validatedConfig.instance, + accessToken: validatedConfig.accessToken, + }) for (const colorsConfig of validatedConfig.colors) { const cssClassDefinition: CSSClassDefinition = { diff --git a/packages/penpot-css-export/src/lib/types.ts b/packages/penpot-css-export/src/lib/types.ts index 01c97eb..daed47c 100644 --- a/packages/penpot-css-export/src/lib/types.ts +++ b/packages/penpot-css-export/src/lib/types.ts @@ -15,6 +15,7 @@ export interface ColorsConfig { } export interface Config { + instance: string accessToken: string colors: ColorsConfig[] typographies: TypographiesConfig[]