@wkovacs64/add-icon 0.1.0-dev.e2dd6945 → 1.1.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/README.md +13 -4
- package/bin/add-icon.js +1 -1
- package/dist/config.d.ts +3 -1
- package/dist/config.js +3 -3
- package/dist/iconify.js +6 -3
- package/dist/import-module.js +3 -3
- package/dist/index.js +27 -7
- package/dist/types.d.ts +1 -1
- package/package.json +12 -2
package/README.md
CHANGED
|
@@ -14,22 +14,30 @@ npm install @wkovacs64/add-icon
|
|
|
14
14
|
Or use it directly with npx without installing:
|
|
15
15
|
|
|
16
16
|
```bash
|
|
17
|
-
npx @wkovacs64/add-icon <icon
|
|
17
|
+
npx @wkovacs64/add-icon <icon>... [options]
|
|
18
18
|
```
|
|
19
19
|
|
|
20
20
|
## Usage
|
|
21
21
|
|
|
22
22
|
### Basic Usage
|
|
23
23
|
|
|
24
|
-
Download
|
|
24
|
+
Download a single icon to the specified directory:
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
27
|
npx @wkovacs64/add-icon heroicons:arrow-up-circle --output-dir ./app/assets/svg-icons
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
+
Download multiple icons in one command:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npx @wkovacs64/add-icon heroicons:arrow-up-circle mdi:home lucide:github --output-dir ./app/assets/svg-icons
|
|
34
|
+
```
|
|
35
|
+
|
|
30
36
|
### Transformations
|
|
31
37
|
|
|
32
|
-
The tool fetches SVG icons directly from the Iconify API with width and height attributes removed
|
|
38
|
+
The tool fetches SVG icons directly from the Iconify API with width and height attributes removed
|
|
39
|
+
automatically. You can optionally provide a transform file using either JavaScript or TypeScript
|
|
40
|
+
containing custom transformations for more advanced modifications.
|
|
33
41
|
|
|
34
42
|
#### TypeScript Transform Example
|
|
35
43
|
|
|
@@ -56,7 +64,8 @@ npx @wkovacs64/add-icon heroicons:arrow-up-circle --transform ./my-transform.ts
|
|
|
56
64
|
|
|
57
65
|
### Configuration File
|
|
58
66
|
|
|
59
|
-
You can create a configuration file in your project root, using either JavaScript
|
|
67
|
+
You can create a configuration file in your project root, using either JavaScript
|
|
68
|
+
(`add-icon.config.js`) or TypeScript (`add-icon.config.ts`).
|
|
60
69
|
|
|
61
70
|
#### TypeScript Configuration Example
|
|
62
71
|
|
package/bin/add-icon.js
CHANGED
package/dist/config.d.ts
CHANGED
|
@@ -2,7 +2,9 @@ import type { Config } from './types.js';
|
|
|
2
2
|
/**
|
|
3
3
|
* Default configuration
|
|
4
4
|
*/
|
|
5
|
-
export declare const defaultConfig:
|
|
5
|
+
export declare const defaultConfig: {
|
|
6
|
+
readonly outputDir: ".";
|
|
7
|
+
};
|
|
6
8
|
/**
|
|
7
9
|
* Loads configuration from file if it exists
|
|
8
10
|
* @param configPath - Path to config file
|
package/dist/config.js
CHANGED
|
@@ -18,7 +18,7 @@ export async function loadConfig(configPath) {
|
|
|
18
18
|
if (configPath) {
|
|
19
19
|
// Use the unified import method for both JS and TS files
|
|
20
20
|
const config = await importModule(configPath);
|
|
21
|
-
return { ...defaultConfig, ...config.default };
|
|
21
|
+
return { ...defaultConfig, ...(config.default || {}) };
|
|
22
22
|
}
|
|
23
23
|
// Try to find a config file in the current directory, checking both JS and TS
|
|
24
24
|
const jsConfigPath = path.resolve(process.cwd(), 'add-icon.config.js');
|
|
@@ -27,7 +27,7 @@ export async function loadConfig(configPath) {
|
|
|
27
27
|
if (existsSync(tsConfigPath)) {
|
|
28
28
|
try {
|
|
29
29
|
const config = await importModule(tsConfigPath);
|
|
30
|
-
return { ...defaultConfig, ...config.default };
|
|
30
|
+
return { ...defaultConfig, ...(config.default || {}) };
|
|
31
31
|
}
|
|
32
32
|
catch (err) {
|
|
33
33
|
console.error('Error loading TypeScript config, falling back to default config:', err);
|
|
@@ -38,7 +38,7 @@ export async function loadConfig(configPath) {
|
|
|
38
38
|
if (existsSync(jsConfigPath)) {
|
|
39
39
|
try {
|
|
40
40
|
const config = await importModule(jsConfigPath);
|
|
41
|
-
return { ...defaultConfig, ...config.default };
|
|
41
|
+
return { ...defaultConfig, ...(config.default || {}) };
|
|
42
42
|
}
|
|
43
43
|
catch (err) {
|
|
44
44
|
console.error('Error loading JavaScript config, falling back to default config:', err);
|
package/dist/iconify.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
+
import { defaultConfig } from './config.js';
|
|
3
4
|
/**
|
|
4
5
|
* Parses an icon reference into iconSet and iconName
|
|
5
6
|
* @param iconReference - Reference in format 'iconSet:iconName'
|
|
@@ -45,9 +46,11 @@ async function fetchIconSvg(iconSet, iconName) {
|
|
|
45
46
|
export async function downloadIcon(iconReference, config) {
|
|
46
47
|
try {
|
|
47
48
|
const { iconSet, iconName } = parseIconReference(iconReference);
|
|
49
|
+
// Use default output directory if not specified
|
|
50
|
+
const outputDir = config.outputDir || defaultConfig.outputDir;
|
|
48
51
|
// Ensure the output directory exists
|
|
49
|
-
if (!fs.existsSync(
|
|
50
|
-
fs.mkdirSync(
|
|
52
|
+
if (!fs.existsSync(outputDir)) {
|
|
53
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
51
54
|
}
|
|
52
55
|
// Fetch SVG directly with width=unset parameter to remove width/height attributes
|
|
53
56
|
let svg = await fetchIconSvg(iconSet, iconName);
|
|
@@ -66,7 +69,7 @@ export async function downloadIcon(iconReference, config) {
|
|
|
66
69
|
}
|
|
67
70
|
// Create file name
|
|
68
71
|
const fileName = `${iconSet}-${iconName}.svg`;
|
|
69
|
-
const filePath = path.join(
|
|
72
|
+
const filePath = path.join(outputDir, fileName);
|
|
70
73
|
// Write the SVG file
|
|
71
74
|
fs.writeFileSync(filePath, svg, 'utf8');
|
|
72
75
|
return filePath;
|
package/dist/import-module.js
CHANGED
|
@@ -10,20 +10,20 @@ export async function importModule(filePath) {
|
|
|
10
10
|
const absolutePath = path.resolve(filePath);
|
|
11
11
|
try {
|
|
12
12
|
// Read the module file content
|
|
13
|
-
const code = await fs.readFile(absolutePath,
|
|
13
|
+
const code = await fs.readFile(absolutePath, 'utf-8');
|
|
14
14
|
// Determine the appropriate loader based on file extension
|
|
15
15
|
const loader = absolutePath.endsWith('.ts') ? 'ts' : 'js';
|
|
16
16
|
// Use esbuild to transform the code to ESM JS
|
|
17
17
|
const result = await esbuild.transform(code, {
|
|
18
18
|
loader, // Automatically use the appropriate loader
|
|
19
|
-
format:
|
|
19
|
+
format: 'esm', // Output format
|
|
20
20
|
sourcemap: false, // Disable source maps for data URI
|
|
21
21
|
sourcefile: absolutePath, // Helps with error messages
|
|
22
22
|
target: 'esnext',
|
|
23
23
|
});
|
|
24
24
|
const jsCode = result.code;
|
|
25
25
|
// Create data URI and import
|
|
26
|
-
const base64Code = Buffer.from(jsCode).toString(
|
|
26
|
+
const base64Code = Buffer.from(jsCode).toString('base64');
|
|
27
27
|
const dataUri = `data:text/javascript;base64,${base64Code}`;
|
|
28
28
|
// Import the transformed code as a module
|
|
29
29
|
return await import(dataUri);
|
package/dist/index.js
CHANGED
|
@@ -16,14 +16,14 @@ const setupProgram = async () => {
|
|
|
16
16
|
.name(name.split('/').pop() || name)
|
|
17
17
|
.description(description)
|
|
18
18
|
.version(version, '-v, --version', 'Output the current version')
|
|
19
|
-
.argument('<
|
|
20
|
-
.option('-o, --output-dir <dir>', 'Directory to save
|
|
19
|
+
.argument('<icons...>', 'Icon references (e.g., heroicons:arrow-up-circle mdi:home)')
|
|
20
|
+
.option('-o, --output-dir <dir>', 'Directory to save icons')
|
|
21
21
|
.option('-c, --config <path>', 'Path to config file')
|
|
22
22
|
.option('-t, --transform <path>', 'Path to custom transform module (.js or .ts)');
|
|
23
23
|
};
|
|
24
24
|
// Initialize the program
|
|
25
25
|
const initializedProgram = await setupProgram();
|
|
26
|
-
initializedProgram.action(async (
|
|
26
|
+
initializedProgram.action(async (icons, options) => {
|
|
27
27
|
try {
|
|
28
28
|
// Load config (first from config file, then override with CLI options)
|
|
29
29
|
const config = await loadConfig(options.config);
|
|
@@ -59,10 +59,30 @@ initializedProgram.action(async (icon, options) => {
|
|
|
59
59
|
process.exit(1);
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
|
-
// Download
|
|
63
|
-
|
|
64
|
-
const
|
|
65
|
-
|
|
62
|
+
// Download all icons
|
|
63
|
+
const results = [];
|
|
64
|
+
for (const icon of icons) {
|
|
65
|
+
console.log(`Downloading icon: ${icon}...`);
|
|
66
|
+
try {
|
|
67
|
+
const savedPath = await downloadIcon(icon, config);
|
|
68
|
+
console.log(`✓ Icon saved to: ${savedPath}`);
|
|
69
|
+
results.push({ icon, path: savedPath, success: true });
|
|
70
|
+
}
|
|
71
|
+
catch (iconError) {
|
|
72
|
+
const errorMessage = iconError instanceof Error ? iconError.message : String(iconError);
|
|
73
|
+
console.error(`Error downloading ${icon}: ${errorMessage}`);
|
|
74
|
+
results.push({ icon, error: errorMessage, success: false });
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Report summary if multiple icons
|
|
78
|
+
if (icons.length > 1) {
|
|
79
|
+
const successful = results.filter((r) => r.success).length;
|
|
80
|
+
console.log(`\nSummary: Downloaded ${successful}/${icons.length} icons`);
|
|
81
|
+
// If any failed, exit with error
|
|
82
|
+
if (successful < icons.length) {
|
|
83
|
+
process.exit(1);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
66
86
|
}
|
|
67
87
|
catch (error) {
|
|
68
88
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
package/dist/types.d.ts
CHANGED
|
@@ -18,7 +18,7 @@ export type TransformFunction = (args: TransformArgs) => Promise<string> | strin
|
|
|
18
18
|
*/
|
|
19
19
|
export type Config = {
|
|
20
20
|
/** Directory to output icons */
|
|
21
|
-
outputDir
|
|
21
|
+
outputDir?: string;
|
|
22
22
|
/** Array of transform functions to apply to icons */
|
|
23
23
|
transforms?: TransformFunction[];
|
|
24
24
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wkovacs64/add-icon",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "CLI tool to download and transform icons from Iconify",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"iconify",
|
|
@@ -9,7 +9,17 @@
|
|
|
9
9
|
"cli",
|
|
10
10
|
"download"
|
|
11
11
|
],
|
|
12
|
-
"author":
|
|
12
|
+
"author": {
|
|
13
|
+
"name": "Justin Hall",
|
|
14
|
+
"email": "justin.r.hall@gmail.com"
|
|
15
|
+
},
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/wKovacs64/add-icon.git"
|
|
19
|
+
},
|
|
20
|
+
"bugs": {
|
|
21
|
+
"url": "https://github.com/wKovacs64/add-icon/issues"
|
|
22
|
+
},
|
|
13
23
|
"license": "MIT",
|
|
14
24
|
"type": "module",
|
|
15
25
|
"main": "dist/index.js",
|