iconfont-preview-cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +255 -0
- package/app/assets/index-BN1JFPmQ.js +22 -0
- package/app/assets/index-fas_yV9m.css +1 -0
- package/app/index.html +14 -0
- package/app/vite.svg +1 -0
- package/components/index.cjs +1 -0
- package/components/index.css +1 -0
- package/components/index.mjs +1233 -0
- package/components/types/index.d.ts +2 -0
- package/components/types/render-icon-list/index.d.ts +3 -0
- package/components/types/render-icon-list/src/components/render-icon-class.d.ts +23 -0
- package/components/types/render-icon-list/src/components/render-icon.d.ts +26 -0
- package/components/types/render-icon-list/src/render-icon-list.d.ts +33 -0
- package/components/types/render-icon-list/src/render-icon-list.vue.d.ts +61 -0
- package/package.json +66 -0
- package/server/bin.cjs +163 -0
- package/server/bin.mjs +150 -0
- package/server/index.cjs +141 -0
- package/server/index.d.cts +6 -0
- package/server/index.d.mts +6 -0
- package/server/index.d.ts +6 -0
- package/server/index.mjs +133 -0
package/server/index.mjs
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import css from 'css';
|
|
3
|
+
import { readFile, readdir, stat } from 'node:fs/promises';
|
|
4
|
+
import { resolve, extname, dirname } from 'node:path';
|
|
5
|
+
import 'node:os';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
import 'portfinder';
|
|
8
|
+
import { readFileSync } from 'node:fs';
|
|
9
|
+
|
|
10
|
+
async function readCssFilesAsync(dirPath) {
|
|
11
|
+
const cssFiles = [];
|
|
12
|
+
async function traverseDirectory(currentPath) {
|
|
13
|
+
const items = await readdir(currentPath);
|
|
14
|
+
for (const item of items) {
|
|
15
|
+
const fullPath = resolve(currentPath, item);
|
|
16
|
+
let fileStat;
|
|
17
|
+
try {
|
|
18
|
+
fileStat = await stat(fullPath);
|
|
19
|
+
} catch (error) {
|
|
20
|
+
console.error(`\u65E0\u6CD5\u8BBF\u95EE\u6587\u4EF6: ${fullPath}`, error);
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
if (fileStat.isDirectory()) {
|
|
24
|
+
await traverseDirectory(fullPath);
|
|
25
|
+
} else {
|
|
26
|
+
const ext = extname(fullPath).toLowerCase();
|
|
27
|
+
if (ext === ".css") {
|
|
28
|
+
cssFiles.push(fullPath);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
await traverseDirectory(dirPath);
|
|
34
|
+
return cssFiles;
|
|
35
|
+
}
|
|
36
|
+
async function extractClassNames(cssFilePath, basePath) {
|
|
37
|
+
try {
|
|
38
|
+
const cssContent = await readFile(cssFilePath, "utf8");
|
|
39
|
+
const ast = css.parse(cssContent);
|
|
40
|
+
let baseClassName = "";
|
|
41
|
+
const classNames = /* @__PURE__ */ new Set();
|
|
42
|
+
const fontFamilyRule = ast.stylesheet?.rules.find((rule) => rule.type === "font-face");
|
|
43
|
+
const fontFamilyDeclaration = fontFamilyRule?.declarations?.find((declaration) => declaration.property === "font-family");
|
|
44
|
+
const fontFamily = fontFamilyDeclaration?.value?.replaceAll(/["']/g, "");
|
|
45
|
+
const rules = ast.stylesheet?.rules || [];
|
|
46
|
+
for (const rule of rules) {
|
|
47
|
+
if (rule.type === "rule") {
|
|
48
|
+
const declarations = rule.declarations || [];
|
|
49
|
+
const selectors = rule.selectors || [];
|
|
50
|
+
if (!baseClassName && fontFamily && declarations.some((declaration) => declaration.value?.includes(fontFamily))) {
|
|
51
|
+
baseClassName = selectors.join(" ").replaceAll(".", "");
|
|
52
|
+
}
|
|
53
|
+
if (declarations.some((declaration) => declaration.property === "content")) {
|
|
54
|
+
for (const selector of selectors) {
|
|
55
|
+
const classSelectorMatch = selector.match(/^\.([\w-]+)(?::before)?$/);
|
|
56
|
+
if (classSelectorMatch) {
|
|
57
|
+
const className = classSelectorMatch[1];
|
|
58
|
+
classNames.add(className);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return { filePath: cssFilePath.replace(basePath, ""), baseClassName, classNames: [...classNames] };
|
|
65
|
+
} catch (error) {
|
|
66
|
+
console.error("\u63D0\u53D6\u7C7B\u540D\u65F6\u51FA\u9519:", error.message);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
async function getCssInfo(dirPath) {
|
|
70
|
+
const filePaths = await readCssFilesAsync(dirPath);
|
|
71
|
+
const data = [];
|
|
72
|
+
await Promise.all(filePaths.map(async (filePath) => {
|
|
73
|
+
const res = await extractClassNames(filePath, dirPath);
|
|
74
|
+
res && data.push(res);
|
|
75
|
+
}));
|
|
76
|
+
return data;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const __dirname$1 = dirname(fileURLToPath(import.meta.url));
|
|
80
|
+
const runtimeProjRoot = process.env.NODE_ENV === "dev" ? resolve(__dirname$1, "..", "..", "..") : resolve(__dirname$1, "..");
|
|
81
|
+
resolve(__dirname$1, "..", "..", "..");
|
|
82
|
+
const buildOutput = process.env.NODE_ENV === "dev" ? resolve(runtimeProjRoot, "dist") : runtimeProjRoot;
|
|
83
|
+
resolve(buildOutput, "app");
|
|
84
|
+
|
|
85
|
+
const getVersion = () => {
|
|
86
|
+
const packageJsonContent = readFileSync(resolve(runtimeProjRoot, "package.json"), "utf8");
|
|
87
|
+
const packageJson = JSON.parse(packageJsonContent);
|
|
88
|
+
const { version = "" } = packageJson;
|
|
89
|
+
return version ? `v${version}` : version;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const logTitle = (start) => {
|
|
93
|
+
const readyIn = "";
|
|
94
|
+
console.log(`
|
|
95
|
+
${chalk.green.bold("iconfont-preview-cli")} ${chalk.green(getVersion())}${readyIn}
|
|
96
|
+
`);
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const iconfontServer = async (options) => {
|
|
100
|
+
const pluginOption = {
|
|
101
|
+
name: "iconfont-server",
|
|
102
|
+
enforce: "pre",
|
|
103
|
+
apply: "serve",
|
|
104
|
+
configureServer(server) {
|
|
105
|
+
const { urlPrefix = "/iconfont-proxy", iconDir = "" } = options;
|
|
106
|
+
logTitle();
|
|
107
|
+
console.log(` \u5B57\u4F53\u56FE\u6807\u670D\u52A1\u4E2D\u95F4\u4EF6\u5DF2\u542F\u52A8\uFF0C${chalk.cyan(urlPrefix)}\u5F00\u5934\u7684\u8BF7\u6C42\u5C06\u88AB\u4EE3\u7406\u5230\u5B57\u4F53\u56FE\u6807\u670D\u52A1`);
|
|
108
|
+
server.middlewares.use(async (req, res, next) => {
|
|
109
|
+
const codeServiceReg = new RegExp(`^${urlPrefix}`);
|
|
110
|
+
if (req.url && codeServiceReg.test(req.url)) {
|
|
111
|
+
if (req.url === `${urlPrefix}/api/iconsInfo`) {
|
|
112
|
+
const fontDir = resolve(process.cwd(), iconDir);
|
|
113
|
+
const data = await getCssInfo(fontDir);
|
|
114
|
+
res.setHeader("Content-Type", "application/json");
|
|
115
|
+
res.end(JSON.stringify({
|
|
116
|
+
data,
|
|
117
|
+
dir: options.iconDir || "",
|
|
118
|
+
absDir: fontDir
|
|
119
|
+
}));
|
|
120
|
+
} else {
|
|
121
|
+
res.statusCode = 404;
|
|
122
|
+
res.end(req.url);
|
|
123
|
+
}
|
|
124
|
+
} else {
|
|
125
|
+
next();
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
return pluginOption;
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
export { iconfontServer };
|