mirror of
				https://github.com/home-assistant/frontend.git
				synced 2025-11-04 08:29:52 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			168 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			168 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
const gulp = require("gulp");
 | 
						|
const path = require("path");
 | 
						|
const fs = require("fs");
 | 
						|
const hash = require("object-hash");
 | 
						|
 | 
						|
const ICON_PACKAGE_PATH = path.resolve(
 | 
						|
  __dirname,
 | 
						|
  "../../node_modules/@mdi/svg/"
 | 
						|
);
 | 
						|
const META_PATH = path.resolve(ICON_PACKAGE_PATH, "meta.json");
 | 
						|
const PACKAGE_PATH = path.resolve(ICON_PACKAGE_PATH, "package.json");
 | 
						|
const ICON_PATH = path.resolve(ICON_PACKAGE_PATH, "svg");
 | 
						|
const OUTPUT_DIR = path.resolve(__dirname, "../../build/mdi");
 | 
						|
const REMOVED_ICONS_PATH = path.resolve(__dirname, "../removedIcons.json");
 | 
						|
 | 
						|
const encoding = "utf8";
 | 
						|
 | 
						|
const getMeta = () => {
 | 
						|
  const file = fs.readFileSync(META_PATH, { encoding });
 | 
						|
  const meta = JSON.parse(file);
 | 
						|
  return meta.map((icon) => {
 | 
						|
    const svg = fs.readFileSync(`${ICON_PATH}/${icon.name}.svg`, {
 | 
						|
      encoding,
 | 
						|
    });
 | 
						|
    return {
 | 
						|
      path: svg.match(/ d="([^"]+)"/)[1],
 | 
						|
      name: icon.name,
 | 
						|
      tags: icon.tags,
 | 
						|
      aliases: icon.aliases,
 | 
						|
    };
 | 
						|
  });
 | 
						|
};
 | 
						|
 | 
						|
const addRemovedMeta = (meta) => {
 | 
						|
  const file = fs.readFileSync(REMOVED_ICONS_PATH, { encoding });
 | 
						|
  const removed = JSON.parse(file);
 | 
						|
  const removedMeta = removed.map((removeIcon) => ({
 | 
						|
    path: removeIcon.path,
 | 
						|
    name: removeIcon.name,
 | 
						|
    tags: [],
 | 
						|
    aliases: [],
 | 
						|
  }));
 | 
						|
  const combinedMeta = [...meta, ...removedMeta];
 | 
						|
  return combinedMeta.sort((a, b) => a.name.localeCompare(b.name));
 | 
						|
};
 | 
						|
 | 
						|
const homeAutomationTag = "Home Automation";
 | 
						|
 | 
						|
const orderMeta = (meta) => {
 | 
						|
  const homeAutomationMeta = meta.filter((icon) =>
 | 
						|
    icon.tags.includes(homeAutomationTag)
 | 
						|
  );
 | 
						|
  const otherMeta = meta.filter(
 | 
						|
    (icon) => !icon.tags.includes(homeAutomationTag)
 | 
						|
  );
 | 
						|
  return [...homeAutomationMeta, ...otherMeta];
 | 
						|
};
 | 
						|
 | 
						|
const splitBySize = (meta) => {
 | 
						|
  const chunks = [];
 | 
						|
  const CHUNK_SIZE = 50000;
 | 
						|
 | 
						|
  let curSize = 0;
 | 
						|
  let startKey;
 | 
						|
  let icons = [];
 | 
						|
 | 
						|
  Object.values(meta).forEach((icon) => {
 | 
						|
    if (startKey === undefined) {
 | 
						|
      startKey = icon.name;
 | 
						|
    }
 | 
						|
    curSize += icon.path.length;
 | 
						|
    icons.push(icon);
 | 
						|
    if (curSize > CHUNK_SIZE) {
 | 
						|
      chunks.push({
 | 
						|
        startKey,
 | 
						|
        endKey: icon.name,
 | 
						|
        icons,
 | 
						|
      });
 | 
						|
      curSize = 0;
 | 
						|
      startKey = undefined;
 | 
						|
      icons = [];
 | 
						|
    }
 | 
						|
  });
 | 
						|
 | 
						|
  chunks.push({
 | 
						|
    startKey,
 | 
						|
    icons,
 | 
						|
  });
 | 
						|
 | 
						|
  return chunks;
 | 
						|
};
 | 
						|
 | 
						|
