style-dictionary
Advanced tools
@@ -17,6 +17,6 @@ { | ||
"destination": "font_dimens.xml", | ||
"template": "android/fontDimens" | ||
"format": "android/fontDimens" | ||
},{ | ||
"destination": "colors.xml", | ||
"template": "android/colors" | ||
"format": "android/colors" | ||
}] | ||
@@ -29,3 +29,3 @@ }, | ||
"destination": "StyleDictionaryColor.h", | ||
"template": "ios/colors.h", | ||
"format": "ios/colors.h", | ||
"className": "StyleDictionaryColor", | ||
@@ -40,3 +40,3 @@ "type": "StyleDictionaryColorName", | ||
"destination": "StyleDictionaryColor.m", | ||
"template": "ios/colors.m", | ||
"format": "ios/colors.m", | ||
"className": "StyleDictionaryColor", | ||
@@ -51,3 +51,3 @@ "type": "StyleDictionaryColorName", | ||
"destination": "StyleDictionarySize.h", | ||
"template": "ios/static.h", | ||
"format": "ios/static.h", | ||
"className": "StyleDictionarySize", | ||
@@ -62,3 +62,3 @@ "type": "float", | ||
"destination": "StyleDictionarySize.m", | ||
"template": "ios/static.m", | ||
"format": "ios/static.m", | ||
"className": "StyleDictionarySize", | ||
@@ -65,0 +65,0 @@ "type": "float", |
@@ -139,2 +139,2 @@ # Basic Style Dictionary | ||
Now go forth and create! Take a look at all the built-in [transforms](https://amzn.github.io/style-dictionary/transforms#built-in-transforms), [formats, and templates](https://amzn.github.io/style-dictionary/formats_and_templates#built-in-formats). | ||
Now go forth and create! Take a look at all the built-in [transforms](https://amzn.github.io/style-dictionary/#/transforms?id=pre-defined-transforms) and [formats](https://amzn.github.io/style-dictionary/#/formats?id=pre-defined-formats). |
@@ -12,3 +12,3 @@ { | ||
"destination": "StyleDictionarySize.h", | ||
"template": "ios/static.h", | ||
"format": "ios/static.h", | ||
"type": "float", | ||
@@ -23,3 +23,3 @@ "className": "StyleDictionarySize", | ||
"destination": "StyleDictionarySize.m", | ||
"template": "ios/static.m", | ||
"format": "ios/static.m", | ||
"type": "float", | ||
@@ -34,3 +34,3 @@ "className": "StyleDictionarySize", | ||
"destination": "StyleDictionaryIcons.h", | ||
"template": "ios/strings.h", | ||
"format": "ios/strings.h", | ||
"className": "StyleDictionaryIcons", | ||
@@ -45,3 +45,3 @@ "filter": { | ||
"destination": "StyleDictionaryIcons.m", | ||
"template": "ios/strings.m", | ||
"format": "ios/strings.m", | ||
"className": "StyleDictionaryIcons", | ||
@@ -56,3 +56,3 @@ "filter": { | ||
"destination": "StyleDictionaryColor.h", | ||
"template": "ios/colors.h", | ||
"format": "ios/colors.h", | ||
"className": "StyleDictionaryColor", | ||
@@ -67,3 +67,3 @@ "type": "StyleDictionaryColorName", | ||
"destination": "StyleDictionaryColor.m", | ||
"template": "ios/colors.m", | ||
"format": "ios/colors.m", | ||
"className": "StyleDictionaryColor", | ||
@@ -78,7 +78,7 @@ "type": "StyleDictionaryColorName", | ||
"destination": "StyleDictionaryProperties.h", | ||
"template": "ios/singleton.h", | ||
"format": "ios/singleton.h", | ||
"className": "StyleDictionaryProperties" | ||
},{ | ||
"destination": "StyleDictionaryProperties.m", | ||
"template": "ios/singleton.m", | ||
"format": "ios/singleton.m", | ||
"className": "StyleDictionaryProperties" | ||
@@ -96,12 +96,12 @@ }] | ||
"destination": "style_dictionary_font_dimens.xml", | ||
"template": "android/fontDimens" | ||
"format": "android/fontDimens" | ||
},{ | ||
"destination": "style_dictionary_dimens.xml", | ||
"template": "android/dimens" | ||
"format": "android/dimens" | ||
},{ | ||
"destination": "style_dictionary_integers.xml", | ||
"template": "android/integers" | ||
"format": "android/integers" | ||
},{ | ||
"destination": "style_dictionary_strings.xml", | ||
"template": "android/strings" | ||
"format": "android/strings" | ||
}] | ||
@@ -118,35 +118,4 @@ }, | ||
"actions": ["copy_assets"] | ||
}, | ||
"staticStyleGuide-html":{ | ||
"buildPath": "static-style-guide/public/", | ||
"files": [ | ||
{ | ||
"destination": "index.html", | ||
"template": "static-style-guide/index.html" | ||
} | ||
], | ||
"actions": ["copy_assets"] | ||
}, | ||
"staticStyleGuide-js": { | ||
"transformGroup": "web", | ||
"buildPath": "static-style-guide/public/js/", | ||
"files": [{ | ||
"name": "__style_properties", | ||
"destination": "style-dictionary-properties.js", | ||
"format": "javascript/object" | ||
}] | ||
}, | ||
"staticStyleGuide-css": { | ||
"transformGroup": "scss", | ||
"buildPath": "static-style-guide/public/css/", | ||
"files": [{ | ||
"destination": "fonts.css", | ||
"template": "css/fonts.css" | ||
},{ | ||
"destination": "variables.css", | ||
"format": "css/variables" | ||
}] | ||
} | ||
} | ||
} |
@@ -13,4 +13,4 @@ { | ||
"devDependencies": { | ||
"style-dictionary": "2.4.0" | ||
"style-dictionary": "2.5.0" | ||
} | ||
} |
@@ -13,4 +13,4 @@ { | ||
"devDependencies": { | ||
"style-dictionary": "2.4.0" | ||
"style-dictionary": "2.5.0" | ||
} | ||
} |
@@ -11,10 +11,10 @@ { | ||
"destination": "StyleDictionaryMacros.h", | ||
"template": "ios/macros" | ||
"format": "ios/macros" | ||
},{ | ||
"destination": "StyleDictionary.h", | ||
"template": "ios/singleton.h", | ||
"format": "ios/singleton.h", | ||
"className": "StyleDictionary" | ||
},{ | ||
"destination": "StyleDictionary.m", | ||
"template": "ios/singleton.m", | ||
"format": "ios/singleton.m", | ||
"className": "StyleDictionary" | ||
@@ -29,15 +29,15 @@ }] | ||
"destination": "style_dictionary_colors.xml", | ||
"template": "android/colors" | ||
"format": "android/colors" | ||
},{ | ||
"destination": "style_dictionary_font_dimens.xml", | ||
"template": "android/fontDimens" | ||
"format": "android/fontDimens" | ||
},{ | ||
"destination": "style_dictionary_dimens.xml", | ||
"template": "android/dimens" | ||
"format": "android/dimens" | ||
},{ | ||
"destination": "style_dictionary_integers.xml", | ||
"template": "android/integers" | ||
"format": "android/integers" | ||
},{ | ||
"destination": "style_dictionary_strings.xml", | ||
"template": "android/strings" | ||
"format": "android/strings" | ||
}] | ||
@@ -44,0 +44,0 @@ }, |
@@ -17,4 +17,4 @@ { | ||
"fs-extra": "^1.0.0", | ||
"style-dictionary": "2.4.0" | ||
"style-dictionary": "2.5.0" | ||
} | ||
} |
64
index.js
@@ -13,2 +13,6 @@ /* | ||
*/ | ||
var chalk = require('chalk'); | ||
var GroupMessages = require('./lib/utils/groupMessages'); | ||
var TEMPLATE_DEPRECATION_WARNINGS = GroupMessages.GROUP.TemplateDeprecationWarnings; | ||
var REGISTER_TEMPLATE_DEPRECATION_WARNINGS = GroupMessages.GROUP.RegisterTemplateDeprecationWarnings; | ||
@@ -36,3 +40,2 @@ /** | ||
format: require('./lib/common/formats'), | ||
template: require('./lib/common/templates'), | ||
action: require('./lib/common/actions'), | ||
@@ -57,1 +60,60 @@ | ||
module.exports = StyleDictionary; | ||
process.on('exit', function () { | ||
if(GroupMessages.count(TEMPLATE_DEPRECATION_WARNINGS) > 0) { | ||
var template_warnings = GroupMessages.flush(TEMPLATE_DEPRECATION_WARNINGS).join('\n '); | ||
console.log(chalk.bold.yellow(` | ||
⚠️ DEPRECATION WARNING ️️️️️⚠️ | ||
Templates are deprecated and will be removed, please update your config to use formats. | ||
This is an example of how to update your config.json: | ||
Before: | ||
"files": [{ | ||
"destination": "colors.xml", | ||
"template": "android/colors" | ||
}] | ||
After: | ||
"files": [{ | ||
"destination": "colors.xml", | ||
"format": "android/colors" | ||
}] | ||
Your current config used the following templates: | ||
${template_warnings} | ||
`)); | ||
} | ||
if(GroupMessages.count(REGISTER_TEMPLATE_DEPRECATION_WARNINGS) > 0) { | ||
var register_template_warnings = GroupMessages.flush(REGISTER_TEMPLATE_DEPRECATION_WARNINGS).join('\n '); | ||
console.log(chalk.bold.yellow(` | ||
⚠️ DEPRECATION WARNING ️️️️️⚠️ | ||
The registerTemplate method is deprecated and will be removed, please | ||
migrate to registerFormat. You can use any templating engine you would | ||
like, you just need to require/import it. This is an example of how to | ||
update your code using a lodash template (the template engine previously | ||
used by registerTemplate): | ||
Before: | ||
registerTemplate({ | ||
name: 'template/name', | ||
template: templateFile, | ||
}); | ||
After: | ||
registerFormat({ | ||
name: 'template/name', | ||
formatter: _.template( fs.readFileSync( templateFile ) ), | ||
}); | ||
Note that formatter is a function that takes in a style dictionary | ||
and returns a string with the formatted output. There is a second | ||
argument available that contains the configuration being used to | ||
process the style dictionary. | ||
Calls to registerTemplate included the registration of the following | ||
custom templates: | ||
${register_template_warnings}`)); | ||
} | ||
}); |
@@ -33,8 +33,6 @@ /* | ||
_.each(platform.files, function (file) { | ||
if (file.template) { | ||
buildFile(file.destination, file.template.bind(file), platform, dictionary, file.filter); | ||
} else if (file.format) { | ||
if (file.format) { | ||
buildFile(file.destination, file.format.bind(file), platform, dictionary, file.filter); | ||
} else { | ||
throw new Error('Please supply a template or formatter') | ||
throw new Error('Please supply a format'); | ||
} | ||
@@ -41,0 +39,0 @@ }); |
@@ -32,10 +32,8 @@ /* | ||
// while neither the template, format, or dictionary are used by clean file I'm passing them in for symmetry to buildFile | ||
// while neither the format or dictionary are used by clean file I'm passing them in for symmetry to buildFile | ||
_.each(platform.files, function (file) { | ||
if (file.template) { | ||
cleanDir(file.destination, file.template.bind(file), platform, dictionary); | ||
} else if (file.format) { | ||
if (file.format) { | ||
cleanDir(file.destination, file.format.bind(file), platform, dictionary); | ||
} else { | ||
throw new Error('Please supply a template or formatter') | ||
throw new Error('Please supply a format') | ||
} | ||
@@ -42,0 +40,0 @@ }); |
@@ -32,7 +32,5 @@ /* | ||
// while neither the template, format, or dictionary are used by clean file I'm passing them in for symmetry to buildFile | ||
// while neither the format or dictionary are used by clean file I'm passing them in for symmetry to buildFile | ||
_.each(platform.files, function (file) { | ||
if (file.template) { | ||
cleanFile(file.destination, file.template.bind(file), platform, dictionary); | ||
} else if (file.format) { | ||
if (file.format) { | ||
cleanFile(file.destination, file.format.bind(file), platform, dictionary); | ||
@@ -39,0 +37,0 @@ } else { |
@@ -14,10 +14,17 @@ /* | ||
var _ = require('lodash'); | ||
var module_def = 'module.exports = '; | ||
var fs = require('fs'), | ||
_ = require('lodash'); | ||
function fileHeader() { | ||
return '/**\n' + | ||
' * Do not edit directly\n' + | ||
' * Generated on ' + new Date() + '\n' + | ||
' */\n\n'; | ||
function fileHeader(options) { | ||
var to_ret = ''; | ||
// for backward compatibility we need to have the user explicitly hide them | ||
var showFileHeader = (options) ? options.showFileHeader : true; | ||
if (showFileHeader) { | ||
to_ret += '/**\n'; | ||
to_ret += ' * Do not edit directly\n'; | ||
to_ret += ' * Generated on ' + new Date().toUTCString() + '\n'; | ||
to_ret += ' */\n\n'; | ||
} | ||
return to_ret; | ||
} | ||
@@ -38,3 +45,3 @@ | ||
function iconsWithPrefix(prefix, properties, config) { | ||
return fileHeader() + _.chain(properties) | ||
return _.chain(properties) | ||
.filter(function(prop) { | ||
@@ -51,2 +58,16 @@ return prop.attributes.category === 'content' && prop.attributes.type === 'icon'; | ||
} | ||
function minifyDictionary(obj) { | ||
var toRet = {}; | ||
if (obj.hasOwnProperty('value')) { | ||
return obj.value; | ||
} else { | ||
for(var name in obj) { | ||
if(obj.hasOwnProperty(name)) { | ||
toRet[name] = minifyDictionary(obj[name]); | ||
} | ||
} | ||
} | ||
return toRet; | ||
} | ||
/** | ||
@@ -71,4 +92,6 @@ * @namespace Formats | ||
'css/variables': function(dictionary) { | ||
var root_vars = ':root {\n' + variablesWithPrefix(' --', dictionary.allProperties) + '\n}\n'; | ||
return fileHeader() + root_vars; | ||
return fileHeader(this.options) + | ||
':root {\n' + | ||
variablesWithPrefix(' --', dictionary.allProperties) + | ||
'\n}\n'; | ||
}, | ||
@@ -88,3 +111,3 @@ | ||
'scss/variables': function(dictionary) { | ||
return fileHeader() + variablesWithPrefix('$', dictionary.allProperties); | ||
return fileHeader(this.options) + variablesWithPrefix('$', dictionary.allProperties); | ||
}, | ||
@@ -104,3 +127,3 @@ | ||
'scss/icons': function(dictionary, config) { | ||
return iconsWithPrefix('$', dictionary.allProperties, config); | ||
return fileHeader(this.options) + iconsWithPrefix('$', dictionary.allProperties, config); | ||
}, | ||
@@ -120,3 +143,3 @@ | ||
'less/variables': function(dictionary) { | ||
return fileHeader() + variablesWithPrefix('@', dictionary.allProperties); | ||
return fileHeader(this.options) + variablesWithPrefix('@', dictionary.allProperties); | ||
}, | ||
@@ -136,3 +159,3 @@ | ||
'less/icons': function(dictionary, config) { | ||
return iconsWithPrefix('@', dictionary.allProperties, config); | ||
return fileHeader(this.options) + iconsWithPrefix('@', dictionary.allProperties, config); | ||
}, | ||
@@ -159,4 +182,4 @@ | ||
'javascript/module': function(dictionary) { | ||
return fileHeader() + | ||
module_def + | ||
return fileHeader(this.options) + | ||
'module.exports = ' + | ||
JSON.stringify(dictionary.properties, null, 2) + ';'; | ||
@@ -185,3 +208,3 @@ }, | ||
'javascript/object': function(dictionary) { | ||
return fileHeader() + | ||
return fileHeader(this.options) + | ||
'var ' + | ||
@@ -226,3 +249,3 @@ (this.name || '_styleDictionary') + | ||
var name = this.name || '_styleDictionary' | ||
return fileHeader() + | ||
return fileHeader(this.options) + | ||
'(function(root, factory) {\n' + | ||
@@ -276,3 +299,3 @@ ' if (typeof module === "object" && module.exports) {\n' + | ||
'javascript/es6': function(dictionary) { | ||
return fileHeader() + | ||
return fileHeader(this.options) + | ||
_.map(dictionary.allProperties, function(prop) { | ||
@@ -286,3 +309,230 @@ var to_ret_prop = 'export const ' + prop.name + ' = ' + JSON.stringify(prop.value) + ';'; | ||
// Android templates | ||
/** | ||
* Creates a color resource xml file with all the colors in your style dictionary. | ||
* | ||
* @memberof Formats | ||
* @kind member | ||
* @example | ||
* ```xml | ||
* <?xml version="1.0" encoding="UTF-8"?> | ||
* <resources> | ||
* <color name="color_base_red_5">#fffaf3f2</color> | ||
* <color name="color_base_red_30">#fff0cccc</color> | ||
* <color name="color_base_red_60">#ffe19d9c</color> | ||
* ``` | ||
*/ | ||
'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 | ||
* <?xml version="1.0" encoding="UTF-8"?> | ||
* <resources> | ||
* <dimen name="size_padding_tiny">5.00dp</dimen> | ||
* <dimen name="size_padding_small">10.00dp</dimen> | ||
* <dimen name="size_padding_medium">15.00dp</dimen> | ||
* ``` | ||
*/ | ||
'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 | ||
* <?xml version="1.0" encoding="UTF-8"?> | ||
* <resources> | ||
* <dimen name="size_font_tiny">10.00sp</dimen> | ||
* <dimen name="size_font_small">13.00sp</dimen> | ||
* <dimen name="size_font_medium">15.00sp</dimen> | ||
* ``` | ||
*/ | ||
'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 | ||
* <?xml version="1.0" encoding="UTF-8"?> | ||
* <resources> | ||
* <integer name="time_duration_short">1000</string> | ||
* <integer name="time_duration_medium">2000</string> | ||
* <integer name="time_duration_long">4000</string> | ||
* ``` | ||
*/ | ||
'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 | ||
* <?xml version="1.0" encoding="UTF-8"?> | ||
* <resources> | ||
* <string name="content_icon_email"></string> | ||
* <string name="content_icon_chevron_down"></string> | ||
* <string name="content_icon_chevron_up"></string> | ||
* ``` | ||
*/ | ||
'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 <Foundation/Foundation.h> | ||
* #import <UIKit/UIKit.h> | ||
* | ||
* #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') | ||
), | ||
// 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 | ||
/** | ||
* Creates a JSON file of the style dictionary. | ||
@@ -332,2 +582,23 @@ * | ||
/** | ||
* Creates a JSON nested file of the style dictionary. | ||
* | ||
* @memberof Formats | ||
* @kind member | ||
* @example | ||
* ```json | ||
* { | ||
* "color": { | ||
* "base": { | ||
* "red": "#ff000" | ||
* } | ||
* } | ||
* } | ||
* ``` | ||
*/ | ||
'json/nested': function(dictionary) { | ||
return JSON.stringify(minifyDictionary(dictionary.properties), null, 2); | ||
}, | ||
/** | ||
* Creates a sketchpalette file of all the base colors | ||
@@ -334,0 +605,0 @@ * |
@@ -16,4 +16,7 @@ /* | ||
transformObject = require('./transform/object'), | ||
transformConfig = require('./transform/config'); | ||
transformConfig = require('./transform/config'), | ||
GroupMessages = require('./utils/groupMessages'); | ||
var PROPERTY_REFERENCE_WARNINGS = GroupMessages.GROUP.PropertyReferenceWarnings; | ||
/** | ||
@@ -45,5 +48,13 @@ * Exports a properties object with applied | ||
// replacing that value in the string. | ||
return resolveObject( | ||
var to_ret = resolveObject( | ||
transformObject(this.properties, platformConfig) | ||
); | ||
if(GroupMessages.count(PROPERTY_REFERENCE_WARNINGS) > 0) { | ||
var warnings = GroupMessages.flush(PROPERTY_REFERENCE_WARNINGS).join('\n'); | ||
console.log(`\n${PROPERTY_REFERENCE_WARNINGS}:\n${warnings}\n\n`); | ||
throw new Error('Problems were found when trying to resolve property references'); | ||
} | ||
return to_ret; | ||
} | ||
@@ -50,0 +61,0 @@ |
@@ -14,2 +14,4 @@ /* | ||
require('json5/lib/register'); | ||
var combineJSON = require('./utils/combineJSON'), | ||
@@ -19,4 +21,7 @@ deepExtend = require('./utils/deepExtend'), | ||
_ = require('lodash'), | ||
chalk = require('chalk'); | ||
chalk = require('chalk'), | ||
GroupMessages = require('./utils/groupMessages'); | ||
var PROPERTY_VALUE_COLLISIONS = GroupMessages.GROUP.PropertyValueCollisions; | ||
/** | ||
@@ -92,3 +97,3 @@ * Either a string to a JSON file that contains configuration for the style dictionary or a plain Javascript object | ||
options = opts; | ||
}`` | ||
} | ||
@@ -117,14 +122,19 @@ // Creating a new object and copying over the options | ||
var props = combineJSON(options.source, true, function Collision(opts) { | ||
if (options.log) { | ||
var str = `Collision detected at: ${opts.path.join('.')}! Original value: ${opts.target[opts.key]}, New value: ${opts.copy[opts.key]}`; | ||
if (options.log === 'warn') { | ||
console.warn(chalk.keyword('orange')(str)); | ||
} else if (options.log === 'error') { | ||
throw new Error(str); | ||
} | ||
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.source = null; // We don't want to carry over the source references | ||
@@ -131,0 +141,0 @@ } |
@@ -14,3 +14,2 @@ /* | ||
/** | ||
@@ -37,7 +36,8 @@ * Add a custom format to the style dictionary | ||
if (typeof options.name !== 'string') | ||
throw new Error('transform name must be a string'); | ||
throw new Error('Can\'t register format; format.name must be a string'); | ||
if (typeof options.formatter !== 'function') | ||
throw new Error('format formatter must be a function'); | ||
throw new Error('Can\'t register format; format.formatter must be a function'); | ||
this.format[options.name] = options.formatter; | ||
return this; | ||
@@ -44,0 +44,0 @@ } |
@@ -15,7 +15,12 @@ /* | ||
var fs = require('fs'), | ||
_ = require('lodash'); | ||
_ = require('lodash'), | ||
chalk = require('chalk'), | ||
GroupMessages = require('../utils/groupMessages'); | ||
var REGISTER_TEMPLATE_DEPRECATION_WARNINGS = GroupMessages.GROUP.RegisterTemplateDeprecationWarnings; | ||
/** | ||
* Add a custom template to the Style Dictionary | ||
* @static | ||
* @deprecated registerTemplate will be removed in the future, please use registerFormat | ||
* @memberof module:style-dictionary | ||
@@ -36,11 +41,16 @@ * @param {Object} template | ||
if (typeof options.name !== 'string') | ||
throw new Error('transform name must be a string'); | ||
throw new Error('Template name must be a string: ' + chalk.red(JSON.stringify(options.name))); | ||
if (typeof options.template !== 'string') | ||
throw new Error('template path must be a string'); | ||
throw new Error('Template path must be a string: ' + chalk.red(JSON.stringify(options.template))); | ||
if (!fs.existsSync(options.template)) | ||
throw new Error('template must be a file'); | ||
throw new Error('Can\'t find template: ' + chalk.red(JSON.stringify(options.template))); | ||
GroupMessages.add( | ||
REGISTER_TEMPLATE_DEPRECATION_WARNINGS, | ||
`${options.name}` | ||
); | ||
var template_string = fs.readFileSync( options.template ); | ||
this.template[options.name] = _.template( template_string ); | ||
this.format[options.name] = _.template( template_string ); | ||
return this; | ||
@@ -47,0 +57,0 @@ } |
@@ -15,7 +15,10 @@ /* | ||
var _ = require('lodash'), | ||
chalk = require('chalk'); | ||
chalk = require('chalk'), | ||
GroupMessages = require('../utils/groupMessages'); | ||
var TEMPLATE_DEPRECATION_WARNINGS = GroupMessages.GROUP.TemplateDeprecationWarnings; | ||
/** | ||
* Takes a platform config object and returns a new one | ||
* that has transforms, formats, templates, and actions | ||
* that has transforms, formats, and actions | ||
* mapped properly. | ||
@@ -54,4 +57,8 @@ * @private | ||
if (file.template) { | ||
if (dictionary.template[file.template]) { | ||
return _.extend({}, file, {template: dictionary.template[file.template]}); | ||
if (dictionary.format[file.template]) { | ||
GroupMessages.add( | ||
TEMPLATE_DEPRECATION_WARNINGS, | ||
`${file.destination} (template: ${file.template})` | ||
); | ||
return _.extend({}, file, {format: dictionary.format[file.template]}); | ||
} else { | ||
@@ -67,3 +74,3 @@ throw new Error('Can\'t find template: ' + file.template); | ||
} else { | ||
throw new Error('Please supply a format or template for file: ' + JSON.stringify(file)); | ||
throw new Error('Please supply a format for file: ' + JSON.stringify(file)); | ||
} | ||
@@ -70,0 +77,0 @@ }); |
@@ -14,2 +14,4 @@ /* | ||
require('json5/lib/register'); | ||
var glob = require('glob'), | ||
@@ -16,0 +18,0 @@ deepExtend = require('./deepExtend'), |
@@ -65,6 +65,7 @@ /* | ||
path.push(name); | ||
var nextPath = path.slice(0); | ||
nextPath.push(name); | ||
// Never move original objects, clone them | ||
target[ name ] = deepExtend( [clone, copy], collision, path ); | ||
target[ name ] = deepExtend( [clone, copy], collision, nextPath ); | ||
@@ -78,3 +79,2 @@ // Don't bring in undefined values | ||
} | ||
path.pop(); | ||
} | ||
@@ -81,0 +81,0 @@ } |
@@ -14,4 +14,7 @@ /* | ||
var _ = require('lodash'); | ||
var _ = require('lodash'), | ||
GroupMessages = require('./groupMessages'); | ||
var PROPERTY_REFERENCE_WARNINGS = GroupMessages.GROUP.PropertyReferenceWarnings; | ||
var current_context = []; // To maintain the context so we can test for circular definitions | ||
@@ -54,3 +57,2 @@ var defaults = { | ||
var key; | ||
var errors = []; | ||
@@ -67,8 +69,3 @@ for (key in obj) { | ||
if (typeof obj[key] === 'string' && obj[key].indexOf('{') > -1) { | ||
try { | ||
obj[key] = compile_value( obj[key], [key] ); | ||
} | ||
catch (e) { | ||
errors.push(e); | ||
} | ||
obj[key] = compile_value( obj[key], [current_context.join('.')] ); | ||
} | ||
@@ -80,6 +77,2 @@ } | ||
if(errors.length) { | ||
throw new Error(errors.length===1 ? errors[0] : 'Failed due to '+errors.length+' errors:\n' + errors.join('\n').replace(/Error: /g,'\t')); | ||
} | ||
return obj; | ||
@@ -89,6 +82,6 @@ } | ||
var foundCirc = {}; | ||
function compile_value(value, stack) { | ||
function compile_value(value, stack) { | ||
var to_ret, ref; | ||
stack.push(value.slice(1, -1)); | ||
@@ -98,2 +91,4 @@ // Replace the reference inline, but don't replace the whole string because | ||
value.replace(regex, function(match, variable) { | ||
stack.push(variable); | ||
// Find what the value is referencing | ||
@@ -109,6 +104,29 @@ ref = selfRef(variable.trim(), updated_object); | ||
var reference = to_ret.slice(1, -1); | ||
if(stack.indexOf(reference)!==-1) { | ||
stack.push(reference); | ||
throw new Error('Variable reference for \'' + stack[0] + '\' resolves to circular definition cycle of \'' + reference + '\': ' + stack.join(', ') ); | ||
// Compare to found circular references | ||
if (foundCirc.hasOwnProperty(reference)) { | ||
// If the current reference is a member of a circular reference, do nothing | ||
} | ||
else if(stack.indexOf(reference)!==-1) { | ||
// If the current stack already contains the current reference, we found a new circular reference | ||
// chop down to just the circular part, save it to our circular reference info, and spit out an error | ||
// Get the position of the existing reference in the stack | ||
var stackIndexReference = stack.indexOf(reference); | ||
// Get the portion of the stack that starts at the circular reference and brings you through until the end | ||
var circStack = stack.slice(stackIndexReference); | ||
// For all the references in this list, add them to the list of references that end up in a circular reference | ||
circStack.forEach(function(key) { foundCirc[key] = true; }); | ||
// Add our found circular reference to the end of the cycle | ||
circStack.push(reference); | ||
// Add circ reference info to our list of warning messages | ||
GroupMessages.add( | ||
PROPERTY_REFERENCE_WARNINGS, | ||
"Circular definition cycle: " + circStack.join(', ') | ||
); | ||
} | ||
else { | ||
@@ -126,2 +144,3 @@ to_ret = compile_value( to_ret, stack ); | ||
} | ||
stack.pop(variable); | ||
@@ -135,6 +154,6 @@ return to_ret; | ||
function selfRef(string, obj) { | ||
function selfRef(str, obj) { | ||
var i, | ||
ref=obj, | ||
array = string.split(options.separator), | ||
array = str.split(options.separator), | ||
context = current_context.join(options.separator); | ||
@@ -154,12 +173,9 @@ | ||
if (ref === obj) { | ||
throw new Error('Reference doesn\'t exist: ' + context + ' tries to reference ' + string + ', which is not defined'); | ||
GroupMessages.add( | ||
PROPERTY_REFERENCE_WARNINGS, | ||
"Reference doesn't exist: " + context + " tries to reference " + str + ", which is not defined" | ||
); | ||
} | ||
var test = options.opening_character + context + options.closing_character; | ||
if (typeof ref === 'string' && ref.indexOf(test) > -1) { | ||
throw new Error('Circular definition: ' + context + ' | ' + string); | ||
} else { | ||
return ref; | ||
} | ||
return ref; | ||
} | ||
@@ -166,0 +182,0 @@ |
{ | ||
"name": "style-dictionary", | ||
"version": "2.4.0", | ||
"version": "2.5.0", | ||
"description": "Style once, use everywhere. A build system for creating cross-platform styles.", | ||
@@ -39,3 +39,3 @@ "keywords": [ | ||
"lint": "eslint index.js lib/**/*.js test/*.js test/**/*.js", | ||
"test": "npm run lint && mocha --recursive -c", | ||
"test": "npm run lint && jest --runInBand", | ||
"coverage": "istanbul cover ./node_modules/mocha/bin/_mocha -- test/*.js test/**/*.js", | ||
@@ -48,2 +48,20 @@ "preversion": "npm test", | ||
}, | ||
"jest": { | ||
"verbose": false, | ||
"roots": [ | ||
"__tests__" | ||
], | ||
"testPathIgnorePatterns": [ | ||
"/__tests__/__helpers.js", | ||
"/__tests__/__assets/", | ||
"/__tests__/__configs/", | ||
"/__tests__/__json_files/", | ||
"/__tests__/__properties/", | ||
"/__tests__/__output/" | ||
], | ||
"transform": { | ||
"^.+\\.json5?$": "json5-jest", | ||
"^.+\\.jsx?$": "babel-jest" | ||
} | ||
}, | ||
"husky": { | ||
@@ -71,22 +89,27 @@ "hooks": { | ||
"dependencies": { | ||
"chalk": "^2.4.1", | ||
"commander": "^2.9.0", | ||
"fs-extra": "^6.0.1", | ||
"glob": "^7.1.1", | ||
"json5": "^2.1.0", | ||
"lodash": "^4.16.4", | ||
"resolve-cwd": "^2.0.0", | ||
"tinycolor2": "^1.4.1", | ||
"chalk": "^2.4.1" | ||
"tinycolor2": "^1.4.1" | ||
}, | ||
"devDependencies": { | ||
"babel-jest": "^23.6.0", | ||
"babel-preset-env": "^1.7.0", | ||
"chai": "^4.1.2", | ||
"docsify": "^4.6.10", | ||
"docsify-cli": "^4.2.1", | ||
"docsify": "^4.8.0", | ||
"docsify-cli": "^4.3.0", | ||
"eslint": "^4.19.1", | ||
"husky": "^1.0.0-rc.8", | ||
"istanbul": "^0.4.5", | ||
"jest": "^23.6.0", | ||
"jsdoc-to-markdown": "^4.0.1", | ||
"json5-jest": "^1.0.1", | ||
"less": "^3.0.1", | ||
"mocha": "^5.2.0", | ||
"node-sass": "^4.8.3" | ||
"node-sass": "^4.9.4" | ||
} | ||
} |
@@ -127,3 +127,3 @@ <img src="docs/assets/logo.png" alt="Style Dictionary logo and mascot" title=""Pascal"" width="100" align="right" /> | ||
"destination": "font_dimens.xml", | ||
"template": "android/fontDimens" | ||
"format": "android/fontDimens" | ||
}] | ||
@@ -144,4 +144,5 @@ } | ||
| platform.file.destination | String (optional) | Location to build the file, will be appended to the buildPath. | | ||
| platform.file.format | String (optional) | Format used to generate the file. Can be a built-in one or you can create your own. Must declare a format or a template. | | ||
| platform.file.template | String (optional) | Template used to generate the file. Can be a built-in one or you can create your own. [More on formats and templates](https://amzn.github.io/style-dictionary/formats_and_templates) | | ||
| platform.file.format | String (optional) | Format used to generate the file. Can be a built-in one or you can create your own. [More on formats](https://amzn.github.io/style-dictionary/#/formats) | | ||
| platform.file.options | Object (optional) | A set of extra options associated with the file. | | ||
| platform.file.options.showFileHeader | Boolean | If the generated file should have a "Do not edit + Timestamp" header (where the format supports it). By default is "true". | | ||
@@ -259,3 +260,3 @@ ### Properties | ||
The style dictionary build system is made to be extended. We don't know exactly how everyone will want to use style dictionaries in their project, which is why it is easy to create custom transforms, templates, and formats. | ||
The style dictionary build system is made to be extended. We don't know exactly how everyone will want to use style dictionaries in their project, which is why it is easy to create custom transforms and formats. | ||
@@ -279,3 +280,3 @@ ```javascript | ||
For more information on creating your own transforms, templates, and formats, take a look at our [docs](https://amzn.github.io/style-dictionary/). | ||
For more information on creating your own transforms and formats, take a look at our [docs](https://amzn.github.io/style-dictionary/). | ||
@@ -282,0 +283,0 @@ ## Mascot |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
293
0.34%2852486
-0.32%8
14.29%14
40%341
-1.45%9326
-5.42%