feat: use theme index to build themes

Sergey Onufrienko created

Change summary

styles/src/buildThemes.ts  | 30 ++++++---------
styles/src/colorSchemes.ts | 79 ----------------------------------------
styles/src/themeConfig.ts  |  8 +++
3 files changed, 19 insertions(+), 98 deletions(-)

Detailed changes

styles/src/buildThemes.ts 🔗

@@ -1,17 +1,21 @@
 import * as fs from "fs"
 import { tmpdir } from "os"
 import * as path from "path"
-import { colorSchemes, staffColorSchemes } from "./colorSchemes"
 import app from "./styleTree/app"
-import { ColorScheme } from "./themes/common/colorScheme"
+import { ColorScheme, createColorScheme } from "./themes/common/colorScheme"
 import snakeCase from "./utils/snakeCase"
+import { themes } from "./themes"
 
 const assetsDirectory = `${__dirname}/../../assets`
-const themeDirectory = `${assetsDirectory}/themes`
-const staffDirectory = `${themeDirectory}/staff`
-
 const tempDirectory = fs.mkdtempSync(path.join(tmpdir(), "build-themes"))
 
+function getColorSchemes() {
+    const colorSchemes: ColorScheme[] = themes.map((theme) =>
+        createColorScheme(theme)
+    )
+    return colorSchemes
+}
+
 // Clear existing themes
 function clearThemes(themeDirectory: string) {
     if (!fs.existsSync(themeDirectory)) {
@@ -19,23 +23,14 @@ function clearThemes(themeDirectory: string) {
     } else {
         for (const file of fs.readdirSync(themeDirectory)) {
             if (file.endsWith(".json")) {
-                const name = file.replace(/\.json$/, "")
-                if (
-                    !colorSchemes.find(
-                        (colorScheme) => colorScheme.name === name
-                    )
-                ) {
-                    fs.unlinkSync(path.join(themeDirectory, file))
-                }
+                fs.unlinkSync(path.join(themeDirectory, file))
             }
         }
     }
 }
 
-clearThemes(themeDirectory)
-clearThemes(staffDirectory)
-
 function writeThemes(colorSchemes: ColorScheme[], outputDirectory: string) {
+    clearThemes(outputDirectory)
     for (let colorScheme of colorSchemes) {
         let styleTree = snakeCase(app(colorScheme))
         let styleTreeJSON = JSON.stringify(styleTree, null, 2)
@@ -48,5 +43,4 @@ function writeThemes(colorSchemes: ColorScheme[], outputDirectory: string) {
 }
 
 // Write new themes to theme directory
-writeThemes(colorSchemes, themeDirectory)
-writeThemes(staffColorSchemes, staffDirectory)
+writeThemes(getColorSchemes(), `${assetsDirectory}/themes`)

styles/src/colorSchemes.ts 🔗

@@ -1,79 +0,0 @@
-import fs from "fs"
-import path from "path"
-import { ColorScheme, MetaAndLicense } from "./themes/common/colorScheme"
-
-const THEMES_DIRECTORY = path.resolve(`${__dirname}/themes`)
-const STAFF_DIRECTORY = path.resolve(`${__dirname}/themes/staff`)
-const IGNORE_ITEMS = ["staff", "common", "common.ts"]
-const ACCEPT_EXTENSION = ".ts"
-const LICENSE_FILE_NAME = "LICENSE"
-
-function getAllTsFiles(directoryPath: string) {
-    const files = fs.readdirSync(directoryPath)
-    const fileList: string[] = []
-
-    for (const file of files) {
-        if (!IGNORE_ITEMS.includes(file)) {
-            const filePath = path.join(directoryPath, file)
-
-            if (fs.statSync(filePath).isDirectory()) {
-                fileList.push(...getAllTsFiles(filePath))
-            } else if (path.extname(file) === ACCEPT_EXTENSION) {
-                fileList.push(filePath)
-            }
-        }
-    }
-
-    return fileList
-}
-
-function getAllColorSchemes(directoryPath: string) {
-    const files = getAllTsFiles(directoryPath)
-    return files.map((filePath) => ({
-        colorScheme: require(filePath),
-        filePath,
-        fileName: path.basename(filePath),
-        licenseFile: `${path.dirname(filePath)}/${LICENSE_FILE_NAME}`,
-    }))
-}
-
-function getColorSchemes(directoryPath: string) {
-    const colorSchemes: ColorScheme[] = []
-
-    for (const { colorScheme } of getAllColorSchemes(directoryPath)) {
-        if (colorScheme.dark) colorSchemes.push(colorScheme.dark)
-        else if (colorScheme.light) colorSchemes.push(colorScheme.light)
-    }
-
-    return colorSchemes
-}
-
-function getMetaAndLicense(directoryPath: string) {
-    const meta: MetaAndLicense[] = []
-
-    for (const { colorScheme, filePath, licenseFile } of getAllColorSchemes(
-        directoryPath
-    )) {
-        const licenseExists = fs.existsSync(licenseFile)
-        if (!licenseExists) {
-            throw Error(
-                `Public theme should have a LICENSE file ${licenseFile}`
-            )
-        }
-
-        if (!colorScheme.meta) {
-            throw Error(`Public theme ${filePath} must have a meta field`)
-        }
-
-        meta.push({
-            meta: colorScheme.meta,
-            licenseFile,
-        })
-    }
-
-    return meta
-}
-
-export const colorSchemes = getColorSchemes(THEMES_DIRECTORY)
-export const staffColorSchemes = getColorSchemes(STAFF_DIRECTORY)
-export const schemeMeta = getMetaAndLicense(THEMES_DIRECTORY)

styles/src/themeConfig.ts 🔗

@@ -17,8 +17,9 @@ interface ThemeMeta {
      *
      * Example: `MIT`
      */
-    licenseType?: string
+    licenseType?: string | ThemeLicenseType
     licenseUrl?: string
+    licenseFile: string
     themeUrl?: string
 }
 
@@ -94,6 +95,11 @@ export enum ThemeAppearance {
     Dark = "dark",
 }
 
+export enum ThemeLicenseType {
+    MIT = "MIT",
+    Apache2 = "Apache License 2.0",
+}
+
 export type ThemeFamilyItem =
     | ThemeConfig
     | { light: ThemeConfig; dark: ThemeConfig }