Skip to content

Commit

Permalink
Split up build into build and generate
Browse files Browse the repository at this point in the history
  • Loading branch information
gossi committed Mar 30, 2020
1 parent 24684c3 commit 8a0cdfe
Show file tree
Hide file tree
Showing 8 changed files with 263 additions and 185 deletions.
14 changes: 11 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"name": "theemo",
"description": "The yordle powered theme automator",
"version": "0.0.2",
"license": "MIT",
"author": "Thomas Gossmann",
Expand All @@ -11,17 +12,24 @@
"bin"
],
"scripts": {
"clean": "rm -rf dist",
"build": "yarn clean && tsdx build --target node",
"start": "tsdx watch --target node",
"build": "tsdx build --target node",
"_test": "tsdx test",
"lint": "tsdx lint"
"lint:js": "eslint --ext ts,js src",
"lint:types": "tsc --noEmit",
"lint": "yarn lint:js && yarn lint:types",
"api": "yarn build && node scripts/make-docs.js",
"prepublish": "yarn build"
},
"bin": {
"theemo": "bin/theemo.js"
},
"dependencies": {
"color-converter": "1.4.1",
"commander": "^5.0.0",
"dotenv": "^8.2.0",
"esm": "3.2.25",
"figma-api": "^1.5.5",
"node-fetch": "^2.6.0",
"style-dictionary": "^2.8.3"
Expand All @@ -37,4 +45,4 @@
"tslib": "^1.11.1",
"typescript": "^3.8.3"
}
}
}
117 changes: 1 addition & 116 deletions src/build/index.ts
Original file line number Diff line number Diff line change
@@ -1,128 +1,13 @@
import Tool from '../tools/tool';
import BuildConfig, { SchemeConfig } from './config';
import fs from 'fs';
import path from 'path';
import { requireFile } from '../utils';

