From ee9739b20bc5f9a90cbc740b9531834a20489656 Mon Sep 17 00:00:00 2001 From: Nikita Nigmatullin Date: Tue, 22 Jun 2021 21:30:46 +0300 Subject: [PATCH 1/5] feat: file system related things are run only on node env --- src/core/yaml-interop.ts | 26 +- src/vendors/style-dictionary/lib/buildFile.js | 6 +- src/vendors/style-dictionary/lib/cleanDir.js | 5 +- src/vendors/style-dictionary/lib/cleanFile.js | 6 +- .../style-dictionary/lib/common/actions.js | 6 +- .../style-dictionary/lib/common/formats.js | 335 ------------------ src/vendors/style-dictionary/lib/extend.js | 57 +-- .../style-dictionary/lib/utils/combineJSON.js | 5 +- 8 files changed, 50 insertions(+), 396 deletions(-) diff --git a/src/core/yaml-interop.ts b/src/core/yaml-interop.ts index 1da1e86..c5fb8a5 100644 --- a/src/core/yaml-interop.ts +++ b/src/core/yaml-interop.ts @@ -25,16 +25,18 @@ class YamlParseError extends Error { /** * Patched native `require` for importing module with `yaml` extensions. */ -Module.prototype.require = new Proxy(Module.prototype.require, { - apply(target, thisArg, args) { - if (/\.ya?ml$/.test(args[0])) { - const file = readFileSync(args[0], 'utf8') - try { - return YAML.parse(file, { prettyErrors: true }) - } catch (error) { - throw new YamlParseError(args[0], file, error.message, error.linePos) +if (typeof window === 'undefined') { + Module.prototype.require = new Proxy(Module.prototype.require, { + apply(target, thisArg, args) { + if (/\.ya?ml$/.test(args[0])) { + const file = readFileSync(args[0], 'utf8') + try { + return YAML.parse(file, { prettyErrors: true }) + } catch (error) { + throw new YamlParseError(args[0], file, error.message, error.linePos) + } } - } - return Reflect.apply(target, thisArg, args) - }, -}) + return Reflect.apply(target, thisArg, args) + }, + }) +} diff --git a/src/vendors/style-dictionary/lib/buildFile.js b/src/vendors/style-dictionary/lib/buildFile.js index 364073c..795c344 100644 --- a/src/vendors/style-dictionary/lib/buildFile.js +++ b/src/vendors/style-dictionary/lib/buildFile.js @@ -12,11 +12,15 @@ */ var path = require('path'), - fs = require('fs-extra'), chalk = require('chalk'), filterProperties = require('./filterProperties'), GroupMessages = require('./utils/groupMessages'); +let fs +if (typeof window === 'undefined') { + fs = require('fs-extra') +} + /** * Takes the style property object and a format and returns a * string that can be written to a file. diff --git a/src/vendors/style-dictionary/lib/cleanDir.js b/src/vendors/style-dictionary/lib/cleanDir.js index 5caf90c..59bde48 100644 --- a/src/vendors/style-dictionary/lib/cleanDir.js +++ b/src/vendors/style-dictionary/lib/cleanDir.js @@ -12,9 +12,12 @@ */ var path = require('path'), - fs = require('fs-extra'), chalk = require('chalk'); +let fs +if (typeof window === 'undefined') { + require('fs-extra') +} /** * Takes the style property object and a format and returns a diff --git a/src/vendors/style-dictionary/lib/cleanFile.js b/src/vendors/style-dictionary/lib/cleanFile.js index 4d4eeff..37989d2 100644 --- a/src/vendors/style-dictionary/lib/cleanFile.js +++ b/src/vendors/style-dictionary/lib/cleanFile.js @@ -12,10 +12,12 @@ */ var path = require('path'), - fs = require('fs-extra'), chalk = require('chalk'); - +let fs +if (typeof window === 'undefined') { + require('fs-extra') +} /** * Takes the style property object and a format and returns a * string that can be written to a file. diff --git a/src/vendors/style-dictionary/lib/common/actions.js b/src/vendors/style-dictionary/lib/common/actions.js index bde0763..76fac41 100644 --- a/src/vendors/style-dictionary/lib/common/actions.js +++ b/src/vendors/style-dictionary/lib/common/actions.js @@ -12,9 +12,13 @@ */ let _ = require('lodash') -let fs = require('fs-extra') let chalk = require('chalk') +let fs +if (typeof window === 'undefined') { + require('fs-extra') +} + /** * @namespace Actions */ diff --git a/src/vendors/style-dictionary/lib/common/formats.js b/src/vendors/style-dictionary/lib/common/formats.js index 1349136..4e6e439 100644 --- a/src/vendors/style-dictionary/lib/common/formats.js +++ b/src/vendors/style-dictionary/lib/common/formats.js @@ -11,7 +11,6 @@ * and limitations under the License. */ -let fs = require('fs') let _ = require('lodash') let GroupMessages = require('../utils/groupMessages') @@ -108,72 +107,6 @@ module.exports = { '\n}\n' }, - /** - * Creates a SCSS file with a flat map based on the style dictionary - * - * Name the map by adding a 'mapName' attribute on the file object in your config. - * - * @memberof Formats - * @kind member - * @example - * ```scss - * $tokens: ( - * 'color-background-base': #f0f0f0; - * 'color-background-alt': #eeeeee; - * ) - * ``` - */ - 'scss/map-flat': _.template( - fs.readFileSync(__dirname + '/templates/scss/map-flat.template') - ), - - // This will soon be removed, is left here only for backwards compatibility - 'sass/map-flat': function(dictionary, config) { - GroupMessages.add(SASS_MAP_FORMAT_DEPRECATION_WARNINGS, 'sass/map-flat') - const templateMapFlat = _.template(fs.readFileSync(__dirname + '/templates/scss/map-flat.template')) - return templateMapFlat({ - showFileHeader: config.showFileHeader, - allProperties: dictionary.allProperties - }) - }, - - /** - * Creates a SCSS file with a deep map based on the style dictionary. - * - * Name the map by adding a 'mapName' attribute on the file object in your config. - * - * @memberof Formats - * @kind member - * @example - * ```scss - * $color-background-base: #f0f0f0 !default; - * $color-background-alt: #eeeeee !default; - * - * $tokens: { - * 'color': ( - * 'background': ( - * 'base': $color-background-base, - * 'alt': $color-background-alt - * ) - * ) - * ) - * ``` - */ - 'scss/map-deep': _.template( - fs.readFileSync(__dirname + '/templates/scss/map-deep.template') - ), - - // This will soon be removed, is left here only for backwards compatibility - 'sass/map-deep': function(dictionary, config) { - GroupMessages.add(SASS_MAP_FORMAT_DEPRECATION_WARNINGS, 'sass/map-deep') - const templateMapDeep = _.template(fs.readFileSync(__dirname + '/templates/scss/map-deep.template')) - return templateMapDeep({ - showFileHeader: config.showFileHeader, - properties: dictionary.properties, - allProperties: dictionary.allProperties - }) - }, - /** * Creates a SCSS file with variable definitions based on the style dictionary * @@ -375,252 +308,6 @@ module.exports = { }).join('\n') }, - // Android templates - /** - * Creates a color resource xml file with all the colors in your style dictionary. - * - * @memberof Formats - * @kind member - * @example - * ```xml - * - * - * #fffaf3f2 - * #fff0cccc - * #ffe19d9c - * ``` - */ - 'android/colors': _.template( - fs.readFileSync(__dirname + '/templates/android/colors.template') - ), - - /** - * Creates a dimen resource xml file with all the sizes in your style dictionary. - * - * @memberof Formats - * @kind member - * @example - * ```xml - * - * - * 5.00dp - * 10.00dp - * 15.00dp - * ``` - */ - 'android/dimens': _.template( - fs.readFileSync(__dirname + '/templates/android/dimens.template') - ), - - /** - * Creates a dimen resource xml file with all the font sizes in your style dictionary. - * - * @memberof Formats - * @kind member - * @example - * ```xml - * - * - * 10.00sp - * 13.00sp - * 15.00sp - * ``` - */ - 'android/fontDimens': _.template( - fs.readFileSync(__dirname + '/templates/android/fontDimens.template') - ), - - /** - * Creates a resource xml file with all the integers in your style dictionary. It filters your - * style properties by `prop.attributes.category === 'time'` - * - * @memberof Formats - * @kind member - * @todo Update the filter on this. - * @example - * ```xml - * - * - * 1000 - * 2000 - * 4000 - * ``` - */ - 'android/integers': _.template( - fs.readFileSync(__dirname + '/templates/android/integers.template') - ), - - /** - * Creates a resource xml file with all the strings in your style dictionary. Filters your - * style properties by `prop.attributes.category === 'content'` - * - * @memberof Formats - * @kind member - * @example - * ```xml - * - * - * - * - * - * ``` - */ - 'android/strings': _.template( - fs.readFileSync(__dirname + '/templates/android/strings.template') - ), - - // iOS templates - /** - * Creates an Objective-C header file with macros for style properties - * - * @memberof Formats - * @kind member - * @example - * ```objectivec - * #import - * #import - * - * #define ColorFontLink [UIColor colorWithRed:0.00f green:0.47f blue:0.80f alpha:1.00f] - * #define SizeFontTiny 176.00f - * ``` - */ - 'ios/macros': _.template( - fs.readFileSync(__dirname + '/templates/ios/macros.template') - ), - - /** - * Creates an Objective-C plist file - * - * @memberof Formats - * @kind member - * @todo Fix this template and add example and usage - */ - 'ios/plist': _.template( - fs.readFileSync(__dirname + '/templates/ios/plist.template') - ), - - /** - * Creates an Objective-C implementation file of a style dictionary singleton class - * - * @memberof Formats - * @kind member - * @todo Add example and usage - */ - 'ios/singleton.m': _.template( - fs.readFileSync(__dirname + '/templates/ios/singleton.m.template') - ), - - /** - * Creates an Objective-C header file of a style dictionary singleton class - * - * @memberof Formats - * @kind member - * @todo Add example and usage - */ - 'ios/singleton.h': _.template( - fs.readFileSync(__dirname + '/templates/ios/singleton.h.template') - ), - - /** - * Creates an Objective-C header file of a static style dictionary class - * - * @memberof Formats - * @kind member - * @todo Add example and usage - */ - 'ios/static.h': _.template( - fs.readFileSync(__dirname + '/templates/ios/static.h.template') - ), - - /** - * Creates an Objective-C implementation file of a static style dictionary class - * - * @memberof Formats - * @kind member - * @todo Add example and usage - */ - 'ios/static.m': _.template( - fs.readFileSync(__dirname + '/templates/ios/static.m.template') - ), - - /** - * Creates an Objective-C header file of a color class - * - * @memberof Formats - * @kind member - * @todo Add example and usage - */ - 'ios/colors.h': _.template( - fs.readFileSync(__dirname + '/templates/ios/colors.h.template') - ), - - /** - * Creates an Objective-C implementation file of a color class - * - * @memberof Formats - * @kind member - * @todo Add example and usage - */ - 'ios/colors.m': _.template( - fs.readFileSync(__dirname + '/templates/ios/colors.m.template') - ), - - /** - * Creates an Objective-C header file of strings - * - * @memberof Formats - * @kind member - * @todo Add example and usage - */ - 'ios/strings.h': _.template( - fs.readFileSync(__dirname + '/templates/ios/strings.h.template') - ), - - /** - * Creates an Objective-C implementation file of strings - * - * @memberof Formats - * @kind member - * @todo Add example and usage - */ - 'ios/strings.m': _.template( - fs.readFileSync(__dirname + '/templates/ios/strings.m.template') - ), - - /** - * Creates a Swift implementation file of a class with values - * - * @memberof Formats - * @kind member - * @todo Add example and usage - */ - 'ios-swift/class.swift': _.template( - fs.readFileSync(__dirname + '/templates/ios-swift/class.swift.template') - ), - - /** - * Creates a Swift implementation file of an enum with values - * - * @memberof Formats - * @kind member - * @todo Add example and usage - */ - 'ios-swift/enum.swift': _.template( - fs.readFileSync(__dirname + '/templates/ios-swift/enum.swift.template') - ), - // Css templates - - /** - * Creates CSS file with @font-face declarations - * - * @memberof Formats - * @kind member - * @todo Add example and usage - */ - 'css/fonts.css': _.template( - fs.readFileSync(__dirname + '/templates/css/fonts.css.template') - ), - // Web templates /** @@ -772,26 +459,4 @@ module.exports = { } return JSON.stringify(to_ret, null, 2) }, - - // Flutter templates - /** - * Creates a Dart implementation file of a class with values - * - * @memberof Formats - * @kind member - * @example - * ```dart - * import 'package:flutter/material.dart'; - * - * class StyleDictionary { - * StyleDictionary._(); - * - * static const colorBrandPrimary = Color(0x00ff5fff); - * static const sizeFontSizeMedium = 16.00; - * static const contentFontFamily1 = "NewJune"; - * ``` - */ - 'flutter/class.dart': _.template( - fs.readFileSync(__dirname + '/templates/flutter/class.dart.template') - ), } diff --git a/src/vendors/style-dictionary/lib/extend.js b/src/vendors/style-dictionary/lib/extend.js index 2829014..81b5f23 100644 --- a/src/vendors/style-dictionary/lib/extend.js +++ b/src/vendors/style-dictionary/lib/extend.js @@ -11,16 +11,13 @@ * and limitations under the License. */ -require('json5/lib/register'); +if (typeof window === 'undefined') { + require('json5/lib/register') +} var combineJSON = require('./utils/combineJSON'), deepExtend = require('./utils/deepExtend'), - resolveCwd = require('resolve-cwd'), - _ = require('lodash'), - chalk = require('chalk'), - GroupMessages = require('./utils/groupMessages'); - -var PROPERTY_VALUE_COLLISIONS = GroupMessages.GROUP.PropertyValueCollisions; + _ = require('lodash'); /** * Either a string to a JSON file that contains configuration for the style dictionary or a plain Javascript object @@ -60,13 +57,10 @@ var PROPERTY_VALUE_COLLISIONS = GroupMessages.GROUP.PropertyValueCollisions; * Create a Style Dictionary * @static * @memberof module:style-dictionary - * @param {Config} config - Configuration options to build your style dictionary. If you pass a string, - * it will be used as a path to a JSON config file. You can also pass an object with the configuration. + * @param {Config} config - Configuration options to build your style dictionary. Pass an object with the configuration. * @returns {module:style-dictionary} * @example * ```js - * const StyleDictionary = require('style-dictionary').extend('config.json'); - * * const StyleDictionary = require('style-dictionary').extend({ * source: ['properties/*.json'], * platforms: { @@ -86,13 +80,7 @@ var PROPERTY_VALUE_COLLISIONS = GroupMessages.GROUP.PropertyValueCollisions; function extend(opts) { var options, to_ret; - // Overloaded method, can accept a string as a path that points to a JS or - // JSON file or a plain object. Potentially refactor. - if (_.isString(opts)) { - options = require(resolveCwd(opts)); - } else { - options = opts; - } + options = opts; // Creating a new object and copying over the options // Also keeping an options object in case @@ -103,36 +91,19 @@ function extend(opts) { if (!_.isArray(options.include)) throw new Error('include must be an array'); - to_ret.properties = combineJSON(options.include, true); + if (options.include.length > 0) { + to_ret.properties = combineJSON(options.include, true); - to_ret.include = null; // We don't want to carry over include references + to_ret.include = null; // We don't want to carry over include references + } } - // Update properties with current package's source - // These highest precedence - if (options.source) { - if (!_.isArray(options.source)) - throw new Error('source must be an array'); + if (options.properties) { + to_ret.properties = options.properties - var props = combineJSON(options.source, true, function Collision(prop) { - GroupMessages.add( - PROPERTY_VALUE_COLLISIONS, - `Collision detected at: ${prop.path.join('.')}! Original value: ${prop.target[prop.key]}, New value: ${prop.copy[prop.key]}` - ); - }); - - if(GroupMessages.count(PROPERTY_VALUE_COLLISIONS) > 0) { - var collisions = GroupMessages.flush(PROPERTY_VALUE_COLLISIONS).join('\n'); - console.log(`\n${PROPERTY_VALUE_COLLISIONS}:\n${collisions}\n\n`); - if (options.log === 'error') { - throw new Error('Collisions detected'); - } - } - - to_ret.properties = deepExtend([{}, to_ret.properties, props]); + to_ret.include = null; // We don't want to carry over include references + } - to_ret.source = null; // We don't want to carry over the source references - } return to_ret; } diff --git a/src/vendors/style-dictionary/lib/utils/combineJSON.js b/src/vendors/style-dictionary/lib/utils/combineJSON.js index a323088..80c5883 100644 --- a/src/vendors/style-dictionary/lib/utils/combineJSON.js +++ b/src/vendors/style-dictionary/lib/utils/combineJSON.js @@ -11,7 +11,10 @@ * and limitations under the License. */ -require('json5/lib/register') +if (typeof window === 'undefined') { + require('json5/lib/register') +} + let glob = require('glob') let deepExtend = require('./deepExtend') From 263182213e08b0402fd2a63af7ca8fa280f0bf50 Mon Sep 17 00:00:00 2001 From: Nikita Nigmatullin Date: Tue, 22 Jun 2021 21:32:02 +0300 Subject: [PATCH 2/5] feat: types refactoring --- src/core/enhance-whitepaper-config.ts | 2 +- src/core/mappers.ts | 3 ++- src/core/types.ts | 29 +++++++++++++++++++++++++ src/vendors/style-dictionary/index.d.ts | 1 + 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/core/enhance-whitepaper-config.ts b/src/core/enhance-whitepaper-config.ts index 05668d0..cf25020 100644 --- a/src/core/enhance-whitepaper-config.ts +++ b/src/core/enhance-whitepaper-config.ts @@ -1,4 +1,4 @@ -type WhitepaperConfig = Record +import { WhitepaperConfig } from './types' export function enhanceWhitepaperConfig( config: WhitepaperConfig, diff --git a/src/core/mappers.ts b/src/core/mappers.ts index f0c168c..c5d9697 100644 --- a/src/core/mappers.ts +++ b/src/core/mappers.ts @@ -3,8 +3,9 @@ import { readJSON, readFileSync } from 'fs-extra' import YAML from 'yaml' import { normalizePaths } from './utils' +import { Mapper } from './types' -export async function loadMappers(paths: string[]): Promise { +export async function loadMappers(paths: string[]): Promise { const result = {} for (const file of await glob(normalizePaths(paths))) { if (/\.ya?ml$/.test(file)) { diff --git a/src/core/types.ts b/src/core/types.ts index 7c5f480..3c938b2 100644 --- a/src/core/types.ts +++ b/src/core/types.ts @@ -1,3 +1,6 @@ +import { Platforms as PlatformsTypes } from './platforms' +import { Platform as SDPlatform } from '../vendors/style-dictionary' + export type File = { context: any destination: string @@ -23,3 +26,29 @@ export type Platform = { } export type Platforms = Record + +export type WhitepaperConfig = Record + +export type Mapper = Record + +export type BaseData = { + mapper: Mapper + whitepaper: WhitepaperConfig + output: Record + entry: string + platform: PlatformsTypes +} + +export type NodeData = Array< + BaseData & { + sources: string[] + } +> + +export type BrowserData = Array< + BaseData & { + properties: object + } +> + +export type Data = NodeData | BrowserData diff --git a/src/vendors/style-dictionary/index.d.ts b/src/vendors/style-dictionary/index.d.ts index 44723d5..0ab3fb3 100644 --- a/src/vendors/style-dictionary/index.d.ts +++ b/src/vendors/style-dictionary/index.d.ts @@ -19,6 +19,7 @@ export type Platform = { export type Config = { include: string[] platforms: Record + properties: object } export type InjectedTransformer = { From 371a2d33058ebc201aeada4b98918162f8448823 Mon Sep 17 00:00:00 2001 From: Nikita Nigmatullin Date: Tue, 22 Jun 2021 21:33:01 +0300 Subject: [PATCH 3/5] feat: move data loading to separate function --- src/cli/build.ts | 24 +++++++++++++++++++++--- src/core/loadData.ts | 26 ++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 src/core/loadData.ts diff --git a/src/cli/build.ts b/src/cli/build.ts index f31df24..cf5ba1b 100644 --- a/src/cli/build.ts +++ b/src/cli/build.ts @@ -3,12 +3,14 @@ import { Command, flags } from '@oclif/command' import { watch } from 'chokidar' import chalk from 'chalk' +import { Config } from '../core/config' import { loadConfig } from '../core/config' import { build } from '../core/build' import { loadTheme } from '../core/loadTheme' import { debounce, flatten } from '../core/utils' import { buildFiles } from '../core/buildFiles' -import { Platforms } from '../core/types' +import { Data, Platforms } from '../core/types' +import { loadData } from '../core/loadData' type Flags = { config: string @@ -49,7 +51,13 @@ export default class Build extends Command { outputs: flags.output, }) - const result = await this.build(config) + const data = await this.loadData(config) + + if (!data) { + return + } + + const result = await this.build(data) if (!result) { return @@ -93,7 +101,17 @@ export default class Build extends Command { } } - private async build(config: any) { + private async loadData(config: Config): Promise { + try { + return await loadData(config) + } catch (error) { + console.log('\r') + console.log(error) + console.log(`\n>---------------- ${chalk.red('Data loading failed')} -----------------<`) + } + } + + private async build(config: any): Promise { console.log(`>---------------- ${chalk.yellow('Build started')} ----------------<`) try { const result = await build(config) diff --git a/src/core/loadData.ts b/src/core/loadData.ts new file mode 100644 index 0000000..f564339 --- /dev/null +++ b/src/core/loadData.ts @@ -0,0 +1,26 @@ +import { Config } from './config' +import { enhanceWhitepaperConfig } from './enhance-whitepaper-config' +import { loadSources } from './load-sources' +import { loadTheme } from './loadTheme' +import { loadMappers } from './mappers' +import { Data } from './types' + +export async function loadData(config: Config): Promise { + const result = [] + + for (const entry in config.entry) { + const theme = await loadTheme(config.entry[entry]) + for (const platform of theme.platforms) { + result.push({ + sources: await loadSources(theme.sources, platform), + mapper: await loadMappers(theme.mappers), + whitepaper: enhanceWhitepaperConfig(theme.whitepaper, platform), + output: config.output, + entry, + platform, + }) + } + } + + return result +} From 254347f76fa4a5e3154015c3cb95b8057bd16c25 Mon Sep 17 00:00:00 2001 From: Nikita Nigmatullin Date: Tue, 22 Jun 2021 21:34:06 +0300 Subject: [PATCH 4/5] feat: register format and transform from themebox, refactor build function --- src/core/build.ts | 92 +++++++++++++++-------------- src/core/style-dictionary-config.ts | 15 ++++- 2 files changed, 61 insertions(+), 46 deletions(-) diff --git a/src/core/build.ts b/src/core/build.ts index a3b78ee..9634e81 100644 --- a/src/core/build.ts +++ b/src/core/build.ts @@ -4,17 +4,12 @@ import cssColorFn from 'css-color-function' import { Api, InternalApi } from '../index' import { createStyleDictionaryConfig } from './style-dictionary-config' import { variablesWithPrefix } from './variablesWithPrefix' -import { loadMappers } from './mappers' -import { loadTheme } from './loadTheme' import { dedupeProps } from './dedupe-props' -import { loadSources } from './load-sources' -import { Config } from './config' import { isColor } from './utils' -import { enhanceWhitepaperConfig } from './enhance-whitepaper-config' import { replaceAliasToVariable } from './replace-alias-to-variable' import { deprecate } from './deprecate' -import { Platforms } from './types' import { performActions } from './perfomActions' +import { Platforms, Data } from './types' const context = new Map() @@ -74,6 +69,32 @@ Api.registerTransform({ }, }) +Api.registerFormat({ + name: 'json/extended', + formatter(dictionary) { + const result: Record = {} + console.log(dictionary) + for (const prop of dictionary.allProperties) { + result[prop.name] = { + name: prop.name, + value: prop.value, + rawValue: prop.original.value, + path: prop.path, + comment: prop.comment, + } + } + return JSON.stringify(result, null, 2) + }, +}) + +Api.registerTransform({ + name: 'json/extended/mapper', + type: 'name', + transformer: (prop) => { + return context.get('mapper')[prop.name] || prop.name + }, +}) + Api.registerFilter({ name: 'whitepaper/color', matcher: (prop) => { @@ -108,24 +129,13 @@ Api.registerAction({ if (key === 'value') { let convertedValue = value - const colorRe = /color\(.+\)/g + const colorRe = /color\((?!{).+\)/g let executed while ((executed = colorRe.exec(convertedValue)) !== null) { convertedValue = convertedValue.replace(executed[0], cssColorFn.convert(executed[0])) } - return { - original: value, - value: convertedValue, - } - } - - // If the value has "value" key, spread the original and converted values - if (value.value) { - return { - ...value, - ...value.value, - } + return convertedValue } return value @@ -140,32 +150,28 @@ Api.registerPreset({ actions: ['process-color'], }) -export async function build(config: Config): Promise { +export async function build(data: Data): Promise { let result = {} - for (const entry in config.entry) { - const theme = await loadTheme(config.entry[entry]) - for (const platform of theme.platforms) { - // TODO: Load sources in themes? - const sources = await loadSources(theme.sources, platform) - - // TODO: Load mappers in themes? - context.set('mapper', await loadMappers(theme.mappers)) - context.set('whitepaper', enhanceWhitepaperConfig(theme.whitepaper, platform)) - - const StyleDictionary = InternalApi.extend( - createStyleDictionaryConfig({ - platform: platform, - sources: sources, - entry: entry, - output: config.output, - }), - ) - - StyleDictionary.properties = dedupeProps(StyleDictionary.properties) - result = { ...result, ...StyleDictionary.buildAllPlatforms() } - } - } + data.forEach((el: any) => { + const { sources, mapper, whitepaper, platform, entry, output, properties } = el + + context.set('mapper', mapper) + context.set('whitepaper', whitepaper) + + const StyleDictionary = InternalApi.extend( + createStyleDictionaryConfig({ + platform, + sources, + entry, + output, + properties, + }), + ) + + StyleDictionary.properties = dedupeProps(StyleDictionary.properties) + result = { ...result, ...StyleDictionary.buildAllPlatforms() } + }) return performActions(result) } diff --git a/src/core/style-dictionary-config.ts b/src/core/style-dictionary-config.ts index 2e4da4e..8f22f36 100644 --- a/src/core/style-dictionary-config.ts +++ b/src/core/style-dictionary-config.ts @@ -7,9 +7,16 @@ type Options = { entry: string platform: string output: Record + properties: object } -export function createStyleDictionaryConfig({ sources, entry, platform, output }: Options): Config { +export function createStyleDictionaryConfig({ + sources, + entry, + platform, + output, + properties, +}: Options): Config { const platforms = Object.entries(output) // prettier-ignore .reduce>((acc, [key, value]) => { @@ -41,8 +48,10 @@ export function createStyleDictionaryConfig({ sources, entry, platform, output } return acc }, {}) + // To work in browser we should pass `properties` and set `include` to [] return { - include: sources, - platforms: platforms, + include: properties ? [] : sources, + platforms, + properties, } } From 6fc8c4d90e164a600cbe1a46cdeac67cd1a97959 Mon Sep 17 00:00:00 2001 From: Nikita Nigmatullin Date: Tue, 22 Jun 2021 21:34:22 +0300 Subject: [PATCH 5/5] feat: add parseContent function from themebox --- src/core/parseContent.ts | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/core/parseContent.ts diff --git a/src/core/parseContent.ts b/src/core/parseContent.ts new file mode 100644 index 0000000..bbcf3eb --- /dev/null +++ b/src/core/parseContent.ts @@ -0,0 +1,27 @@ +import YAML from 'yaml' + +type Format = 'json' | 'yaml' | 'yml' + +/** + * Parse content by format. + * + * @param content - Raw content + * @param format - Parsing format + */ +export function parseContent(content: string, format: Format): any { + switch (format) { + case 'json': + try { + return JSON.parse(content) + } catch (_e) { + return content + } + case 'yml': + case 'yaml': + return YAML.parse(content) + default: + throw new Error( + `Unexpected format "${format}" for parsing, please choose json or yaml format.`, + ) + } +}