Comparing version 6.0.0-beta.5 to 6.0.0-beta.6
// Copyright (c) 2015-present, salesforce.com, inc. All rights reserved | ||
// Licensed under BSD 3-Clause - see LICENSE.txt or git.io/sfdc-license | ||
const theo = require('../../lib') | ||
const fs = require('fs-extra') | ||
const path = require('path') | ||
const theo = require("../../lib"); | ||
const fs = require("fs-extra"); | ||
const path = require("path"); | ||
module.exports = ({ src = '', dest, formats, transform }) => | ||
module.exports = ({ src = "", dest, formats, transform }) => | ||
Promise.all( | ||
formats.map(format => | ||
theo.convert({ | ||
transform: { | ||
type: transform, | ||
file: path.resolve(process.cwd(), src) | ||
}, | ||
format: { | ||
type: format | ||
} | ||
}) | ||
.then(data => { | ||
if (dest) { | ||
const base = path.basename(src, path.extname(src)) | ||
const fileBase = path.join(dest, `${base}.${format}`) | ||
const file = path.resolve(process.cwd(), fileBase) | ||
return fs.outputFile(file, data) | ||
.then(() => console.log(`✏️ ${format} tokens created at "${fileBase}"`)) | ||
} else { | ||
console.log(data) | ||
} | ||
}) | ||
theo | ||
.convert({ | ||
transform: { | ||
type: transform, | ||
file: path.resolve(process.cwd(), src) | ||
}, | ||
format: { | ||
type: format | ||
} | ||
}) | ||
.then(data => { | ||
if (dest) { | ||
const base = path.basename(src, path.extname(src)); | ||
const fileBase = path.join(dest, `${base}.${format}`); | ||
const file = path.resolve(process.cwd(), fileBase); | ||
return fs | ||
.outputFile(file, data) | ||
.then(() => | ||
console.log(`✏️ ${format} tokens created at "${fileBase}"`) | ||
); | ||
} else { | ||
console.log(data); | ||
} | ||
}) | ||
) | ||
) | ||
); |
@@ -5,5 +5,5 @@ #!/usr/bin/env node | ||
const argv = require('optimist').argv | ||
const argv = require("optimist").argv; | ||
const build = require('./scripts/build') | ||
const build = require("./scripts/build"); | ||
@@ -13,9 +13,9 @@ const options = { | ||
dest: argv.dest, | ||
formats: (argv.format || 'raw.json').split(','), | ||
transform: argv.transform || 'raw' | ||
} | ||
formats: (argv.format || "raw.json").split(","), | ||
transform: argv.transform || "raw" | ||
}; | ||
build(options).catch(error => { | ||
console.log(`💩 Oops, something went wrong: ${error}`) | ||
return process.exit(1) | ||
}) | ||
console.log(`💩 Oops, something went wrong: ${error}`); | ||
return process.exit(1); | ||
}); |
@@ -5,3 +5,2 @@ // Copyright (c) 2015-present, salesforce.com, inc. All rights reserved | ||
module.exports = { | ||
ALIAS_PATTERN: /{!([^}]+)}/g, | ||
@@ -12,3 +11,2 @@ | ||
PERCENTAGE_PATTERN: /(\d+)%/g | ||
} | ||
}; |
// Copyright (c) 2015-present, salesforce.com, inc. All rights reserved | ||
// Licensed under BSD 3-Clause - see LICENSE.txt or git.io/sfdc-license | ||
const { constant, identity } = require('core.lambda') | ||
const Either = require('data.either') | ||
const Immutable = require('immutable-ext') | ||
const { constant, identity } = require("core.lambda"); | ||
const Either = require("data.either"); | ||
const Immutable = require("immutable-ext"); | ||
const { ALIAS_PATTERN } = require('./constants') | ||
const { allMatches } = require('./util') | ||
const { ALIAS_PATTERN } = require("./constants"); | ||
const { allMatches } = require("./util"); | ||
@@ -17,6 +17,5 @@ const transform = options => { | ||
const go = def => | ||
Either | ||
.fromNullable(def) | ||
Either.fromNullable(def) | ||
.chain(validate) | ||
.map(options.get('preprocess', identity)) | ||
.map(options.get("preprocess", identity)) | ||
.chain(validateProps(validateProp)) | ||
@@ -29,24 +28,23 @@ .map(includeOriginalValue) | ||
.map(formatAliases) | ||
.chain(def => | ||
options.get('resolveAliases') === false | ||
? Either.of(def) | ||
: Either.try(resolveNestedAliases)(def) | ||
.chain( | ||
def => | ||
options.get("resolveAliases") === false | ||
? Either.of(def) | ||
: Either.try(resolveNestedAliases)(def) | ||
) | ||
.chain(def => | ||
options.get('resolveAliases') === false | ||
? Either.of(def) | ||
: Either.try(resolveAliases)(def) | ||
.chain( | ||
def => | ||
options.get("resolveAliases") === false | ||
? Either.of(def) | ||
: Either.try(resolveAliases)(def) | ||
) | ||
.map(addPropName) | ||
.chain(transformValues) | ||
.chain(transformValues); | ||
/** | ||
* Merge the "global" object into each prop | ||
*/ | ||
const mergeGlobal = def => def | ||
.update('props', props => | ||
props.map((v, k) => | ||
def.get('global').merge(v) | ||
) | ||
) | ||
.delete('global') | ||
const mergeGlobal = def => | ||
def | ||
.update("props", props => props.map((v, k) => def.get("global").merge(v))) | ||
.delete("global"); | ||
/** | ||
@@ -56,7 +54,5 @@ * | ||
const includeOriginalValue = def => | ||
def.update('props', props => | ||
props.map(prop => | ||
prop.set('originalValue', prop.get('value')) | ||
) | ||
) | ||
def.update("props", props => | ||
props.map(prop => prop.set("originalValue", prop.get("value"))) | ||
); | ||
/** | ||
@@ -66,9 +62,8 @@ * Validate that a prop is structured correctly | ||
const validateProp = (prop, propName) => | ||
Either | ||
.of(prop) | ||
.chain(prop => | ||
Either.of(prop).chain( | ||
prop => | ||
Immutable.Map.isMap(prop) | ||
? Either.Right(prop) | ||
: Either.Left(`Property "${propName}" must be an object`) | ||
) | ||
); | ||
/** | ||
@@ -79,27 +74,31 @@ * Validate that a prop has all required keys | ||
Immutable.List | ||
.of('value', 'type', 'category') | ||
.traverse(Either.of, propKey => | ||
prop.has(propKey) | ||
? Either.Right() | ||
: Either.Left(`Property "${propName}" contained no "${propKey}" key`) | ||
.of("value", "type", "category") | ||
.traverse( | ||
Either.of, | ||
propKey => | ||
prop.has(propKey) | ||
? Either.Right() | ||
: Either.Left( | ||
`Property "${propName}" contained no "${propKey}" key` | ||
) | ||
) | ||
.map(constant(prop)) | ||
.map(constant(prop)); | ||
/** | ||
* Validate that all props have required keys | ||
*/ | ||
const validateProps = fn => def => def | ||
.get('props') | ||
.traverse(Either.of, fn) | ||
.map(constant(def)) | ||
const validateProps = fn => def => | ||
def | ||
.get("props") | ||
.traverse(Either.of, fn) | ||
.map(constant(def)); | ||
/** | ||
* Validate that all props have required keys | ||
*/ | ||
const formatAliases = def => def | ||
.update('aliases', aliases => | ||
aliases.map(alias => | ||
Immutable.Map.isMap(alias) | ||
? alias | ||
: Immutable.Map({ value: alias }) | ||
const formatAliases = def => | ||
def.update("aliases", aliases => | ||
aliases.map( | ||
alias => | ||
Immutable.Map.isMap(alias) ? alias : Immutable.Map({ value: alias }) | ||
) | ||
) | ||
); | ||
/** | ||
@@ -109,73 +108,86 @@ * Validate that a definition is correctly structured | ||
const validate = def => | ||
Either | ||
.of(def) | ||
.chain(def => | ||
Immutable.Map.isMap(def.get('props')) | ||
? Either.Right(def) | ||
: Either.Left('"props" key must be an object') | ||
Either.of(def) | ||
.chain( | ||
def => | ||
Immutable.Map.isMap(def.get("props")) | ||
? Either.Right(def) | ||
: Either.Left('"props" key must be an object') | ||
) | ||
.chain(def => | ||
Immutable.Map.isMap(def.get('aliases')) | ||
? Either.Right(def) | ||
: Either.Left('"aliases" key must be an object') | ||
.chain( | ||
def => | ||
Immutable.Map.isMap(def.get("aliases")) | ||
? Either.Right(def) | ||
: Either.Left('"aliases" key must be an object') | ||
) | ||
.chain(def => | ||
Immutable.Map.isMap(def.get('global')) | ||
? Either.Right(def) | ||
: Either.Left('"global" key must be an object') | ||
) | ||
.chain( | ||
def => | ||
Immutable.Map.isMap(def.get("global")) | ||
? Either.Right(def) | ||
: Either.Left('"global" key must be an object') | ||
); | ||
/** | ||
* Map each import over go() | ||
*/ | ||
const transformImports = def => def | ||
.get('imports') | ||
.traverse(Either.of, go) | ||
.map(imports => | ||
def.set('imports', imports) | ||
) | ||
const transformImports = def => | ||
def | ||
.get("imports") | ||
.traverse(Either.of, go) | ||
.map(imports => def.set("imports", imports)); | ||
/** | ||
* Merge aliases/props from each import into the provided def | ||
*/ | ||
const mergeImports = def => def | ||
.update('aliases', aliases => | ||
def.get('imports').reduce((aliases, i) => | ||
aliases.merge(i.get('aliases', Immutable.OrderedMap())) | ||
, Immutable.OrderedMap()).merge(aliases) | ||
) | ||
.update('props', props => | ||
def.get('imports').reduce((props, i) => | ||
props.merge(i.get('props', Immutable.OrderedMap())) | ||
, Immutable.OrderedMap()).merge(props) | ||
) | ||
.delete('imports') | ||
const mergeImports = def => | ||
def | ||
.update("aliases", aliases => | ||
def | ||
.get("imports") | ||
.reduce( | ||
(aliases, i) => | ||
aliases.merge(i.get("aliases", Immutable.OrderedMap())), | ||
Immutable.OrderedMap() | ||
) | ||
.merge(aliases) | ||
) | ||
.update("props", props => | ||
def | ||
.get("imports") | ||
.reduce( | ||
(props, i) => props.merge(i.get("props", Immutable.OrderedMap())), | ||
Immutable.OrderedMap() | ||
) | ||
.merge(props) | ||
) | ||
.delete("imports"); | ||
/** | ||
* Resolve aliases that refer to other aliases | ||
*/ | ||
const resolveNestedAliases = def => def | ||
.update('aliases', aliases => { | ||
const resolveNestedAliases = def => | ||
def.update("aliases", aliases => { | ||
const resolve = value => | ||
value.update('value', v => | ||
allMatches(v, ALIAS_PATTERN).reduce((v, [alias, key]) => | ||
aliases.has(key) | ||
? v.replace(alias, resolve(aliases.get(key)).get('value')) | ||
: v | ||
, v) | ||
) | ||
return aliases.map(resolve) | ||
}) | ||
value.update("value", v => | ||
allMatches(v, ALIAS_PATTERN).reduce( | ||
(v, [alias, key]) => | ||
aliases.has(key) | ||
? v.replace(alias, resolve(aliases.get(key)).get("value")) | ||
: v, | ||
v | ||
) | ||
); | ||
return aliases.map(resolve); | ||
}); | ||
/** | ||
* Resolve aliases inside prop values | ||
*/ | ||
const resolveAliases = def => def | ||
.update('props', props => { | ||
const aliases = def.get('aliases', Immutable.Map()) | ||
const resolveAliases = def => | ||
def.update("props", props => { | ||
const aliases = def.get("aliases", Immutable.Map()); | ||
return props.map((value, key) => | ||
value.update('value', v => | ||
value.update("value", v => | ||
allMatches(v, ALIAS_PATTERN).reduce((v, [alias, key]) => { | ||
if (!aliases.has(key)) throw new Error(`Alias "${key}" not found`) | ||
return v.replace(alias, aliases.getIn([key, 'value'])) | ||
if (!aliases.has(key)) throw new Error(`Alias "${key}" not found`); | ||
return v.replace(alias, aliases.getIn([key, "value"])); | ||
}, v) | ||
) | ||
) | ||
}) | ||
); | ||
}); | ||
/** | ||
@@ -185,7 +197,7 @@ * | ||
const transformValue = transform => prop => | ||
transform.get('predicate')(prop) | ||
? Either | ||
.try(transform.get('transform'))(prop) | ||
.map(value => prop.set('value', value)) | ||
: Either.Right(prop) | ||
transform.get("predicate")(prop) | ||
? Either.try(transform.get("transform"))(prop).map(value => | ||
prop.set("value", value) | ||
) | ||
: Either.Right(prop); | ||
/** | ||
@@ -196,29 +208,28 @@ * transform each prop value using the provided value transforms | ||
def | ||
.get('props') | ||
.get("props") | ||
.keySeq() | ||
.toList() | ||
.traverse(Either.of, key => { | ||
const prop = def.getIn(['props', key]) | ||
return options.get('transforms', Immutable.List()).reduce((p, t) => | ||
p.chain(transformValue(t)) | ||
, Either.of(prop)) | ||
const prop = def.getIn(["props", key]); | ||
return options | ||
.get("transforms", Immutable.List()) | ||
.reduce((p, t) => p.chain(transformValue(t)), Either.of(prop)); | ||
}) | ||
.map(props => | ||
props.reduce((props, prop) => | ||
props.set(prop.get('name'), prop) | ||
, Immutable.OrderedMap()) | ||
props.reduce( | ||
(props, prop) => props.set(prop.get("name"), prop), | ||
Immutable.OrderedMap() | ||
) | ||
) | ||
.map(props => | ||
def.set('props', props) | ||
) | ||
.map(props => def.set("props", props)); | ||
/** | ||
* Add a "name" key to each prop | ||
*/ | ||
const addPropName = def => def | ||
.update('props', props => | ||
props.map((prop, name) => prop.set('name', name)) | ||
) | ||
const addPropName = def => | ||
def.update("props", props => | ||
props.map((prop, name) => prop.set("name", name)) | ||
); | ||
return go | ||
} | ||
return go; | ||
}; | ||
@@ -229,10 +240,13 @@ module.exports = { | ||
// Cleanup after recursion | ||
.map(def => def | ||
.delete('imports') | ||
.update('props', props => | ||
options.get('includeMeta') | ||
? props | ||
: props.map(prop => prop.delete('meta')) | ||
) | ||
.map(def => | ||
def | ||
.delete("imports") | ||
.update( | ||
"props", | ||
props => | ||
options.get("includeMeta") | ||
? props | ||
: props.map(prop => prop.delete("meta")) | ||
) | ||
) | ||
} | ||
}; |
// Copyright (c) 2015-present, salesforce.com, inc. All rights reserved | ||
// Licensed under BSD 3-Clause - see LICENSE.txt or git.io/sfdc-license | ||
const { constant } = require('core.lambda') | ||
const Either = require('data.either') | ||
const fs = require('fs') | ||
const Immutable = require('immutable-ext') | ||
const JSON5 = require('json5') | ||
const path = require('path') | ||
const yaml = require('js-yaml') | ||
const { constant } = require("core.lambda"); | ||
const Either = require("data.either"); | ||
const fs = require("fs"); | ||
const Immutable = require("immutable-ext"); | ||
const JSON5 = require("json5"); | ||
const path = require("path"); | ||
const yaml = require("js-yaml"); | ||
const load = file => | ||
Either | ||
.try(fs.readFileSync)(file) | ||
Either.try(fs.readFileSync)(file) | ||
.map(buffer => buffer.toString()) | ||
.map(data => | ||
({ file, data }) | ||
) | ||
.map(data => ({ file, data })); | ||
const parse = ({ file, data }) => { | ||
switch (path.extname(file)) { | ||
case '.yaml': | ||
case '.yml': | ||
return Either | ||
.try(yaml.safeLoad)(data) | ||
case '.json': | ||
case '.json5': | ||
return Either | ||
.try(JSON5.parse)(data) | ||
case ".yaml": | ||
case ".yml": | ||
return Either.try(yaml.safeLoad)(data); | ||
case ".json": | ||
case ".json5": | ||
return Either.try(JSON5.parse)(data); | ||
default: | ||
return Either.Left(`Unable to parse file "${file}"`) | ||
return Either.Left(`Unable to parse file "${file}"`); | ||
} | ||
} | ||
}; | ||
const resolve = ({ file, data }) => | ||
Either | ||
.fromNullable(data) | ||
Either.fromNullable(data) | ||
.map(constant({ file, data })) | ||
@@ -43,22 +37,41 @@ .orElse(() => load(file)) | ||
.map(parsed => | ||
Immutable | ||
.fromJS({ | ||
global: {}, | ||
props: {}, | ||
aliases: {}, | ||
imports: [] | ||
}) | ||
.merge(parsed) | ||
Immutable.fromJS({ | ||
global: {}, | ||
props: {}, | ||
aliases: {}, | ||
imports: [] | ||
}).merge(parsed) | ||
) | ||
.chain(parsed => parsed | ||
.get('imports') | ||
.traverse(Either.of, i => | ||
Either | ||
.of(path.resolve(path.dirname(file), i)) | ||
.chain(load) | ||
.chain(resolve) | ||
) | ||
.map(parsedImports => | ||
parsed.set('imports', parsedImports)) | ||
) | ||
// If "props" is a List, foldMap it into an OrderedMap using "name" as the key | ||
.chain(parsed => { | ||
const props = parsed.get("props"); | ||
if (Immutable.List.isList(props)) { | ||
return props | ||
.foldMap( | ||
prop => | ||
prop.has("name") | ||
? Either.Right( | ||
Immutable.OrderedMap().set(prop.get("name"), prop) | ||
) | ||
: Either.Left( | ||
new Error( | ||
'Each prop must have a "name" key when "props" is an array.' | ||
) | ||
), | ||
Either.Right(Immutable.OrderedMap()) | ||
) | ||
.map(props => parsed.set("props", props)); | ||
} | ||
return Either.Right(parsed); | ||
}) | ||
.chain(parsed => | ||
parsed | ||
.get("imports") | ||
.traverse(Either.of, i => | ||
Either.of(path.resolve(path.dirname(file), i)) | ||
.chain(load) | ||
.chain(resolve) | ||
) | ||
.map(parsedImports => parsed.set("imports", parsedImports)) | ||
); | ||
@@ -69,2 +82,2 @@ module.exports = { | ||
resolve | ||
} | ||
}; |
// Copyright (c) 2015-present, salesforce.com, inc. All rights reserved | ||
// Licensed under BSD 3-Clause - see LICENSE.txt or git.io/sfdc-license | ||
const Immutable = require('immutable') | ||
const _ = require('lodash') | ||
const xml = require('xml') | ||
const _ = require("lodash"); | ||
const xml = require("xml"); | ||
module.exports = def => { | ||
const o = { | ||
'resources': def.get('props', Immutable.List()).toList().map(prop => { | ||
const key = (() => { | ||
switch (prop.type) { | ||
case 'color': | ||
return prop.type | ||
default: | ||
return 'property' | ||
} | ||
})() | ||
return { | ||
[key]: { | ||
_attr: { | ||
name: _.toUpper(prop.get('name')), | ||
category: prop.get('category'), | ||
value: prop.get('value') | ||
resources: def | ||
.get("props") | ||
.map(prop => { | ||
const key = (() => { | ||
switch (prop.type) { | ||
case "color": | ||
return prop.type; | ||
default: | ||
return "property"; | ||
} | ||
} | ||
} | ||
}).toJS() | ||
} | ||
return xml(o, { indent: ' ', declaration: true }) | ||
} | ||
})(); | ||
return { | ||
[key]: { | ||
_attr: { | ||
name: _.toUpper(prop.get("name")), | ||
category: prop.get("category"), | ||
value: prop.get("value") | ||
} | ||
} | ||
}; | ||
}) | ||
.toJS() | ||
}; | ||
return xml(o, { indent: " ", declaration: true }); | ||
}; |
// Copyright (c) 2015-present, salesforce.com, inc. All rights reserved | ||
// Licensed under BSD 3-Clause - see LICENSE.txt or git.io/sfdc-license | ||
const Immutable = require('immutable') | ||
const _ = require('lodash') | ||
const xml = require('xml') | ||
const Immutable = require("immutable"); | ||
const _ = require("lodash"); | ||
const xml = require("xml"); | ||
module.exports = def => { | ||
const o = { | ||
'aura:tokens': [{ | ||
_attr: Immutable.Map({ | ||
extends: def.get('auraExtends') | ||
}).filter(attr => typeof attr !== 'undefined').toJS() | ||
}] | ||
.concat( | ||
def.get('auraImports', Immutable.List()).map(name => { | ||
return { | ||
'aura:import': { _attr: { name } } | ||
} | ||
}).toJS() | ||
) | ||
.concat( | ||
def.get('props', Immutable.List()).toList().map(prop => { | ||
return { | ||
'aura:token': { | ||
_attr: Immutable.Map({ | ||
name: _.camelCase(prop.get('name')), | ||
property: prop.get('cssProperties', Immutable.List()).join(','), | ||
value: prop.get('value') | ||
}) | ||
.update(attrs => | ||
!attrs.get('property') | ||
? attrs.delete('property') | ||
: attrs) | ||
.toJS() | ||
} | ||
} | ||
}).toJS() | ||
) | ||
} | ||
return xml(o, { indent: ' ' }) | ||
} | ||
"aura:tokens": [ | ||
{ | ||
_attr: Immutable.Map({ | ||
extends: def.get("auraExtends") | ||
}) | ||
.filter(attr => typeof attr !== "undefined") | ||
.toJS() | ||
} | ||
] | ||
.concat( | ||
def | ||
.get("auraImports", Immutable.List()) | ||
.map(name => { | ||
return { | ||
"aura:import": { _attr: { name } } | ||
}; | ||
}) | ||
.toJS() | ||
) | ||
.concat( | ||
def | ||
.get("props") | ||
.map(prop => { | ||
return { | ||
"aura:token": { | ||
_attr: Immutable.Map({ | ||
name: _.camelCase(prop.get("name")), | ||
property: prop | ||
.get("cssProperties", Immutable.List()) | ||
.join(","), | ||
value: prop.get("value") | ||
}) | ||
.update( | ||
attrs => | ||
!attrs.get("property") ? attrs.delete("property") : attrs | ||
) | ||
.toJS() | ||
} | ||
}; | ||
}) | ||
.toJS() | ||
) | ||
}; | ||
return xml(o, { indent: " " }); | ||
}; |
// Copyright (c) 2015-present, salesforce.com, inc. All rights reserved | ||
// Licensed under BSD 3-Clause - see LICENSE.txt or git.io/sfdc-license | ||
let groupBy = require('lodash/groupBy') | ||
let camelCase = require('lodash/camelCase') | ||
let upperfirst = require('lodash/upperFirst') | ||
let groupBy = require("lodash/groupBy"); | ||
let camelCase = require("lodash/camelCase"); | ||
let upperfirst = require("lodash/upperFirst"); | ||
class Styleguide { | ||
constructor (json) { | ||
this.categories = groupBy(json.props, 'category') | ||
constructor(json) { | ||
this.categories = groupBy(json.props, "category"); | ||
} | ||
renderRowHeader (id, heading) { | ||
renderRowHeader(id, heading) { | ||
return ` | ||
@@ -23,7 +23,7 @@ <thead> | ||
</thead> | ||
` | ||
`; | ||
} | ||
renderRow (prop, example) { | ||
let name = camelCase(prop.name) | ||
renderRow(prop, example) { | ||
let name = camelCase(prop.name); | ||
return ` | ||
@@ -38,8 +38,8 @@ <tr> | ||
${example} | ||
<td>${prop.comment ? prop.comment : ''}</td> | ||
<td>${prop.comment ? prop.comment : ""}</td> | ||
</tr> | ||
` | ||
`; | ||
} | ||
renderSpacing (props) { | ||
renderSpacing(props) { | ||
return props.map(prop => { | ||
@@ -50,8 +50,8 @@ let example = ` | ||
</td> | ||
` | ||
return this.renderRow(prop, example) | ||
}) | ||
`; | ||
return this.renderRow(prop, example); | ||
}); | ||
} | ||
renderSizing (props) { | ||
renderSizing(props) { | ||
return props.map(prop => { | ||
@@ -62,8 +62,8 @@ let example = ` | ||
</td> | ||
` | ||
return this.renderRow(prop, example) | ||
}) | ||
`; | ||
return this.renderRow(prop, example); | ||
}); | ||
} | ||
renderFont (props) { | ||
renderFont(props) { | ||
return props.map(prop => { | ||
@@ -76,8 +76,8 @@ let example = ` | ||
</td> | ||
` | ||
return this.renderRow(prop, example) | ||
}) | ||
`; | ||
return this.renderRow(prop, example); | ||
}); | ||
} | ||
renderFontStyle (props) { | ||
renderFontStyle(props) { | ||
return props.map(prop => { | ||
@@ -90,8 +90,8 @@ let example = ` | ||
</td> | ||
` | ||
return this.renderRow(prop, example) | ||
}) | ||
`; | ||
return this.renderRow(prop, example); | ||
}); | ||
} | ||
renderFontWeight (props) { | ||
renderFontWeight(props) { | ||
return props.map(prop => { | ||
@@ -104,8 +104,8 @@ let example = ` | ||
</td> | ||
` | ||
return this.renderRow(prop, example) | ||
}) | ||
`; | ||
return this.renderRow(prop, example); | ||
}); | ||
} | ||
renderFontSize (props) { | ||
renderFontSize(props) { | ||
return props.map(prop => { | ||
@@ -118,10 +118,10 @@ let example = ` | ||
</td> | ||
` | ||
return this.renderRow(prop, example) | ||
}) | ||
`; | ||
return this.renderRow(prop, example); | ||
}); | ||
} | ||
renderLineHeight (props) { | ||
renderLineHeight(props) { | ||
return props.map(prop => { | ||
let vHeight = !isNaN(prop.value) ? `${prop.value}em` : prop.value | ||
let vHeight = !isNaN(prop.value) ? `${prop.value}em` : prop.value; | ||
let example = ` | ||
@@ -135,8 +135,8 @@ <td> | ||
</td> | ||
` | ||
return this.renderRow(prop, example) | ||
}) | ||
`; | ||
return this.renderRow(prop, example); | ||
}); | ||
} | ||
renderFontFamily (props) { | ||
renderFontFamily(props) { | ||
return props.map(prop => { | ||
@@ -149,22 +149,22 @@ let example = ` | ||
</td> | ||
` | ||
return this.renderRow(prop, example) | ||
}) | ||
`; | ||
return this.renderRow(prop, example); | ||
}); | ||
} | ||
renderBorderStyle (props) { | ||
renderBorderStyle(props) { | ||
return props.map(prop => { | ||
let example = `<td style="border: ${prop.value};"></td>` | ||
return this.renderRow(prop, example) | ||
}) | ||
let example = `<td style="border: ${prop.value};"></td>`; | ||
return this.renderRow(prop, example); | ||
}); | ||
} | ||
renderBorderColor (props) { | ||
renderBorderColor(props) { | ||
return props.map(prop => { | ||
let example = `<td style="border: 2px solid ${prop.value};"></td>` | ||
return this.renderRow(prop, example) | ||
}) | ||
let example = `<td style="border: 2px solid ${prop.value};"></td>`; | ||
return this.renderRow(prop, example); | ||
}); | ||
} | ||
renderHrColor (props) { | ||
renderHrColor(props) { | ||
return props.map(prop => { | ||
@@ -175,10 +175,10 @@ let example = ` | ||
</td> | ||
` | ||
return this.renderRow(prop, example) | ||
}) | ||
`; | ||
return this.renderRow(prop, example); | ||
}); | ||
} | ||
renderRadius (props) { | ||
renderRadius(props) { | ||
return props.map(prop => { | ||
let name = camelCase(prop.name) | ||
let name = camelCase(prop.name); | ||
let example = ` | ||
@@ -188,8 +188,8 @@ <td> | ||
</td> | ||
` | ||
return this.renderRow(prop, example) | ||
}) | ||
`; | ||
return this.renderRow(prop, example); | ||
}); | ||
} | ||
renderBorderRadius (props) { | ||
renderBorderRadius(props) { | ||
return props.map(prop => { | ||
@@ -200,43 +200,43 @@ let example = ` | ||
</td> | ||
` | ||
return this.renderRow(prop, example) | ||
}) | ||
`; | ||
return this.renderRow(prop, example); | ||
}); | ||
} | ||
renderBackgroundColor (props) { | ||
renderBackgroundColor(props) { | ||
return props.map(prop => { | ||
let example = `<td style="background-color: ${prop.value}; border: 1px solid #f6f6f6;"></td>` | ||
return this.renderRow(prop, example) | ||
}) | ||
let example = `<td style="background-color: ${prop.value}; border: 1px solid #f6f6f6;"></td>`; | ||
return this.renderRow(prop, example); | ||
}); | ||
} | ||
renderGradient (props) { | ||
renderGradient(props) { | ||
return props.map(prop => { | ||
let example = `<td style="background: ${prop.value};"></td>` | ||
return this.renderRow(prop, example) | ||
}) | ||
let example = `<td style="background: ${prop.value};"></td>`; | ||
return this.renderRow(prop, example); | ||
}); | ||
} | ||
renderBackgroundGradient (props) { | ||
renderBackgroundGradient(props) { | ||
return props.map(prop => { | ||
let example = `<td style="background-image: ${prop.value};"></td>` | ||
return this.renderRow(prop, example) | ||
}) | ||
let example = `<td style="background-image: ${prop.value};"></td>`; | ||
return this.renderRow(prop, example); | ||
}); | ||
} | ||
renderDropShadow (props) { | ||
renderDropShadow(props) { | ||
return props.map(prop => { | ||
let example = `<td style="box-shadow: ${prop.value};"></td>` | ||
return this.renderRow(prop, example) | ||
}) | ||
let example = `<td style="box-shadow: ${prop.value};"></td>`; | ||
return this.renderRow(prop, example); | ||
}); | ||
} | ||
renderBoxShadow (props) { | ||
renderBoxShadow(props) { | ||
return props.map(prop => { | ||
let example = `<td style="box-shadow: ${prop.value};"></td>` | ||
return this.renderRow(prop, example) | ||
}) | ||
let example = `<td style="box-shadow: ${prop.value};"></td>`; | ||
return this.renderRow(prop, example); | ||
}); | ||
} | ||
renderTextColor (props) { | ||
renderTextColor(props) { | ||
return props.map(prop => { | ||
@@ -247,8 +247,8 @@ let example = ` | ||
</td> | ||
` | ||
return this.renderRow(prop, example) | ||
}) | ||
`; | ||
return this.renderRow(prop, example); | ||
}); | ||
} | ||
renderTextShadow (props) { | ||
renderTextShadow(props) { | ||
return props.map(prop => { | ||
@@ -259,26 +259,28 @@ let example = ` | ||
</td> | ||
` | ||
return this.renderRow(prop, example) | ||
}) | ||
`; | ||
return this.renderRow(prop, example); | ||
}); | ||
} | ||
renderTime (props) { | ||
renderTime(props) { | ||
return props.map(prop => { | ||
let example = `<td></td>` | ||
return this.renderRow(prop, example) | ||
}) | ||
let example = `<td></td>`; | ||
return this.renderRow(prop, example); | ||
}); | ||
} | ||
renderMediaQuery (props) { | ||
renderMediaQuery(props) { | ||
return props.map(prop => { | ||
let example = `<td></td>` | ||
return this.renderRow(prop, example) | ||
}) | ||
let example = `<td></td>`; | ||
return this.renderRow(prop, example); | ||
}); | ||
} | ||
renderSection (type, heading, fn) { | ||
let props = this.categories[type] | ||
if (!props) { return '' } | ||
let name = upperfirst(camelCase(type)) | ||
let render = typeof fn === 'function' ? fn : this[`render${name}`] | ||
renderSection(type, heading, fn) { | ||
let props = this.categories[type]; | ||
if (!props) { | ||
return ""; | ||
} | ||
let name = upperfirst(camelCase(type)); | ||
let render = typeof fn === "function" ? fn : this[`render${name}`]; | ||
return ` | ||
@@ -289,3 +291,6 @@ <section> | ||
<tbody> | ||
${render.call(this, props).join('').trim()} | ||
${render | ||
.call(this, props) | ||
.join("") | ||
.trim()} | ||
</tbody> | ||
@@ -295,6 +300,6 @@ </table> | ||
</section> | ||
` | ||
`; | ||
} | ||
render () { | ||
render() { | ||
return ` | ||
@@ -415,26 +420,33 @@ <!DOCTYPE html> | ||
<main role="main"> | ||
${this.renderSection('sizing', 'Sizing')} | ||
${this.renderSection('spacing', 'Spacing')} | ||
${this.renderSection('font', 'Fonts')} | ||
${this.renderSection('font-style', 'Font Styles')} | ||
${this.renderSection('font-weight', 'Font Weights')} | ||
${this.renderSection('font-size', 'Font Sizes')} | ||
${this.renderSection('line-height', 'Line Heights')} | ||
${this.renderSection('font-families', 'Font Families')} | ||
${this.renderSection('border-style', 'Border Styles')} | ||
${this.renderSection('border-color', 'Border Colors')} | ||
${this.renderSection('radius', 'Radius')} | ||
${this.renderSection('border-radius', 'Border Radii')} | ||
${this.renderSection('hr-color', 'Horizontal Rule Colors')} | ||
${this.renderSection('background-color', 'Background Colors')} | ||
${this.renderSection('gradient', 'Gradients')} | ||
${this.renderSection('background-gradient', 'Background Gradients')} | ||
${this.renderSection('drop-shadow', 'Drop Shadows')} | ||
${this.renderSection('box-shadow', 'Box Shadows')} | ||
${this.renderSection('inner-shadow', 'Inner Drop Shadows', this.renderDropShadow)} | ||
${this.renderSection('box-shadow', 'Box Shadows')} | ||
${this.renderSection('text-color', 'Text Colors')} | ||
${this.renderSection('text-shadow', 'Text Shadows')} | ||
${this.renderSection('time', 'Time')} | ||
${this.renderSection('media-query', 'Media Queries')} | ||
${this.renderSection("sizing", "Sizing")} | ||
${this.renderSection("spacing", "Spacing")} | ||
${this.renderSection("font", "Fonts")} | ||
${this.renderSection("font-style", "Font Styles")} | ||
${this.renderSection("font-weight", "Font Weights")} | ||
${this.renderSection("font-size", "Font Sizes")} | ||
${this.renderSection("line-height", "Line Heights")} | ||
${this.renderSection("font-families", "Font Families")} | ||
${this.renderSection("border-style", "Border Styles")} | ||
${this.renderSection("border-color", "Border Colors")} | ||
${this.renderSection("radius", "Radius")} | ||
${this.renderSection("border-radius", "Border Radii")} | ||
${this.renderSection("hr-color", "Horizontal Rule Colors")} | ||
${this.renderSection("background-color", "Background Colors")} | ||
${this.renderSection("gradient", "Gradients")} | ||
${this.renderSection( | ||
"background-gradient", | ||
"Background Gradients" | ||
)} | ||
${this.renderSection("drop-shadow", "Drop Shadows")} | ||
${this.renderSection("box-shadow", "Box Shadows")} | ||
${this.renderSection( | ||
"inner-shadow", | ||
"Inner Drop Shadows", | ||
this.renderDropShadow | ||
)} | ||
${this.renderSection("box-shadow", "Box Shadows")} | ||
${this.renderSection("text-color", "Text Colors")} | ||
${this.renderSection("text-shadow", "Text Shadows")} | ||
${this.renderSection("time", "Time")} | ||
${this.renderSection("media-query", "Media Queries")} | ||
</main> | ||
@@ -444,9 +456,9 @@ </div> | ||
</html> | ||
` | ||
`; | ||
} | ||
} | ||
module.exports = (json) => { | ||
const styleguide = new Styleguide(json.toJS()) | ||
return styleguide.render() | ||
} | ||
module.exports = json => { | ||
const styleguide = new Styleguide(json.toJS()); | ||
return styleguide.render(); | ||
}; |
// Copyright (c) 2015-present, salesforce.com, inc. All rights reserved | ||
// Licensed under BSD 3-Clause - see LICENSE.txt or git.io/sfdc-license | ||
const camelCase = require('lodash/camelCase') | ||
const camelCase = require("lodash/camelCase"); | ||
module.exports = (result) => { | ||
module.exports = result => { | ||
let output = { | ||
properties: result.get('props').toList().map(prop => { | ||
return prop | ||
.update('name', camelCase) | ||
.delete('originalValue') | ||
}).toJS() | ||
} | ||
return JSON.stringify(output, null, 2) | ||
} | ||
properties: result | ||
.get("props") | ||
.map(prop => { | ||
return prop.update("name", camelCase).delete("originalValue"); | ||
}) | ||
.toJS() | ||
}; | ||
return JSON.stringify(output, null, 2); | ||
}; |
@@ -1,8 +0,13 @@ | ||
const Immutable = require('immutable') | ||
const Immutable = require("immutable"); | ||
module.exports = def => | ||
JSON.stringify( | ||
def.get('props').reduce((a, b, c) => a.set(c, b.get('value')), Immutable.Map()), | ||
def | ||
.get("props") | ||
.reduce( | ||
(a, b, c) => a.set(b.get("name"), b.get("value")), | ||
Immutable.OrderedMap() | ||
), | ||
null, | ||
2 | ||
) | ||
); |
// Copyright (c) 2015-present, salesforce.com, inc. All rights reserved | ||
// Licensed under BSD 3-Clause - see LICENSE.txt or git.io/sfdc-license | ||
const Immutable = require("immutable"); | ||
const toMap = list => | ||
list.reduce((a, b) => a.set(b.get("name"), b), Immutable.OrderedMap()); | ||
module.exports = def => | ||
JSON.stringify( | ||
def.delete('meta').toJS(), | ||
def | ||
.delete("meta") | ||
.update("props", toMap) | ||
.toJS(), | ||
null, | ||
2 | ||
) | ||
); |
152
lib/index.js
// Copyright (c) 2015-present, salesforce.com, inc. All rights reserved | ||
// Licensed under BSD 3-Clause - see LICENSE.txt or git.io/sfdc-license | ||
const { constant } = require('core.lambda') | ||
const Either = require('data.either') | ||
const Immutable = require('immutable') | ||
const { constant } = require("core.lambda"); | ||
const Either = require("data.either"); | ||
const Immutable = require("immutable"); | ||
const { | ||
isFunction, | ||
isString | ||
} = require('lodash') | ||
const { isFunction, isString } = require("lodash"); | ||
const effects = require('./effects') | ||
const definition = require('./definition') | ||
const effects = require("./effects"); | ||
const definition = require("./definition"); | ||
@@ -22,3 +19,3 @@ const { | ||
getFormat | ||
} = require('./register') | ||
} = require("./register"); | ||
@@ -29,3 +26,3 @@ // (...Function) -> Map -> Either Err Map | ||
.traverse(Either.of, fn => fn(options)) | ||
.map(constant(options)) | ||
.map(constant(options)); | ||
@@ -38,44 +35,47 @@ // (Function, String, String, Bool) -> Map -> Either Err Map | ||
? Either.Right(options) | ||
: Either.Left(`Invalid option "${key}": ${message}`) | ||
: Either.Left(`Invalid option "${key}": ${message}`); | ||
// Map -> Either Err Map | ||
const validateTransform = options => | ||
Either | ||
.fromNullable(options) | ||
Either.fromNullable(options) | ||
.leftMap(() => `No options?`) | ||
.map(Immutable.fromJS) | ||
.chain(validate( | ||
v(isString, 'file', 'must be a path'), | ||
v(isString, 'data', 'must be a string', false) | ||
)) | ||
.chain(options => | ||
options.has('type') | ||
? getTransform(options.get('type')).map(transforms => | ||
options.set('transforms', transforms) | ||
) | ||
: Either.of(options.set('transforms', Immutable.List())) | ||
.chain( | ||
validate( | ||
v(isString, "file", "must be a path"), | ||
v(isString, "data", "must be a string", false) | ||
) | ||
) | ||
.chain( | ||
options => | ||
options.has("type") | ||
? getTransform(options.get("type")).map(transforms => | ||
options.set("transforms", transforms) | ||
) | ||
: Either.of(options.set("transforms", Immutable.List())) | ||
); | ||
// Map -> Either Err Map | ||
const transform = options => validateTransform(options) | ||
.chain(options => | ||
effects.resolve({ | ||
file: options.get('file'), | ||
data: options.get('data') | ||
}) | ||
.chain(parsed => | ||
definition | ||
.transform(parsed, options) | ||
.map(def => | ||
def.set('meta', Immutable.Map({ | ||
file: options.get('file') | ||
})) | ||
const transform = options => | ||
validateTransform(options).chain(options => | ||
effects | ||
.resolve({ | ||
file: options.get("file"), | ||
data: options.get("data") | ||
}) | ||
.chain(parsed => | ||
definition.transform(parsed, options).map(def => | ||
def.set( | ||
"meta", | ||
Immutable.Map({ | ||
file: options.get("file") | ||
}) | ||
) | ||
) | ||
) | ||
) | ||
) | ||
); | ||
// Map -> Either Err Map | ||
const validateFormat = options => | ||
Either | ||
.fromNullable(options) | ||
Either.fromNullable(options) | ||
.leftMap(() => `No options?`) | ||
@@ -89,49 +89,43 @@ .map(Immutable.fromJS) | ||
) | ||
.chain(validate( | ||
v(Immutable.Map.isMap, 'data', 'must be an Immutable.Map'), | ||
v(isFunction, 'propsFilter', 'must be a function'), | ||
v(isFunction, 'propsMap', 'must be a function') | ||
)) | ||
.chain( | ||
validate( | ||
v(Immutable.Map.isMap, "data", "must be an Immutable.Map"), | ||
v(isFunction, "propsFilter", "must be a function"), | ||
v(isFunction, "propsMap", "must be a function") | ||
) | ||
) | ||
.chain(options => | ||
getFormat(options.get('type')) | ||
.map(format => | ||
options.set('format', format) | ||
) | ||
) | ||
getFormat(options.get("type")).map(format => | ||
options.set("format", format) | ||
) | ||
); | ||
// Map -> Either Err Map | ||
const format = options => validateFormat(options) | ||
.map(options => { | ||
const format = options.get('format') | ||
const propsFilter = options.get('propsFilter') | ||
const propsMap = options.get('propsMap') | ||
const data = options | ||
.get('data') | ||
.update('props', props => props | ||
const format = options => | ||
validateFormat(options).map(options => { | ||
const format = options.get("format"); | ||
const propsFilter = options.get("propsFilter"); | ||
const propsMap = options.get("propsMap"); | ||
const data = options.get("data").update("props", props => | ||
props | ||
.filter(propsFilter) | ||
.map(propsMap) | ||
) | ||
return format(data) | ||
}) | ||
.toList() | ||
); | ||
return format(data); | ||
}); | ||
const convertSync = options => | ||
transform(options.transform) | ||
.chain(data => | ||
format(Object.assign({}, options.format, { data })) | ||
) | ||
.fold( | ||
e => { | ||
if (isString(e)) throw new Error(e) | ||
throw e | ||
}, | ||
r => r | ||
) | ||
.chain(data => format(Object.assign({}, options.format, { data }))) | ||
.fold(e => { | ||
if (isString(e)) throw new Error(e); | ||
throw e; | ||
}, r => r); | ||
const convert = options => | ||
Either | ||
.try(convertSync)(options) | ||
.fold( | ||
e => Promise.reject(e), | ||
r => Promise.resolve(r) | ||
) | ||
Either.try(convertSync)(options).fold( | ||
e => Promise.reject(e), | ||
r => Promise.resolve(r) | ||
); | ||
@@ -146,2 +140,2 @@ module.exports = { | ||
convertSync | ||
} | ||
}; |
// Copyright (c) 2015-present, salesforce.com, inc. All rights reserved | ||
// Licensed under BSD 3-Clause - see LICENSE.txt or git.io/sfdc-license | ||
const Either = require('data.either') | ||
const fs = require('fs') | ||
const glob = require('glob') | ||
const handlebars = require('handlebars') | ||
const Immutable = require('immutable') | ||
const path = require('path') | ||
const Either = require("data.either"); | ||
const fs = require("fs"); | ||
const glob = require("glob"); | ||
const handlebars = require("handlebars"); | ||
const Immutable = require("immutable"); | ||
const path = require("path"); | ||
const { | ||
isString, | ||
isFunction | ||
} = require('lodash') | ||
const { isString, isFunction } = require("lodash"); | ||
const { | ||
kebabCase | ||
} = require('./util') | ||
const { kebabCase } = require("./util"); | ||
@@ -24,7 +19,7 @@ // ////////////////////////////////////////////////////////////////// | ||
require('handlebars-helpers')({ | ||
require("handlebars-helpers")({ | ||
handlebars | ||
}) | ||
}); | ||
handlebars.registerHelper('kebabcase', kebabCase) | ||
handlebars.registerHelper("kebabcase", kebabCase); | ||
@@ -35,45 +30,53 @@ // ////////////////////////////////////////////////////////////////// | ||
let VALUE_TRANSFORMS = Immutable.Map() | ||
let TRANSFORMS = Immutable.Map() | ||
let FORMATS = Immutable.Map() | ||
let FORMAT_TEMPLATES = Immutable.Map() | ||
let VALUE_TRANSFORMS = Immutable.Map(); | ||
let TRANSFORMS = Immutable.Map(); | ||
let FORMATS = Immutable.Map(); | ||
let FORMAT_TEMPLATES = Immutable.Map(); | ||
const registerValueTransform = (name, predicate, transform) => { | ||
if (!isString(name)) { | ||
throw new Error('valueTransform name must be a string') | ||
throw new Error("valueTransform name must be a string"); | ||
} | ||
if (!isFunction(predicate)) { | ||
throw new Error('valueTransform predicate must be a function') | ||
throw new Error("valueTransform predicate must be a function"); | ||
} | ||
if (!isFunction(transform)) { | ||
throw new Error('valueTransform transform must be a function') | ||
throw new Error("valueTransform transform must be a function"); | ||
} | ||
VALUE_TRANSFORMS = VALUE_TRANSFORMS.set(name, Immutable.fromJS({ | ||
predicate, | ||
transform | ||
})) | ||
} | ||
VALUE_TRANSFORMS = VALUE_TRANSFORMS.set( | ||
name, | ||
Immutable.fromJS({ | ||
predicate, | ||
transform | ||
}) | ||
); | ||
}; | ||
const registerTransform = (name, valueTransforms) => { | ||
if (!isString(name)) { | ||
throw new Error('transform name must be a string') | ||
throw new Error("transform name must be a string"); | ||
} | ||
if (!Array.isArray(valueTransforms)) { | ||
throw new Error('valueTransforms must be an array of registered value transforms') | ||
throw new Error( | ||
"valueTransforms must be an array of registered value transforms" | ||
); | ||
} | ||
valueTransforms.forEach(t => { | ||
if (!VALUE_TRANSFORMS.has(t)) { | ||
throw new Error('valueTransforms must be an array of registered value transforms') | ||
throw new Error( | ||
"valueTransforms must be an array of registered value transforms" | ||
); | ||
} | ||
}) | ||
TRANSFORMS = TRANSFORMS.set(name, | ||
}); | ||
TRANSFORMS = TRANSFORMS.set( | ||
name, | ||
Immutable.List(valueTransforms).map(valueTransform => | ||
VALUE_TRANSFORMS.get(valueTransform) | ||
) | ||
) | ||
} | ||
); | ||
}; | ||
const registerFormat = (name, formatter) => { | ||
if (!isString(name)) { | ||
throw new Error('format name must be a string') | ||
throw new Error("format name must be a string"); | ||
} | ||
@@ -84,14 +87,14 @@ if (isString(formatter)) { | ||
handlebars.compile(formatter) | ||
) | ||
); | ||
FORMATS = FORMATS.set(name, json => | ||
FORMAT_TEMPLATES.get(name)(json.toJS()) | ||
) | ||
return | ||
); | ||
return; | ||
} | ||
if (isFunction(formatter)) { | ||
FORMATS = FORMATS.set(name, formatter) | ||
return | ||
FORMATS = FORMATS.set(name, formatter); | ||
return; | ||
} | ||
throw new Error('format formatter must be a string or function') | ||
} | ||
throw new Error("format formatter must be a string or function"); | ||
}; | ||
@@ -104,54 +107,46 @@ // ////////////////////////////////////////////////////////////////// | ||
glob | ||
.sync(path.resolve(__dirname, 'transforms', '**/*.js')) | ||
.forEach(file => { | ||
const transforms = require(file) | ||
Object.keys(transforms).forEach(name => { | ||
const t = transforms[name] | ||
registerValueTransform(name, t.predicate, t.transform) | ||
}) | ||
}) | ||
glob.sync(path.resolve(__dirname, "transforms", "**/*.js")).forEach(file => { | ||
const transforms = require(file); | ||
Object.keys(transforms).forEach(name => { | ||
const t = transforms[name]; | ||
registerValueTransform(name, t.predicate, t.transform); | ||
}); | ||
}); | ||
// Transforms | ||
registerTransform('raw', []) | ||
registerTransform("raw", []); | ||
registerTransform('web', [ | ||
'color/rgb' | ||
]) | ||
registerTransform("web", ["color/rgb"]); | ||
registerTransform('ios', [ | ||
'color/rgb', | ||
'relative/pixelValue', | ||
'percentage/float' | ||
]) | ||
registerTransform("ios", [ | ||
"color/rgb", | ||
"relative/pixelValue", | ||
"percentage/float" | ||
]); | ||
registerTransform('android', [ | ||
'color/hex8argb', | ||
'relative/pixelValue', | ||
'percentage/float' | ||
]) | ||
registerTransform("android", [ | ||
"color/hex8argb", | ||
"relative/pixelValue", | ||
"percentage/float" | ||
]); | ||
registerTransform('aura', [ | ||
'color/hex' | ||
]) | ||
registerTransform("aura", ["color/hex"]); | ||
// Formats | ||
glob | ||
.sync(path.resolve(__dirname, 'formats', '**/*.{js,hbs}')) | ||
.forEach(file => { | ||
const ext = path.extname(file) | ||
const name = path.basename(file, ext) | ||
switch (ext) { | ||
case '.js': | ||
registerFormat(name, require(file)) | ||
break | ||
case '.hbs': | ||
registerFormat(name, fs.readFileSync(file, 'utf8')) | ||
break | ||
default: | ||
throw new Error(`Unrecognized format "${name}${ext}"`) | ||
} | ||
}) | ||
glob.sync(path.resolve(__dirname, "formats", "**/*.{js,hbs}")).forEach(file => { | ||
const ext = path.extname(file); | ||
const name = path.basename(file, ext); | ||
switch (ext) { | ||
case ".js": | ||
registerFormat(name, require(file)); | ||
break; | ||
case ".hbs": | ||
registerFormat(name, fs.readFileSync(file, "utf8")); | ||
break; | ||
default: | ||
throw new Error(`Unrecognized format "${name}${ext}"`); | ||
} | ||
}); | ||
@@ -162,13 +157,11 @@ module.exports = { | ||
registerFormat, | ||
getValueTransform: name => | ||
Either | ||
.fromNullable(VALUE_TRANSFORMS.get(name)), | ||
getValueTransform: name => Either.fromNullable(VALUE_TRANSFORMS.get(name)), | ||
getTransform: name => | ||
Either | ||
.fromNullable(TRANSFORMS.get(name)) | ||
.leftMap(() => `Transform "${name}" is not registered`), | ||
Either.fromNullable(TRANSFORMS.get(name)).leftMap( | ||
() => `Transform "${name}" is not registered` | ||
), | ||
getFormat: name => | ||
Either | ||
.fromNullable(FORMATS.get(name)) | ||
.leftMap(() => `Format "${name}" is not registered`) | ||
} | ||
Either.fromNullable(FORMATS.get(name)).leftMap( | ||
() => `Format "${name}" is not registered` | ||
) | ||
}; |
// Copyright (c) 2015-present, salesforce.com, inc. All rights reserved | ||
// Licensed under BSD 3-Clause - see LICENSE.txt or git.io/sfdc-license | ||
const tinycolor = require('tinycolor2') | ||
const tinycolor = require("tinycolor2"); | ||
const isType = type => prop => | ||
prop.get('type') === type | ||
const isType = type => prop => prop.get("type") === type; | ||
const toColor = prop => | ||
tinycolor(prop.get('value')) | ||
const toColor = prop => tinycolor(prop.get("value")); | ||
module.exports = { | ||
'color/rgb': { | ||
predicate: isType('color'), | ||
transform: prop => | ||
toColor(prop).toRgbString() | ||
"color/rgb": { | ||
predicate: isType("color"), | ||
transform: prop => toColor(prop).toRgbString() | ||
}, | ||
'color/hex': { | ||
predicate: isType('color'), | ||
transform: prop => | ||
toColor(prop).toHexString() | ||
"color/hex": { | ||
predicate: isType("color"), | ||
transform: prop => toColor(prop).toHexString() | ||
}, | ||
@@ -26,6 +22,5 @@ // RRGGBBAA Hex8 notation | ||
// https://drafts.csswg.org/css-color-4/#hex-notation | ||
'color/hex8rgba': { | ||
predicate: isType('color'), | ||
transform: prop => | ||
toColor(prop).toHex8String() | ||
"color/hex8rgba": { | ||
predicate: isType("color"), | ||
transform: prop => toColor(prop).toHex8String() | ||
}, | ||
@@ -35,9 +30,9 @@ // AARRGGBB Hex8 notation | ||
// https://developer.android.com/reference/android/graphics/Color.html | ||
'color/hex8argb': { | ||
predicate: isType('color'), | ||
"color/hex8argb": { | ||
predicate: isType("color"), | ||
transform: prop => | ||
toColor(prop) | ||
.toHex8String() | ||
.replace(/^#(.{6})(.{2})/, '#$2$1') | ||
.replace(/^#(.{6})(.{2})/, "#$2$1") | ||
} | ||
} | ||
}; |
// Copyright (c) 2015-present, salesforce.com, inc. All rights reserved | ||
// Licensed under BSD 3-Clause - see LICENSE.txt or git.io/sfdc-license | ||
const { | ||
PERCENTAGE_PATTERN | ||
} = require('../constants') | ||
const { PERCENTAGE_PATTERN } = require("../constants"); | ||
module.exports = { | ||
'percentage/float': { | ||
predicate: prop => | ||
/%/.test(prop.get('value')), | ||
"percentage/float": { | ||
predicate: prop => /%/.test(prop.get("value")), | ||
transform: prop => | ||
prop | ||
.get('value') | ||
.replace(PERCENTAGE_PATTERN, (match, number) => parseFloat(number / 100)) | ||
.get("value") | ||
.replace(PERCENTAGE_PATTERN, (match, number) => | ||
parseFloat(number / 100) | ||
) | ||
} | ||
} | ||
}; |
// Copyright (c) 2015-present, salesforce.com, inc. All rights reserved | ||
// Licensed under BSD 3-Clause - see LICENSE.txt or git.io/sfdc-license | ||
const { | ||
isRelativeSpacing, | ||
remToPx | ||
} = require('../util') | ||
const { isRelativeSpacing, remToPx } = require("../util"); | ||
const convertRemToPx = (prop) => { | ||
const baseFontPercentage = typeof prop.getIn(['meta', 'baseFontPercentage']) === 'number' | ||
? prop.getIn(['meta', 'baseFontPercentage']) : 100 | ||
const baseFontPixel = typeof prop.getIn(['meta', 'baseFontPixel']) === 'number' | ||
? prop.getIn(['meta', 'baseFontPixel']) : 16 | ||
return remToPx(prop.get('value'), baseFontPercentage, baseFontPixel) | ||
} | ||
const convertRemToPx = prop => { | ||
const baseFontPercentage = | ||
typeof prop.getIn(["meta", "baseFontPercentage"]) === "number" | ||
? prop.getIn(["meta", "baseFontPercentage"]) | ||
: 100; | ||
const baseFontPixel = | ||
typeof prop.getIn(["meta", "baseFontPixel"]) === "number" | ||
? prop.getIn(["meta", "baseFontPixel"]) | ||
: 16; | ||
return remToPx(prop.get("value"), baseFontPercentage, baseFontPixel); | ||
}; | ||
module.exports = { | ||
'relative/pixel': { | ||
predicate: prop => isRelativeSpacing(prop.get('value')), | ||
"relative/pixel": { | ||
predicate: prop => isRelativeSpacing(prop.get("value")), | ||
transform: prop => convertRemToPx(prop) | ||
}, | ||
'relative/pixelValue': { | ||
predicate: prop => isRelativeSpacing(prop.get('value')), | ||
transform: prop => convertRemToPx(prop).replace(/px$/g, '') | ||
"relative/pixelValue": { | ||
predicate: prop => isRelativeSpacing(prop.get("value")), | ||
transform: prop => convertRemToPx(prop).replace(/px$/g, "") | ||
} | ||
} | ||
}; |
// Copyright (c) 2015-present, salesforce.com, inc. All rights reserved | ||
// Licensed under BSD 3-Clause - see LICENSE.txt or git.io/sfdc-license | ||
const Immutable = require('immutable') | ||
const noCase = require('no-case') | ||
const Immutable = require("immutable"); | ||
const noCase = require("no-case"); | ||
const allMatches = (s, pattern) => { | ||
let matches = Immutable.List() | ||
let match | ||
let matches = Immutable.List(); | ||
let match; | ||
while ((match = pattern.exec(s)) !== null) { | ||
matches = matches.push(match) | ||
matches = matches.push(match); | ||
} | ||
return matches | ||
} | ||
return matches; | ||
}; | ||
const isRelativeSpacing = value => /rem$/.test(value) | ||
const isRelativeSpacing = value => /rem$/.test(value); | ||
const remToPx = (rem, baseFontPercentage, baseFontPixel) => | ||
((parseFloat(rem.replace(/rem/g, '')) * baseFontPixel) * (baseFontPercentage / 100)) + 'px' | ||
parseFloat(rem.replace(/rem/g, "")) * | ||
baseFontPixel * | ||
(baseFontPercentage / 100) + | ||
"px"; | ||
const kebabCase = string => | ||
noCase(string, null, '-') | ||
const kebabCase = string => noCase(string, null, "-"); | ||
@@ -29,2 +31,2 @@ module.exports = { | ||
kebabCase | ||
} | ||
}; |
{ | ||
"name": "theo", | ||
"version": "6.0.0-beta.5", | ||
"version": "6.0.0-beta.6", | ||
"license": "BSD-3-Clause", | ||
@@ -25,4 +25,12 @@ "description": "Design Tokens formatter", | ||
"test": "jest", | ||
"lint": "standard" | ||
"lint": "eslint . --format codeframe --ext .js", | ||
"precommit": "lint-staged" | ||
}, | ||
"lint-staged": { | ||
"*.js": [ | ||
"prettier --write", | ||
"npm run lint", | ||
"git add" | ||
] | ||
}, | ||
"engines": { | ||
@@ -47,3 +55,3 @@ "node": ">=6.3.1" | ||
"data.either": "1.5.1", | ||
"fs-extra": "^4.0.1", | ||
"fs-extra": "4.0.1", | ||
"glob": "7.1.2", | ||
@@ -62,13 +70,14 @@ "handlebars": "4.0.10", | ||
"devDependencies": { | ||
"eslint": "4.5.0", | ||
"eslint-config-prettier": "2.3.0", | ||
"eslint-config-standard": "10.2.1", | ||
"eslint-plugin-import": "2.7.0", | ||
"eslint-plugin-node": "5.1.1", | ||
"eslint-plugin-promise": "3.5.0", | ||
"eslint-plugin-standard": "3.0.1", | ||
"husky": "0.14.3", | ||
"jest": "20.0.4", | ||
"standard": "10.0.2" | ||
}, | ||
"standard": { | ||
"global": [ | ||
"describe", | ||
"it", | ||
"xit", | ||
"expect" | ||
] | ||
"lint-staged": "4.0.4", | ||
"prettier": "1.6.1" | ||
} | ||
} |
@@ -100,3 +100,3 @@ # <img src="https://raw.githubusercontent.com/salesforce-ux/theo/master/assets/theo.png" alt="Theo logo" width="28" /> Theo | ||
type ConvertOptions = { | ||
transform: TransformOpions, | ||
transform: TransformOptions, | ||
format: FormatOptions | ||
@@ -151,3 +151,3 @@ } | ||
Please refere to the [documentation of the CLI](https://github.com/salesforce-ux/theo/blob/master/CLI.md) | ||
Please refer to the [documentation of the CLI](https://github.com/salesforce-ux/theo/blob/master/CLI.md) | ||
@@ -154,0 +154,0 @@ ---- |
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 2 instances in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 2 instances in 1 package
57867
1266
11
1
+ Addedfs-extra@4.0.1(transitive)
+ Addedjsonfile@3.0.1(transitive)
- Removedfs-extra@4.0.3(transitive)
- Removedjsonfile@4.0.0(transitive)
Updatedfs-extra@4.0.1