@svgicons-com/cli 0.1.0-alpha.2 → 0.1.0-alpha.4
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 +28 -5
- package/RELEASE_NOTES.md +5 -1
- package/package.json +1 -1
- package/src/api.js +19 -7
- package/src/cli.js +161 -8
- package/src/downloads.js +19 -0
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ Public icon search works without changing the default endpoint. Pro workflows re
|
|
|
8
8
|
|
|
9
9
|
The scanner is read-only by default. It never edits project files unless a future command explicitly adds that behavior.
|
|
10
10
|
|
|
11
|
-
Current package version: `0.1.0-alpha.
|
|
11
|
+
Current package version: `0.1.0-alpha.3`.
|
|
12
12
|
|
|
13
13
|
## Requirements
|
|
14
14
|
|
|
@@ -18,17 +18,19 @@ Current package version: `0.1.0-alpha.2`.
|
|
|
18
18
|
## Login
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
|
-
svgicons login --token YOUR_PRO_API_TOKEN
|
|
21
|
+
svgicons login --token "YOUR_PRO_API_TOKEN"
|
|
22
22
|
```
|
|
23
23
|
|
|
24
24
|
The explicit auth namespace is also supported:
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
|
-
svgicons auth login --token YOUR_PRO_API_TOKEN
|
|
27
|
+
svgicons auth login --token "YOUR_PRO_API_TOKEN"
|
|
28
28
|
svgicons auth status
|
|
29
29
|
svgicons doctor
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
+
Pro API tokens may start with a numeric prefix and a pipe character, such as `10|...`. Keep the full token and wrap it in quotes when using a shell command.
|
|
33
|
+
|
|
32
34
|
You can also avoid writing a config file by setting `SVGICONS_TOKEN` or `SVGICONS_API_TOKEN`.
|
|
33
35
|
|
|
34
36
|
Inspect local config without exposing the stored token:
|
|
@@ -43,7 +45,7 @@ svgicons config set baseUrl https://svgicons.com
|
|
|
43
45
|
|
|
44
46
|
```bash
|
|
45
47
|
svgicons version
|
|
46
|
-
svgicons auth login --token YOUR_PRO_API_TOKEN
|
|
48
|
+
svgicons auth login --token "YOUR_PRO_API_TOKEN"
|
|
47
49
|
svgicons auth status --json
|
|
48
50
|
svgicons config list --json
|
|
49
51
|
svgicons doctor --json
|
|
@@ -58,6 +60,7 @@ svgicons icon show 33716
|
|
|
58
60
|
svgicons icon url 33716-arrow-circle-up-fill
|
|
59
61
|
svgicons icon raw 33716-arrow-circle-up-fill
|
|
60
62
|
svgicons icon download 33716-arrow-circle-up-fill --output ./icons
|
|
63
|
+
svgicons icon png 33716-arrow-circle-up-fill --size 512 --output ./icons
|
|
61
64
|
svgicons collection list
|
|
62
65
|
svgicons collection create --name "Dashboard icons" --description "Navigation and status icons"
|
|
63
66
|
svgicons collection show "Dashboard icons" --icons
|
|
@@ -67,6 +70,7 @@ svgicons collection add "Dashboard icons" 33716 240297
|
|
|
67
70
|
svgicons collection remove "Dashboard icons" 33716-arrow-circle-up-fill
|
|
68
71
|
svgicons collection delete "Dashboard icons" --yes
|
|
69
72
|
svgicons collection export "Dashboard icons" --formats react-ts,vue --color-policy currentColor --output ./exports
|
|
73
|
+
svgicons collection export "Dashboard icons" --formats png-pack --png-sizes 24,48,512 --output ./exports
|
|
70
74
|
svgicons collection export "Dashboard icons" --formats react-ts --no-size-props --no-typescript --output ./exports
|
|
71
75
|
svgicons export status 55 --collection "Dashboard icons"
|
|
72
76
|
svgicons export download 55 --collection "Dashboard icons" --output ./exports
|
|
@@ -114,6 +118,16 @@ The icon reference must include both the numeric ID and the icon name, such as `
|
|
|
114
118
|
|
|
115
119
|
This command uses the MCP `get_icon` tool with raw SVG output, so the token needs `mcp:use` and `icons:read`. Existing files are not overwritten unless you add `--force`.
|
|
116
120
|
|
|
121
|
+
Export a Pro PNG asset from a single icon:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
svgicons icon png 33716-arrow-circle-up-fill --size 512 --output ./icons
|
|
125
|
+
svgicons icon png 33716-arrow-circle-up-fill --sizes 128,256,512 --density 1,2 --zip --output ./icons
|
|
126
|
+
svgicons icon png 33716-arrow-circle-up-fill --size 512 --color black --background solid --background-color "#ffffff"
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Single-icon PNG export uses the Pro REST API, not the public anonymous search API. The token needs `icons:read` and `exports:create`. The icon reference must include both ID and name, and the server verifies that the name matches before rendering.
|
|
130
|
+
|
|
117
131
|
Read-only icon commands accept a numeric ID, an `id-name` reference, or a full svgicons.com icon URL:
|
|
118
132
|
|
|
119
133
|
```bash
|
|
@@ -172,13 +186,22 @@ The command polls every 2 seconds for up to 180 seconds by default. Use `--timeo
|
|
|
172
186
|
Supported export flags:
|
|
173
187
|
|
|
174
188
|
```bash
|
|
175
|
-
--formats react-ts,vue
|
|
189
|
+
--formats react-ts,vue,png-pack
|
|
176
190
|
--color-policy currentColor|preserve|strip
|
|
177
191
|
--naming-policy kebab|pascal|camel
|
|
178
192
|
--size-props / --no-size-props
|
|
179
193
|
--typescript / --no-typescript
|
|
194
|
+
--png-sizes 24,48,512
|
|
195
|
+
--png-densities 1,2
|
|
196
|
+
--png-background transparent|solid
|
|
197
|
+
--png-background-color "#ffffff"
|
|
198
|
+
--png-color preserve|black|white|custom
|
|
199
|
+
--png-icon-color "#2563eb"
|
|
200
|
+
--png-padding 48
|
|
180
201
|
```
|
|
181
202
|
|
|
203
|
+
Use `--formats png` as a shorthand for `--formats png-pack`. PNG pack exports are generated by the server queue worker and downloaded as part of the collection ZIP.
|
|
204
|
+
|
|
182
205
|
Collection commands accept a numeric ID, exact slug, or exact case-insensitive collection name. The legacy `kit` alias remains available for old scripts.
|
|
183
206
|
|
|
184
207
|
Lifecycle commands are available for collection maintenance:
|
package/RELEASE_NOTES.md
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
# Svg/icons CLI 0.1.0-alpha.
|
|
1
|
+
# Svg/icons CLI 0.1.0-alpha.3
|
|
2
|
+
|
|
3
|
+
This alpha refresh improves token setup safety. `login` now rejects obviously truncated numeric tokens, which commonly happens when a shell command is run without quoting a Sanctum-style token containing `|`.
|
|
4
|
+
|
|
5
|
+
## 0.1.0-alpha.2
|
|
2
6
|
|
|
3
7
|
This alpha refresh removes local-development wording from the public npm README. Runtime behavior is unchanged from `0.1.0-alpha.1`.
|
|
4
8
|
|
package/package.json
CHANGED
package/src/api.js
CHANGED
|
@@ -79,14 +79,26 @@ export async function proApiDownload(pathOrUrl, options = {}) {
|
|
|
79
79
|
let response;
|
|
80
80
|
|
|
81
81
|
try {
|
|
82
|
-
|
|
82
|
+
const headers = {
|
|
83
|
+
Accept: 'image/png, application/zip, application/octet-stream',
|
|
84
|
+
Authorization: `Bearer ${token}`,
|
|
85
|
+
'User-Agent': 'svgicons-cli/0.1.0-alpha',
|
|
86
|
+
...options.headers,
|
|
87
|
+
};
|
|
88
|
+
const init = {
|
|
83
89
|
method: options.method || 'GET',
|
|
84
|
-
headers
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
+
headers,
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
if (options.body !== undefined) {
|
|
94
|
+
headers['Content-Type'] = headers['Content-Type'] || 'application/json';
|
|
95
|
+
init.body = typeof options.body === 'string' || options.body instanceof Buffer
|
|
96
|
+
? options.body
|
|
97
|
+
: JSON.stringify(options.body);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
response = await fetch(url, {
|
|
101
|
+
...init,
|
|
90
102
|
});
|
|
91
103
|
} catch (error) {
|
|
92
104
|
throw networkError(error, url);
|
package/src/cli.js
CHANGED
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
parseIconReference,
|
|
23
23
|
resolveArchiveDownloadPath,
|
|
24
24
|
resolveIconDownloadPath,
|
|
25
|
+
resolvePngDownloadPath,
|
|
25
26
|
sanitizeFileSegment,
|
|
26
27
|
writeBinaryFile,
|
|
27
28
|
writeIconSvg,
|
|
@@ -56,10 +57,15 @@ const KNOWN_SCOPES = [
|
|
|
56
57
|
'exports:create',
|
|
57
58
|
'mcp:use',
|
|
58
59
|
];
|
|
59
|
-
const EXPORT_FORMATS = ['svg-folder', 'svg-sprite', 'json-manifest', 'license-manifest', 'react-ts', 'vue'];
|
|
60
|
+
const EXPORT_FORMATS = ['svg-folder', 'svg-sprite', 'json-manifest', 'license-manifest', 'react-ts', 'vue', 'png-pack'];
|
|
60
61
|
const FRAMEWORKS = ['svg', 'react-ts', 'vue', 'sprite'];
|
|
61
62
|
const COLOR_POLICIES = ['currentColor', 'preserve', 'strip'];
|
|
62
63
|
const NAMING_POLICIES = ['kebab', 'pascal', 'camel'];
|
|
64
|
+
const PNG_SIZES = [16, 24, 32, 48, 96, 128, 256, 512, 1024];
|
|
65
|
+
const PNG_DENSITIES = [1, 2, 3, 4];
|
|
66
|
+
const PNG_BACKGROUNDS = ['transparent', 'solid'];
|
|
67
|
+
const PNG_COLORS = ['preserve', 'black', 'white', 'custom'];
|
|
68
|
+
const PNG_FITS = ['contain'];
|
|
63
69
|
|
|
64
70
|
export async function run(argv) {
|
|
65
71
|
const { args, options: globalOptions } = extractGlobalOptions(argv);
|
|
@@ -181,11 +187,9 @@ export async function run(argv) {
|
|
|
181
187
|
|
|
182
188
|
async function login(args, globalOptions = {}) {
|
|
183
189
|
const options = parseOptions(args);
|
|
184
|
-
const
|
|
190
|
+
const rawToken = options.token || globalOptions.token || process.env.SVGICONS_TOKEN || process.env.SVGICONS_API_TOKEN;
|
|
185
191
|
|
|
186
|
-
|
|
187
|
-
throw new Error('Missing token. Use: svgicons login --token <token>');
|
|
188
|
-
}
|
|
192
|
+
const token = normalizeLoginToken(rawToken);
|
|
189
193
|
|
|
190
194
|
const baseUrl = normalizeBaseUrl(options['base-url'] || globalOptions['base-url'] || defaultBaseUrl());
|
|
191
195
|
await writeConfig({
|
|
@@ -197,6 +201,28 @@ async function login(args, globalOptions = {}) {
|
|
|
197
201
|
console.log(`Svg/icons CLI token saved for ${baseUrl}.`);
|
|
198
202
|
}
|
|
199
203
|
|
|
204
|
+
function normalizeLoginToken(token) {
|
|
205
|
+
if (!token) {
|
|
206
|
+
throw usageError('Missing token. Use: svgicons login --token "<token>"');
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const value = String(token).trim();
|
|
210
|
+
|
|
211
|
+
if (value === '') {
|
|
212
|
+
throw usageError('Missing token. Use: svgicons login --token "<token>"');
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (/^\d+$/.test(value)) {
|
|
216
|
+
throw usageError('The token looks truncated. Svg/icons Pro API tokens can start with an id prefix like "10|". Wrap the full token in quotes: svgicons auth login --token "10|..."');
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (value.length < 20) {
|
|
220
|
+
throw usageError('The token value is too short. Copy the full Pro API token from your account page and wrap it in quotes when it contains "|".');
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return value;
|
|
224
|
+
}
|
|
225
|
+
|
|
200
226
|
async function logout() {
|
|
201
227
|
await clearConfig();
|
|
202
228
|
console.log('Svg/icons CLI credentials removed.');
|
|
@@ -613,7 +639,12 @@ async function icon(args) {
|
|
|
613
639
|
return;
|
|
614
640
|
}
|
|
615
641
|
|
|
616
|
-
|
|
642
|
+
if (subcommand === 'png') {
|
|
643
|
+
await iconPng(rest);
|
|
644
|
+
return;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
throw new Error('Unknown icon command. Use: show, raw, url, open, download, png.');
|
|
617
648
|
}
|
|
618
649
|
|
|
619
650
|
async function iconShow(args) {
|
|
@@ -695,6 +726,40 @@ async function iconDownload(args) {
|
|
|
695
726
|
console.log(` ${outputPath}`);
|
|
696
727
|
}
|
|
697
728
|
|
|
729
|
+
async function iconPng(args) {
|
|
730
|
+
const options = parseOptions(args);
|
|
731
|
+
const [iconReference] = options._;
|
|
732
|
+
const reference = parseIconReference(iconReference);
|
|
733
|
+
const payload = buildIconPngPayload(reference, options);
|
|
734
|
+
const download = await proApiDownload(`/api/pro/icons/${encodeURIComponent(reference.id)}/png-export`, {
|
|
735
|
+
method: 'POST',
|
|
736
|
+
body: payload,
|
|
737
|
+
headers: {
|
|
738
|
+
'Content-Type': 'application/json',
|
|
739
|
+
},
|
|
740
|
+
});
|
|
741
|
+
const outputPath = resolvePngDownloadPath(options.output || options.o, download.filename, process.cwd());
|
|
742
|
+
|
|
743
|
+
await writeBinaryFile(outputPath, download.bytes, booleanOption(options.force, false));
|
|
744
|
+
|
|
745
|
+
if (options.json) {
|
|
746
|
+
printJson({
|
|
747
|
+
icon: {
|
|
748
|
+
id: reference.id,
|
|
749
|
+
name: reference.slug,
|
|
750
|
+
},
|
|
751
|
+
outputPath,
|
|
752
|
+
contentType: download.contentType,
|
|
753
|
+
filename: download.filename,
|
|
754
|
+
options: payload,
|
|
755
|
+
});
|
|
756
|
+
return;
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
console.log(`Downloaded PNG export`);
|
|
760
|
+
console.log(` ${outputPath}`);
|
|
761
|
+
}
|
|
762
|
+
|
|
698
763
|
async function collection(args) {
|
|
699
764
|
const [subcommand, ...rest] = args;
|
|
700
765
|
|
|
@@ -1810,17 +1875,104 @@ function extensionSet(value) {
|
|
|
1810
1875
|
}
|
|
1811
1876
|
|
|
1812
1877
|
function buildExportOptions(options) {
|
|
1878
|
+
const formats = exportFormatsOption(options.formats);
|
|
1879
|
+
const png = buildCollectionPngOptions(options);
|
|
1880
|
+
const includesPng = formats?.includes('png-pack') || Object.keys(png).length > 0;
|
|
1881
|
+
const normalizedFormats = includesPng && formats === undefined
|
|
1882
|
+
? ['png-pack']
|
|
1883
|
+
: formats;
|
|
1884
|
+
|
|
1813
1885
|
return {
|
|
1814
|
-
formats:
|
|
1886
|
+
formats: normalizedFormats,
|
|
1815
1887
|
options: {
|
|
1816
1888
|
colorPolicy: enumOption(options['color-policy'], 'color policy', COLOR_POLICIES),
|
|
1817
1889
|
namingPolicy: enumOption(options['naming-policy'], 'naming policy', NAMING_POLICIES),
|
|
1818
1890
|
sizeProps: booleanFlagPair(options, 'size-props', 'no-size-props'),
|
|
1819
1891
|
typescript: booleanFlagPair(options, 'typescript', 'no-typescript'),
|
|
1892
|
+
png: includesPng ? png : undefined,
|
|
1820
1893
|
},
|
|
1821
1894
|
};
|
|
1822
1895
|
}
|
|
1823
1896
|
|
|
1897
|
+
function buildIconPngPayload(reference, options) {
|
|
1898
|
+
return {
|
|
1899
|
+
iconName: reference.slug,
|
|
1900
|
+
sizes: integerCsvOption(options.sizes ?? options.size, 'PNG size', PNG_SIZES, [512]),
|
|
1901
|
+
densities: integerCsvOption(options.densities ?? options.density, 'PNG density', PNG_DENSITIES, [1]),
|
|
1902
|
+
backgroundType: enumOption(options.background, 'PNG background', PNG_BACKGROUNDS),
|
|
1903
|
+
backgroundColor: options['background-color'],
|
|
1904
|
+
iconColorMode: enumOption(options.color, 'PNG icon color mode', PNG_COLORS),
|
|
1905
|
+
iconColor: options['icon-color'],
|
|
1906
|
+
padding: integerOption(options.padding, 'PNG padding'),
|
|
1907
|
+
fit: enumOption(options.fit, 'PNG fit mode', PNG_FITS),
|
|
1908
|
+
filename: options.filename,
|
|
1909
|
+
zip: booleanOption(options.zip, undefined),
|
|
1910
|
+
};
|
|
1911
|
+
}
|
|
1912
|
+
|
|
1913
|
+
function buildCollectionPngOptions(options) {
|
|
1914
|
+
return stripUndefined({
|
|
1915
|
+
sizes: integerCsvOption(options['png-sizes'] ?? options['png-size'], 'PNG size', PNG_SIZES, undefined),
|
|
1916
|
+
densities: integerCsvOption(options['png-densities'] ?? options['png-density'], 'PNG density', [1, 2, 3], undefined),
|
|
1917
|
+
backgroundType: enumOption(options['png-background'], 'PNG background', PNG_BACKGROUNDS),
|
|
1918
|
+
backgroundColor: options['png-background-color'],
|
|
1919
|
+
iconColorMode: enumOption(options['png-color'], 'PNG icon color mode', PNG_COLORS),
|
|
1920
|
+
iconColor: options['png-icon-color'],
|
|
1921
|
+
padding: integerOption(options['png-padding'], 'PNG padding'),
|
|
1922
|
+
fit: enumOption(options['png-fit'], 'PNG fit mode', PNG_FITS),
|
|
1923
|
+
});
|
|
1924
|
+
}
|
|
1925
|
+
|
|
1926
|
+
function exportFormatsOption(value) {
|
|
1927
|
+
const values = csvOption(value);
|
|
1928
|
+
|
|
1929
|
+
if (!values) {
|
|
1930
|
+
return undefined;
|
|
1931
|
+
}
|
|
1932
|
+
|
|
1933
|
+
const normalized = values.map((item) => item === 'png' ? 'png-pack' : item);
|
|
1934
|
+
const invalid = normalized.filter((item) => !EXPORT_FORMATS.includes(item));
|
|
1935
|
+
if (invalid.length > 0) {
|
|
1936
|
+
throw usageError(`Invalid export format: ${invalid.join(', ')}. Allowed values: ${EXPORT_FORMATS.join(', ')}, png`);
|
|
1937
|
+
}
|
|
1938
|
+
|
|
1939
|
+
return [...new Set(normalized)];
|
|
1940
|
+
}
|
|
1941
|
+
|
|
1942
|
+
function integerCsvOption(value, label, allowed, fallback) {
|
|
1943
|
+
const values = csvOption(value);
|
|
1944
|
+
|
|
1945
|
+
if (!values) {
|
|
1946
|
+
return fallback;
|
|
1947
|
+
}
|
|
1948
|
+
|
|
1949
|
+
const parsed = values.map((item) => Number(item));
|
|
1950
|
+
const invalid = parsed.filter((item) => !Number.isInteger(item) || !allowed.includes(item));
|
|
1951
|
+
|
|
1952
|
+
if (invalid.length > 0) {
|
|
1953
|
+
throw usageError(`Invalid ${label}: ${invalid.join(', ')}. Allowed values: ${allowed.join(', ')}`);
|
|
1954
|
+
}
|
|
1955
|
+
|
|
1956
|
+
return [...new Set(parsed)];
|
|
1957
|
+
}
|
|
1958
|
+
|
|
1959
|
+
function integerOption(value, label) {
|
|
1960
|
+
if (value === undefined || value === true || value === '') {
|
|
1961
|
+
return undefined;
|
|
1962
|
+
}
|
|
1963
|
+
|
|
1964
|
+
const parsed = Number(value);
|
|
1965
|
+
if (!Number.isInteger(parsed)) {
|
|
1966
|
+
throw usageError(`Invalid ${label}: ${value}. Expected an integer.`);
|
|
1967
|
+
}
|
|
1968
|
+
|
|
1969
|
+
return parsed;
|
|
1970
|
+
}
|
|
1971
|
+
|
|
1972
|
+
function stripUndefined(value) {
|
|
1973
|
+
return Object.fromEntries(Object.entries(value).filter(([, item]) => item !== undefined));
|
|
1974
|
+
}
|
|
1975
|
+
|
|
1824
1976
|
function enumOption(value, label, allowed) {
|
|
1825
1977
|
if (value === undefined || value === true || value === '') {
|
|
1826
1978
|
return undefined;
|
|
@@ -1874,6 +2026,7 @@ Usage:
|
|
|
1874
2026
|
svgicons icon url <icon-ref>
|
|
1875
2027
|
svgicons icon open <icon-ref>
|
|
1876
2028
|
svgicons icon download <icon-id-name> [--output ./icons] [--force]
|
|
2029
|
+
svgicons icon png <icon-id-name> [--size 512] [--density 1,2] [--output ./icons] [--force]
|
|
1877
2030
|
svgicons collection list [--json]
|
|
1878
2031
|
svgicons collection create --name "Dashboard icons"
|
|
1879
2032
|
svgicons collection show <collection-id-or-name> [--icons] [--json]
|
|
@@ -1882,7 +2035,7 @@ Usage:
|
|
|
1882
2035
|
svgicons collection add <collection-id-or-name> <icon-id...>
|
|
1883
2036
|
svgicons collection remove <collection-id-or-name> <icon-id...>
|
|
1884
2037
|
svgicons collection delete <collection-id-or-name> [--yes]
|
|
1885
|
-
svgicons collection export <collection-id-or-name> [--formats react-ts,vue] [--no-size-props] [--no-typescript] [--output ./exports]
|
|
2038
|
+
svgicons collection export <collection-id-or-name> [--formats react-ts,vue,png-pack] [--png-sizes 24,48,512] [--no-size-props] [--no-typescript] [--output ./exports]
|
|
1886
2039
|
svgicons export status <export-id> --collection <collection-id-or-name>
|
|
1887
2040
|
svgicons export download <export-id> --collection <collection-id-or-name> [--output ./exports]
|
|
1888
2041
|
svgicons init [--collection <collection-id-or-name>] [--output svgicons-icons]
|
package/src/downloads.js
CHANGED
|
@@ -95,6 +95,25 @@ export function resolveArchiveDownloadPath(output, filename, cwd = process.cwd()
|
|
|
95
95
|
return join(target, safeFilename);
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
+
export function resolvePngDownloadPath(output, filename, cwd = process.cwd()) {
|
|
99
|
+
const safeFilename = sanitizeFileName(filename || 'svgicons-icon.png', 'png');
|
|
100
|
+
|
|
101
|
+
if (!output || output === true) {
|
|
102
|
+
return resolve(cwd, safeFilename);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const target = isAbsolute(String(output))
|
|
106
|
+
? String(output)
|
|
107
|
+
: resolve(cwd, String(output));
|
|
108
|
+
|
|
109
|
+
const extension = extname(target).toLowerCase();
|
|
110
|
+
if (extension === '.png' || extension === '.zip') {
|
|
111
|
+
return target;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return join(target, safeFilename);
|
|
115
|
+
}
|
|
116
|
+
|
|
98
117
|
export async function writeIconSvg(path, svg, force = false) {
|
|
99
118
|
if (!svg || typeof svg !== 'string') {
|
|
100
119
|
throw new Error('The icon response did not include SVG markup.');
|