const findDifferentiator = (curString, prevString) => {
 | 
						|
  for (let i = 0; i < curString.length; i++) {
 | 
						|
    if (curString[i] !== prevString[i]) {
 | 
						|
      return curString.substring(0, i + 1);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  throw new Error("Cannot find differentiator", curString, prevString);
 | 
						|
};
 | 
						|
 | 
						|
gulp.task("gen-icons-json", (done) => {
 | 
						|
  const meta = getMeta();
 | 
						|
 | 
						|
  const metaAndRemoved = addRemovedMeta(meta);
 | 
						|
  const split = splitBySize(metaAndRemoved);
 | 
						|
 | 
						|
  if (!fs.existsSync(OUTPUT_DIR)) {
 | 
						|
    fs.mkdirSync(OUTPUT_DIR, { recursive: true });
 | 
						|
  }
 | 
						|
  const parts = [];
 | 
						|
 | 
						|
  let lastEnd;
 | 
						|
  split.forEach((chunk) => {
 | 
						|
    let startKey;
 | 
						|
    if (lastEnd === undefined) {
 | 
						|
      chunk.startKey = undefined;
 | 
						|
      startKey = undefined;
 | 
						|
    } else {
 | 
						|
      startKey = findDifferentiator(chunk.startKey, lastEnd);
 | 
						|
    }
 | 
						|
    lastEnd = chunk.endKey;
 | 
						|
 | 
						|
    const output = {};
 | 
						|
    chunk.icons.forEach((icon) => {
 | 
						|
      output[icon.name] = icon.path;
 | 
						|
    });
 | 
						|
    const filename = hash(output);
 | 
						|
    parts.push({ start: startKey, file: filename });
 | 
						|
    fs.writeFileSync(
 | 
						|
      path.resolve(OUTPUT_DIR, `${filename}.json`),
 | 
						|
      JSON.stringify(output)
 | 
						|
    );
 | 
						|
  });
 | 
						|
 | 
						|
  const file = fs.readFileSync(PACKAGE_PATH, { encoding });
 | 
						|
  const packageMeta = JSON.parse(file);
 | 
						|
 | 
						|
  fs.writeFileSync(
 | 
						|
    path.resolve(OUTPUT_DIR, "iconMetadata.json"),
 | 
						|
    JSON.stringify({ version: packageMeta.version, parts })
 | 
						|
  );
 | 
						|
 | 
						|
  fs.writeFileSync(
 | 
						|
    path.resolve(OUTPUT_DIR, "iconList.json"),
 | 
						|
    JSON.stringify(
 | 
						|
      orderMeta(meta).map((icon) => ({
 | 
						|
        name: icon.name,
 | 
						|
        keywords: [
 | 
						|
          ...icon.tags.map((t) => t.toLowerCase().replace(/\s\/\s/g, " ")),
 | 
						|
          ...icon.aliases,
 | 
						|
        ],
 | 
						|
      }))
 | 
						|
    )
 | 
						|
  );
 | 
						|
 | 
						|
  done();
 | 
						|
});
 | 
						|
 | 
						|
gulp.task("gen-dummy-icons-json", (done) => {
 | 
						|
  if (!fs.existsSync(OUTPUT_DIR)) {
 | 
						|
    fs.mkdirSync(OUTPUT_DIR, { recursive: true });
 | 
						|
  }
 | 
						|
 | 
						|
  fs.writeFileSync(path.resolve(OUTPUT_DIR, "iconList.json"), "[]");
 | 
						|
  done();
 | 
						|
});
 |