export default class BuildCommand {
private tool: Tool;
private config: BuildConfig;
private name: string;

constructor(tool: Tool, config: BuildConfig) {
constructor(tool: Tool) {
this.tool = tool;
this.config = config;

this.name = this.getThemeName();
}

private getThemeName() {
const data = requireFile('package.json');
return data.theemo?.name ?? data.name;
}

execute() {
this.tool.build();

this.postProcess();
}

private postProcess() {
if (!this.config.enabled) {
return;
}

const contents = [this.prepareBaseBlock(), ...this.prepareColorSchemes()];

if (!fs.existsSync(this.config.output)) {
fs.mkdirSync(this.config.output);
}

const outFile = path.join(this.config.output, `${this.name}.css`);
fs.writeFileSync(outFile, contents.join('\n'));

// update package.json with color schemes
if (this.config.colorSchemes) {
const packageJson = requireFile('package.json');
if (!packageJson.theemo) {
packageJson.theemo = {
name: packageJson.name
};
}
packageJson.theemo.colorSchemes = Object.keys(this.config.colorSchemes);

const data = JSON.stringify(packageJson, null, ' ');
const packageFile = path.join(process.cwd(), 'package.json');
fs.writeFileSync(packageFile, data);
}
}

private prepareBaseBlock() {
const basePath = path.join(
this.config.input,
this.config.base ?? 'base.css'
);

const baseBlock = this.getBlockFromFile(basePath);

const selector = `${this.config.activation === 'auto' ? ':root, ' : ''}.${
this.name
}`;

return `${selector} ${baseBlock}`;
}

private prepareColorSchemes() {
if (!this.config.colorSchemes) {
return '';
}

const contents = [];

for (const [scheme, config] of Object.entries(this.config.colorSchemes)) {
contents.push(
`/* Color Scheme: ${scheme} */\n${this.prepareColorScheme(
scheme,
config as SchemeConfig
)}`
);
}

return contents;
}

private prepareColorScheme(name: string, config: SchemeConfig) {
const filePath = path.join(this.config.input, config.file ?? `${name}.css`);
const block = this.getBlockFromFile(filePath);
const contents = [];

// queries
if (config.activation === 'auto') {
const queries = [];

if (name === 'light' || name === 'dark') {
queries.push(`(prefers-color-scheme: ${name})`);
}

if (name === this.config.defaultColorScheme) {
queries.push('(prefers-color-scheme: none)');
}

if (queries.length > 0) {
contents.push(`@media ${queries.join(', ')} {\n:root ${block}}`);
}
}

// manual activiate
if (config.manual) {
contents.push(`.${this.name}-${name} ${block}`);
}

return contents.join('\n\n');
}

private getBlockFromFile(file: string) {
const contents = fs.readFileSync(file, 'utf-8');
return contents.replace(':root ', '');
}
}
39 changes: 2 additions & 37 deletions src/config.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,7 @@
import SyncConfig from './sync/config';
import BuildConfig from './build/config';
import GenerateConfig from './generate/config';

export default interface TheemoConfig {
sync: SyncConfig;
build: BuildConfig;
generate?: GenerateConfig;
}

// export const DEFAULT_SYNC_CONFIG = {
// referencer: undefined,
// normalizeToken(token: Token): Token {
// const normalizedToken = { ...token };

// normalizedToken.name.replace(/\s/, '');
// if (normalizedToken.reference) {
// normalizedToken.reference.replace(/\s/, '');
// }

// return normalizedToken;
// },

// tool: Tool.StyleDictionary,
// rootDir: 'properties'
// };

// /**
// * From https://medium.com/terria/typescript-transforming-optional-properties-to-required-properties-that-may-be-undefined-7482cb4e1585
// */
// type Complete<T> = {
// [P in keyof Required<T>]: Pick<T, P> extends Required<Pick<T, P>>
// ? T[P]
// : T[P] | undefined;
// };

// export type FigmaConfig = Complete<FigmaUserConfig>;

// export function getConfig(config: FigmaUserConfig): FigmaConfig {
// return {
// ...config,
// ...DEFAULT_CONFIG
// };
// }
9 changes: 4 additions & 5 deletions src/build/config.ts → src/generate/config.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
export interface SchemeConfig {
file?: string;
activation: 'auto' | 'manual';
auto: boolean;
manual: boolean;
}

export default interface BuildConfig {
enabled: boolean;
export default interface GenerateConfig {
input: string;
output: string;
output?: string;
base?: string;
activation: 'auto' | 'manual';
auto: boolean;
defaultColorScheme?: string;
colorSchemes?: {
[key: string]: SchemeConfig;
Expand Down
116 changes: 116 additions & 0 deletions src/generate/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import GenerateConfig, { SchemeConfig } from './config';
import fs from 'fs';
import path from 'path';
import { requireFile } from '../utils';

export default class GenerateCommand {
private config: GenerateConfig;
private name: string;

constructor(config: GenerateConfig) {
this.config = config;

this.name = this.getThemeName();
}

private getThemeName() {
const data = requireFile('package.json');
return data.theemo?.name ?? data.name;
}

execute() {
const contents = [this.prepareBaseBlock(), ...this.prepareColorSchemes()];

const output = this.config.output ?? 'dist';

if (!fs.existsSync(output)) {
fs.mkdirSync(output);
}

const outFile = path.join(output, `${this.name}.css`);
fs.writeFileSync(outFile, contents.join('\n'));

// update package.json with color schemes
if (this.config.colorSchemes) {
const packageJson = requireFile('package.json');
if (!packageJson.theemo) {
packageJson.theemo = {
name: packageJson.name
};
}
packageJson.theemo.colorSchemes = Object.keys(this.config.colorSchemes);
packageJson.theemo.file = outFile;

const data = JSON.stringify(packageJson, null, ' ');
const packageFile = path.join(process.cwd(), 'package.json');
fs.writeFileSync(packageFile, data);
}
}

private prepareBaseBlock() {
const basePath = path.join(
this.config.input,
this.config.base ?? 'base.css'
);

const baseBlock = this.getBlockFromFile(basePath);

const selector = `${this.config.auto ? ':root, ' : ''}.${this.name}`;

return `${selector} ${baseBlock}`;
}

private prepareColorSchemes() {
if (!this.config.colorSchemes) {
return '';
}

const contents = [];

for (const [scheme, config] of Object.entries(this.config.colorSchemes)) {
contents.push(
`/* Color Scheme: ${scheme} */\n${this.prepareColorScheme(
scheme,
config as SchemeConfig
)}`
);
}

return contents;
}

private prepareColorScheme(name: string, config: SchemeConfig) {
const filePath = path.join(this.config.input, config.file ?? `${name}.css`);
const block = this.getBlockFromFile(filePath);
const contents = [];

// queries
if (config.auto) {
const queries = [];

if (name === 'light' || name === 'dark') {
queries.push(`(prefers-color-scheme: ${name})`);
}

if (name === this.config.defaultColorScheme) {
queries.push('(prefers-color-scheme: none)');
}

if (queries.length > 0) {
contents.push(`@media ${queries.join(', ')} {\n:root ${block}}`);
}
}

// manual activiate
if (config.manual || !config.auto) {
contents.push(`.${this.name}-${name} ${block}`);
}

return contents.join('\n\n');
}

private getBlockFromFile(file: string) {
const contents = fs.readFileSync(file, 'utf-8');
return contents.replace(':root ', '');
}
}
Loading

0 comments on commit 8a0cdfe

Please sign in to comment.