Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

theo

Package Overview
Dependencies
Maintainers
3
Versions
109
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

theo - npm Package Compare versions

Comparing version 6.0.0-beta.5 to 6.0.0-beta.6

54

bin/scripts/build.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 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
)
);
// 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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc