@iconify/tools 1.3.17 → 2.0.0-dev.2
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/.editorconfig +13 -0
- package/.eslintignore +2 -0
- package/lib/colors/attribs.d.ts +16 -0
- package/lib/colors/attribs.js +26 -0
- package/lib/colors/attribs.mjs +28 -0
- package/lib/colors/parse.d.ts +37 -0
- package/lib/colors/parse.js +261 -0
- package/lib/colors/parse.mjs +212 -0
- package/lib/css/parse.d.ts +4 -0
- package/lib/css/parse.js +23 -0
- package/lib/css/parse.mjs +20 -0
- package/lib/css/parser/error.d.ts +11 -0
- package/lib/css/parser/error.js +27 -0
- package/lib/css/parser/error.mjs +23 -0
- package/lib/css/parser/export.d.ts +5 -0
- package/lib/css/parser/export.js +69 -0
- package/lib/css/parser/export.mjs +46 -0
- package/lib/css/parser/strings.d.ts +13 -0
- package/lib/css/parser/strings.js +93 -0
- package/lib/css/parser/strings.mjs +74 -0
- package/lib/css/parser/text.d.ts +17 -0
- package/lib/css/parser/text.js +174 -0
- package/lib/css/parser/text.mjs +133 -0
- package/lib/css/parser/tokens.d.ts +6 -0
- package/lib/css/parser/tokens.js +200 -0
- package/lib/css/parser/tokens.mjs +186 -0
- package/lib/css/parser/tree.d.ts +5 -0
- package/lib/css/parser/tree.js +44 -0
- package/lib/css/parser/tree.mjs +40 -0
- package/lib/css/parser/types.d.ts +51 -0
- package/lib/css/parser/types.js +2 -0
- package/lib/css/parser/types.mjs +0 -0
- package/lib/icon-set/index.d.ts +134 -0
- package/lib/icon-set/index.js +776 -0
- package/lib/icon-set/index.mjs +617 -0
- package/lib/icon-set/match.d.ts +6 -0
- package/lib/icon-set/match.js +66 -0
- package/lib/icon-set/match.mjs +55 -0
- package/lib/icon-set/merge.d.ts +5 -0
- package/lib/icon-set/merge.js +91 -0
- package/lib/icon-set/merge.mjs +75 -0
- package/lib/icon-set/props.d.ts +10 -0
- package/lib/icon-set/props.js +33 -0
- package/lib/icon-set/props.mjs +25 -0
- package/lib/icon-set/types.d.ts +68 -0
- package/lib/icon-set/types.js +2 -0
- package/lib/icon-set/types.mjs +0 -0
- package/lib/import/directory.d.ts +35 -0
- package/lib/import/directory.js +59 -0
- package/lib/import/directory.mjs +47 -0
- package/lib/misc/keyword.d.ts +4 -0
- package/lib/misc/keyword.js +31 -0
- package/lib/misc/keyword.mjs +17 -0
- package/lib/misc/scan.d.ts +24 -0
- package/lib/misc/scan.js +48 -0
- package/lib/misc/scan.mjs +43 -0
- package/lib/optimise/flags.d.ts +5 -0
- package/lib/optimise/flags.js +303 -0
- package/lib/optimise/flags.mjs +241 -0
- package/lib/optimise/scale.d.ts +5 -0
- package/lib/optimise/scale.js +42 -0
- package/lib/optimise/scale.mjs +22 -0
- package/lib/optimise/svgo.d.ts +27 -0
- package/lib/optimise/svgo.js +88 -0
- package/lib/optimise/svgo.mjs +75 -0
- package/lib/svg/cleanup/attribs.d.ts +5 -0
- package/lib/svg/cleanup/attribs.js +43 -0
- package/lib/svg/cleanup/attribs.mjs +36 -0
- package/lib/svg/cleanup/bad-tags.d.ts +5 -0
- package/lib/svg/cleanup/bad-tags.js +69 -0
- package/lib/svg/cleanup/bad-tags.mjs +68 -0
- package/lib/svg/cleanup/inline-style.d.ts +5 -0
- package/lib/svg/cleanup/inline-style.js +77 -0
- package/lib/svg/cleanup/inline-style.mjs +65 -0
- package/lib/svg/cleanup/root-svg.d.ts +5 -0
- package/lib/svg/cleanup/root-svg.js +106 -0
- package/lib/svg/cleanup/root-svg.mjs +88 -0
- package/lib/svg/cleanup/svgo-style.d.ts +5 -0
- package/lib/svg/cleanup/svgo-style.js +35 -0
- package/lib/svg/cleanup/svgo-style.mjs +29 -0
- package/lib/svg/cleanup.d.ts +5 -0
- package/lib/svg/cleanup.js +24 -0
- package/lib/svg/cleanup.mjs +16 -0
- package/lib/svg/data/attributes.d.ts +71 -0
- package/lib/svg/data/attributes.js +403 -0
- package/lib/svg/data/attributes.mjs +352 -0
- package/lib/svg/data/tags.d.ts +89 -0
- package/lib/svg/data/tags.js +185 -0
- package/lib/svg/data/tags.mjs +136 -0
- package/lib/svg/index.d.ts +33 -0
- package/lib/svg/index.js +122 -0
- package/lib/svg/index.mjs +85 -0
- package/lib/svg/parse-style.d.ts +40 -0
- package/lib/svg/parse-style.js +131 -0
- package/lib/svg/parse-style.mjs +109 -0
- package/lib/svg/parse.d.ts +30 -0
- package/lib/svg/parse.js +49 -0
- package/lib/svg/parse.mjs +40 -0
- package/package.json +167 -13
- package/README.md +0 -576
- package/license.txt +0 -21
- package/sample/parse.js +0 -74
- package/sample/source/icon-close.svg +0 -15
- package/sample/source/icon-confirm.svg +0 -14
- package/sample/source/icon-search.svg +0 -16
- package/src/collection.js +0 -641
- package/src/colors/change_palette.js +0 -227
- package/src/colors/get_palette.js +0 -143
- package/src/colors/opacify.js +0 -195
- package/src/export/component.js +0 -482
- package/src/export/dir.js +0 -109
- package/src/export/json.js +0 -329
- package/src/export/phantomjs.js +0 -76
- package/src/export/phantomjs_script.js +0 -125
- package/src/export/png.js +0 -193
- package/src/export/svg.js +0 -55
- package/src/export/templates/component.md +0 -79
- package/src/export/templates/info.md +0 -3
- package/src/export/templates/sample-react-1.md +0 -21
- package/src/export/templates/sample-react-2.md +0 -15
- package/src/export/templates/sample-react.md +0 -11
- package/src/export/templates/sample-svelte.md +0 -11
- package/src/export/templates/sample-svelte1.md +0 -22
- package/src/export/templates/sample-svelte2.md +0 -13
- package/src/export/templates/sample-vue-0.md +0 -30
- package/src/export/templates/sample-vue-1.md +0 -25
- package/src/export/templates/sample-vue-2.md +0 -27
- package/src/export/templates/sample-vue.md +0 -28
- package/src/helpers.js +0 -43
- package/src/import/dir.js +0 -234
- package/src/import/font.js +0 -402
- package/src/import/json.js +0 -200
- package/src/import/svg.js +0 -60
- package/src/import/web_icons.js +0 -248
- package/src/modules.js +0 -50
- package/src/optimize/crop.js +0 -554
- package/src/optimize/crop_script.js +0 -525
- package/src/optimize/flags.js +0 -430
- package/src/optimize/scale.js +0 -72
- package/src/optimize/svgo.js +0 -161
- package/src/optimize/tags.js +0 -522
- package/src/shapes/convert.js +0 -264
- package/src/shapes/index.js +0 -135
- package/src/shapes/length.js +0 -707
- package/src/shapes/length_script.js +0 -105
- package/src/shapes/options.js +0 -60
- package/src/svg.js +0 -162
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// src/icon-set/match.ts
|
|
2
|
+
import { iconDefaults } from "@iconify/utils/lib/icon";
|
|
3
|
+
var maxIteration = 5;
|
|
4
|
+
function findMatchingIcon(iconSet, icon) {
|
|
5
|
+
const body = icon.body;
|
|
6
|
+
let hiddenMatch = null;
|
|
7
|
+
function isMatching(data) {
|
|
8
|
+
for (const key in iconDefaults) {
|
|
9
|
+
const attr = key;
|
|
10
|
+
if (data[attr] !== icon[attr]) {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
function test(name, iteration) {
|
|
17
|
+
const data = iconSet.resolve(name, true);
|
|
18
|
+
if (!data) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
if (isMatching(data)) {
|
|
22
|
+
if (data.hidden) {
|
|
23
|
+
hiddenMatch = name;
|
|
24
|
+
} else {
|
|
25
|
+
return name;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (iteration > maxIteration) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
for (const key in iconSet.entries) {
|
|
32
|
+
const item = iconSet.entries[key];
|
|
33
|
+
if (item.type === "variation" && item.parent === name) {
|
|
34
|
+
const result = test(key, iteration + 1);
|
|
35
|
+
if (typeof result === "string") {
|
|
36
|
+
return result;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
for (const key in iconSet.entries) {
|
|
43
|
+
const item = iconSet.entries[key];
|
|
44
|
+
if (item.type === "icon" && item.body === body) {
|
|
45
|
+
const result = test(key, 0);
|
|
46
|
+
if (typeof result === "string") {
|
|
47
|
+
return result;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return hiddenMatch;
|
|
52
|
+
}
|
|
53
|
+
export {
|
|
54
|
+
findMatchingIcon
|
|
55
|
+
};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.mergeIconSets = void 0;
|
|
4
|
+
const _1 = require(".");
|
|
5
|
+
const match_1 = require("./match");
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars-experimental, @typescript-eslint/no-unused-vars
|
|
7
|
+
function assertNever(v) {
|
|
8
|
+
//
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Merge icon sets
|
|
12
|
+
*/
|
|
13
|
+
function mergeIconSets(oldIcons, newIcons) {
|
|
14
|
+
const mergedIcons = new _1.IconSet(newIcons.export());
|
|
15
|
+
const oldEntries = oldIcons.entries;
|
|
16
|
+
const entries = mergedIcons.entries;
|
|
17
|
+
function add(name) {
|
|
18
|
+
if (entries[name]) {
|
|
19
|
+
// Already exists
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
const item = oldEntries[name];
|
|
23
|
+
switch (item.type) {
|
|
24
|
+
case 'icon': {
|
|
25
|
+
// Attempt to find matching icon
|
|
26
|
+
const fullIcon = oldIcons.resolve(name, true);
|
|
27
|
+
const parent = fullIcon
|
|
28
|
+
? (0, match_1.findMatchingIcon)(mergedIcons, fullIcon)
|
|
29
|
+
: null;
|
|
30
|
+
if (parent !== null) {
|
|
31
|
+
// Add as alias
|
|
32
|
+
mergedIcons.setAlias(name, parent);
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
// Add as is, duplicating props
|
|
36
|
+
const props = item.props;
|
|
37
|
+
mergedIcons.setItem(name, {
|
|
38
|
+
...item,
|
|
39
|
+
props: {
|
|
40
|
+
...props,
|
|
41
|
+
hidden: true,
|
|
42
|
+
},
|
|
43
|
+
categories: new Set(),
|
|
44
|
+
});
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
case 'variation':
|
|
48
|
+
case 'alias': {
|
|
49
|
+
// Add parent
|
|
50
|
+
let parent = item.parent;
|
|
51
|
+
if (!add(parent)) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
const parentItem = entries[parent];
|
|
55
|
+
if (parentItem.type === 'alias') {
|
|
56
|
+
// Alias of alias - use parent
|
|
57
|
+
parent = parentItem.parent;
|
|
58
|
+
}
|
|
59
|
+
if (item.type === 'variation') {
|
|
60
|
+
// Hide variation and copy props
|
|
61
|
+
const props = item.props;
|
|
62
|
+
mergedIcons.setItem(name, {
|
|
63
|
+
...item,
|
|
64
|
+
parent,
|
|
65
|
+
props: {
|
|
66
|
+
...props,
|
|
67
|
+
hidden: true,
|
|
68
|
+
},
|
|
69
|
+
categories: new Set(),
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
mergedIcons.setItem(name, {
|
|
74
|
+
...item,
|
|
75
|
+
parent,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
default:
|
|
81
|
+
assertNever(item);
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// Add old icons
|
|
86
|
+
for (const name in oldEntries) {
|
|
87
|
+
add(name);
|
|
88
|
+
}
|
|
89
|
+
return mergedIcons;
|
|
90
|
+
}
|
|
91
|
+
exports.mergeIconSets = mergeIconSets;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// src/icon-set/merge.ts
|
|
2
|
+
import { IconSet } from "./index.mjs";
|
|
3
|
+
import { findMatchingIcon } from "./match.mjs";
|
|
4
|
+
function assertNever(v) {
|
|
5
|
+
}
|
|
6
|
+
function mergeIconSets(oldIcons, newIcons) {
|
|
7
|
+
const mergedIcons = new IconSet(newIcons.export());
|
|
8
|
+
const oldEntries = oldIcons.entries;
|
|
9
|
+
const entries = mergedIcons.entries;
|
|
10
|
+
function add(name) {
|
|
11
|
+
if (entries[name]) {
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
const item = oldEntries[name];
|
|
15
|
+
switch (item.type) {
|
|
16
|
+
case "icon": {
|
|
17
|
+
const fullIcon = oldIcons.resolve(name, true);
|
|
18
|
+
const parent = fullIcon ? findMatchingIcon(mergedIcons, fullIcon) : null;
|
|
19
|
+
if (parent !== null) {
|
|
20
|
+
mergedIcons.setAlias(name, parent);
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
const props = item.props;
|
|
24
|
+
mergedIcons.setItem(name, {
|
|
25
|
+
...item,
|
|
26
|
+
props: {
|
|
27
|
+
...props,
|
|
28
|
+
hidden: true
|
|
29
|
+
},
|
|
30
|
+
categories: new Set()
|
|
31
|
+
});
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
case "variation":
|
|
35
|
+
case "alias": {
|
|
36
|
+
let parent = item.parent;
|
|
37
|
+
if (!add(parent)) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
const parentItem = entries[parent];
|
|
41
|
+
if (parentItem.type === "alias") {
|
|
42
|
+
parent = parentItem.parent;
|
|
43
|
+
}
|
|
44
|
+
if (item.type === "variation") {
|
|
45
|
+
const props = item.props;
|
|
46
|
+
mergedIcons.setItem(name, {
|
|
47
|
+
...item,
|
|
48
|
+
parent,
|
|
49
|
+
props: {
|
|
50
|
+
...props,
|
|
51
|
+
hidden: true
|
|
52
|
+
},
|
|
53
|
+
categories: new Set()
|
|
54
|
+
});
|
|
55
|
+
} else {
|
|
56
|
+
mergedIcons.setItem(name, {
|
|
57
|
+
...item,
|
|
58
|
+
parent
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
default:
|
|
64
|
+
assertNever(item);
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
for (const name in oldEntries) {
|
|
69
|
+
add(name);
|
|
70
|
+
}
|
|
71
|
+
return mergedIcons;
|
|
72
|
+
}
|
|
73
|
+
export {
|
|
74
|
+
mergeIconSets
|
|
75
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CommonIconProps, ExtraIconProps } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Default properties
|
|
4
|
+
*/
|
|
5
|
+
export declare const extraDefaultProps: Required<ExtraIconProps>;
|
|
6
|
+
export declare const defaultCommonProps: Required<CommonIconProps>;
|
|
7
|
+
/**
|
|
8
|
+
* Filter icon props: copies properties, removing undefined and default entries
|
|
9
|
+
*/
|
|
10
|
+
export declare function filterProps(data: CommonIconProps): CommonIconProps;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.filterProps = exports.defaultCommonProps = exports.extraDefaultProps = void 0;
|
|
4
|
+
const icon_1 = require("@iconify/utils/lib/icon");
|
|
5
|
+
/**
|
|
6
|
+
* Default properties
|
|
7
|
+
*/
|
|
8
|
+
exports.extraDefaultProps = {
|
|
9
|
+
hidden: false,
|
|
10
|
+
};
|
|
11
|
+
exports.defaultCommonProps = {
|
|
12
|
+
...icon_1.iconDefaults,
|
|
13
|
+
...exports.extraDefaultProps,
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Properties to filter
|
|
17
|
+
*/
|
|
18
|
+
const props = Object.keys(exports.defaultCommonProps);
|
|
19
|
+
/**
|
|
20
|
+
* Filter icon props: copies properties, removing undefined and default entries
|
|
21
|
+
*/
|
|
22
|
+
function filterProps(data) {
|
|
23
|
+
const result = {};
|
|
24
|
+
props.forEach((attr) => {
|
|
25
|
+
const value = data[attr];
|
|
26
|
+
if (value !== void 0 &&
|
|
27
|
+
value !== exports.defaultCommonProps[attr]) {
|
|
28
|
+
result[attr] = value;
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
exports.filterProps = filterProps;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// src/icon-set/props.ts
|
|
2
|
+
import { iconDefaults } from "@iconify/utils/lib/icon";
|
|
3
|
+
var extraDefaultProps = {
|
|
4
|
+
hidden: false
|
|
5
|
+
};
|
|
6
|
+
var defaultCommonProps = {
|
|
7
|
+
...iconDefaults,
|
|
8
|
+
...extraDefaultProps
|
|
9
|
+
};
|
|
10
|
+
var props = Object.keys(defaultCommonProps);
|
|
11
|
+
function filterProps(data) {
|
|
12
|
+
const result = {};
|
|
13
|
+
props.forEach((attr) => {
|
|
14
|
+
const value = data[attr];
|
|
15
|
+
if (value !== void 0 && value !== defaultCommonProps[attr]) {
|
|
16
|
+
result[attr] = value;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
return result;
|
|
20
|
+
}
|
|
21
|
+
export {
|
|
22
|
+
defaultCommonProps,
|
|
23
|
+
extraDefaultProps,
|
|
24
|
+
filterProps
|
|
25
|
+
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { IconifyIcon, ExtendedIconifyIcon, ExtendedIconifyAlias, IconifyOptional } from '@iconify/types';
|
|
2
|
+
/**
|
|
3
|
+
* Category item
|
|
4
|
+
*/
|
|
5
|
+
export interface IconCategory {
|
|
6
|
+
title: string;
|
|
7
|
+
count: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Get common properties: IconifyOptional + APIIconAttributes
|
|
11
|
+
*/
|
|
12
|
+
declare type CommonProps<A, B> = {
|
|
13
|
+
[K in keyof A & keyof B]?: A[K] extends B[K] ? A[K] : never;
|
|
14
|
+
};
|
|
15
|
+
export declare type CommonIconProps = CommonProps<ExtendedIconifyIcon, ExtendedIconifyAlias>;
|
|
16
|
+
/**
|
|
17
|
+
* Exclude IconifyOptional from CommonIconProps
|
|
18
|
+
*/
|
|
19
|
+
export declare type ExtraIconProps = Omit<CommonIconProps, keyof IconifyOptional>;
|
|
20
|
+
/**
|
|
21
|
+
* Partials
|
|
22
|
+
*/
|
|
23
|
+
export interface IconWithPropsData {
|
|
24
|
+
props: CommonIconProps;
|
|
25
|
+
chars: Set<string>;
|
|
26
|
+
categories: Set<IconCategory>;
|
|
27
|
+
}
|
|
28
|
+
export interface IconParentData {
|
|
29
|
+
parent: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Icon types
|
|
33
|
+
*/
|
|
34
|
+
export interface IconSetIcon extends IconWithPropsData {
|
|
35
|
+
type: 'icon';
|
|
36
|
+
body: string;
|
|
37
|
+
}
|
|
38
|
+
export interface IconSetIconAlias extends IconParentData {
|
|
39
|
+
type: 'alias';
|
|
40
|
+
}
|
|
41
|
+
export interface IconSetIconVariation extends IconWithPropsData, IconParentData {
|
|
42
|
+
type: 'variation';
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* All icon types
|
|
46
|
+
*/
|
|
47
|
+
export declare type IconSetIconEntry = IconSetIcon | IconSetIconAlias | IconSetIconVariation;
|
|
48
|
+
export declare type IconSetIconType = IconSetIconEntry['type'];
|
|
49
|
+
/**
|
|
50
|
+
* Full icon with extra stuff
|
|
51
|
+
*/
|
|
52
|
+
export interface ResolvedIconifyIcon extends IconifyIcon, ExtraIconProps {
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Result for checking theme: list of names for each theme
|
|
56
|
+
*/
|
|
57
|
+
export interface CheckThemeResult {
|
|
58
|
+
valid: Record<string, string[]>;
|
|
59
|
+
invalid: string[];
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Callback for asyncForEach function
|
|
63
|
+
*
|
|
64
|
+
* Return false to stop loop
|
|
65
|
+
*/
|
|
66
|
+
declare type IconSetAsyncForEachCallbackResult = void | false;
|
|
67
|
+
export declare type IconSetAsyncForEachCallback = (name: string, type: IconSetIconEntry['type']) => Promise<IconSetAsyncForEachCallbackResult> | IconSetAsyncForEachCallbackResult;
|
|
68
|
+
export {};
|
|
File without changes
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { IconSet } from '../icon-set';
|
|
2
|
+
/**
|
|
3
|
+
* Entry for file
|
|
4
|
+
*/
|
|
5
|
+
export interface ImportDirectpryFileEntry {
|
|
6
|
+
path: string;
|
|
7
|
+
subdir: string;
|
|
8
|
+
file: string;
|
|
9
|
+
ext: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Callback to get keyword for icon based on file name
|
|
13
|
+
*
|
|
14
|
+
* Returns:
|
|
15
|
+
* - string for new keyword
|
|
16
|
+
* - undefined to skip icon
|
|
17
|
+
*
|
|
18
|
+
* Callback can be asynchronous
|
|
19
|
+
*/
|
|
20
|
+
declare type ImportDirectoryKeywordCallbackResult = string | undefined;
|
|
21
|
+
export declare type ImportDirectoryKeywordCallback = (file: ImportDirectpryFileEntry, defaultKeyword: string, iconSet: IconSet) => ImportDirectoryKeywordCallbackResult | Promise<ImportDirectoryKeywordCallbackResult>;
|
|
22
|
+
/**
|
|
23
|
+
* Options
|
|
24
|
+
*/
|
|
25
|
+
interface ImportDirectoryOptions {
|
|
26
|
+
prefix?: string;
|
|
27
|
+
includeSubDirs?: boolean;
|
|
28
|
+
keyword?: ImportDirectoryKeywordCallback;
|
|
29
|
+
ignoreImportErrors?: boolean;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Import all icons from directory
|
|
33
|
+
*/
|
|
34
|
+
export declare function importDirectory(path: string, options?: ImportDirectoryOptions): Promise<IconSet>;
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.importDirectory = void 0;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const icon_set_1 = require("../icon-set");
|
|
6
|
+
const keyword_1 = require("../misc/keyword");
|
|
7
|
+
const scan_1 = require("../misc/scan");
|
|
8
|
+
const svg_1 = require("../svg");
|
|
9
|
+
const cleanup_1 = require("../svg/cleanup");
|
|
10
|
+
/**
|
|
11
|
+
* Import all icons from directory
|
|
12
|
+
*/
|
|
13
|
+
async function importDirectory(path, options = {}) {
|
|
14
|
+
// Find all files
|
|
15
|
+
const files = await (0, scan_1.scanDirectory)(path, (ext, file, subdir, path) => {
|
|
16
|
+
if (ext.toLowerCase() === '.svg') {
|
|
17
|
+
const result = {
|
|
18
|
+
file,
|
|
19
|
+
ext,
|
|
20
|
+
subdir,
|
|
21
|
+
path,
|
|
22
|
+
};
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
25
|
+
return false;
|
|
26
|
+
});
|
|
27
|
+
// Create blank icon set
|
|
28
|
+
const iconSet = (0, icon_set_1.blankIconSet)(options.prefix || '');
|
|
29
|
+
// Import all files
|
|
30
|
+
for (let i = 0; i < files.length; i++) {
|
|
31
|
+
const file = files[i];
|
|
32
|
+
// Get keyword
|
|
33
|
+
const defaultKeyword = (0, keyword_1.cleanupIconKeyword)(file.file);
|
|
34
|
+
let keyword = options.keyword
|
|
35
|
+
? options.keyword(file, defaultKeyword, iconSet)
|
|
36
|
+
: defaultKeyword;
|
|
37
|
+
if (keyword instanceof Promise) {
|
|
38
|
+
keyword = await keyword;
|
|
39
|
+
}
|
|
40
|
+
// Check it
|
|
41
|
+
if (typeof keyword !== 'string' || !keyword.length) {
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
// Import icon, clean it up
|
|
45
|
+
try {
|
|
46
|
+
const content = await fs_1.promises.readFile(file.path + file.subdir + file.file + file.ext, 'utf8');
|
|
47
|
+
const svg = new svg_1.SVG(content);
|
|
48
|
+
await (0, cleanup_1.cleanupSVG)(svg);
|
|
49
|
+
iconSet.fromSVG(keyword, svg);
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
if (options.ignoreImportErrors !== false) {
|
|
53
|
+
throw err;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return iconSet;
|
|
58
|
+
}
|
|
59
|
+
exports.importDirectory = importDirectory;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// src/import/directory.ts
|
|
2
|
+
import { promises as fs } from "fs";
|
|
3
|
+
import { blankIconSet } from "../icon-set/index.mjs";
|
|
4
|
+
import { cleanupIconKeyword } from "../misc/keyword.mjs";
|
|
5
|
+
import { scanDirectory } from "../misc/scan.mjs";
|
|
6
|
+
import { SVG } from "../svg/index.mjs";
|
|
7
|
+
import { cleanupSVG } from "../svg/cleanup.mjs";
|
|
8
|
+
async function importDirectory(path, options = {}) {
|
|
9
|
+
const files = await scanDirectory(path, (ext, file, subdir, path2) => {
|
|
10
|
+
if (ext.toLowerCase() === ".svg") {
|
|
11
|
+
const result = {
|
|
12
|
+
file,
|
|
13
|
+
ext,
|
|
14
|
+
subdir,
|
|
15
|
+
path: path2
|
|
16
|
+
};
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
return false;
|
|
20
|
+
});
|
|
21
|
+
const iconSet = blankIconSet(options.prefix || "");
|
|
22
|
+
for (let i = 0; i < files.length; i++) {
|
|
23
|
+
const file = files[i];
|
|
24
|
+
const defaultKeyword = cleanupIconKeyword(file.file);
|
|
25
|
+
let keyword = options.keyword ? options.keyword(file, defaultKeyword, iconSet) : defaultKeyword;
|
|
26
|
+
if (keyword instanceof Promise) {
|
|
27
|
+
keyword = await keyword;
|
|
28
|
+
}
|
|
29
|
+
if (typeof keyword !== "string" || !keyword.length) {
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
const content = await fs.readFile(file.path + file.subdir + file.file + file.ext, "utf8");
|
|
34
|
+
const svg = new SVG(content);
|
|
35
|
+
await cleanupSVG(svg);
|
|
36
|
+
iconSet.fromSVG(keyword, svg);
|
|
37
|
+
} catch (err) {
|
|
38
|
+
if (options.ignoreImportErrors !== false) {
|
|
39
|
+
throw err;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return iconSet;
|
|
44
|
+
}
|
|
45
|
+
export {
|
|
46
|
+
importDirectory
|
|
47
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.cleanupIconKeyword = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Clean up keyword
|
|
6
|
+
*/
|
|
7
|
+
function cleanupIconKeyword(keyword, convertCamelCase = false) {
|
|
8
|
+
// Convert camelCase to dash-case
|
|
9
|
+
if (convertCamelCase) {
|
|
10
|
+
keyword = keyword.replace(/[A-Z]+/g, (chars) => '_' + chars.toLowerCase());
|
|
11
|
+
}
|
|
12
|
+
// Replace stuff
|
|
13
|
+
keyword = keyword
|
|
14
|
+
.toLowerCase()
|
|
15
|
+
.trim()
|
|
16
|
+
// Replace few characters with dash
|
|
17
|
+
.replace(/[_.:]/g, '-')
|
|
18
|
+
// Remove bad characters
|
|
19
|
+
.replace(/[^a-z0-9-]/g, '')
|
|
20
|
+
// Replace repeating dash
|
|
21
|
+
.replace(/[-]+/g, '-');
|
|
22
|
+
// Remove '-' at start and end
|
|
23
|
+
if (keyword.slice(0, 1) === '-') {
|
|
24
|
+
keyword = keyword.slice(1);
|
|
25
|
+
}
|
|
26
|
+
if (keyword.slice(-1) === '-') {
|
|
27
|
+
keyword = keyword.slice(0, keyword.length - 1);
|
|
28
|
+
}
|
|
29
|
+
return keyword;
|
|
30
|
+
}
|
|
31
|
+
exports.cleanupIconKeyword = cleanupIconKeyword;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// src/misc/keyword.ts
|
|
2
|
+
function cleanupIconKeyword(keyword, convertCamelCase = false) {
|
|
3
|
+
if (convertCamelCase) {
|
|
4
|
+
keyword = keyword.replace(/[A-Z]+/g, (chars) => "_" + chars.toLowerCase());
|
|
5
|
+
}
|
|
6
|
+
keyword = keyword.toLowerCase().trim().replace(/[_.:]/g, "-").replace(/[^a-z0-9-]/g, "").replace(/[-]+/g, "-");
|
|
7
|
+
if (keyword.slice(0, 1) === "-") {
|
|
8
|
+
keyword = keyword.slice(1);
|
|
9
|
+
}
|
|
10
|
+
if (keyword.slice(-1) === "-") {
|
|
11
|
+
keyword = keyword.slice(0, keyword.length - 1);
|
|
12
|
+
}
|
|
13
|
+
return keyword;
|
|
14
|
+
}
|
|
15
|
+
export {
|
|
16
|
+
cleanupIconKeyword
|
|
17
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Callback
|
|
3
|
+
*
|
|
4
|
+
* Extension starts with '.' (can be empty)
|
|
5
|
+
* File does not include extension
|
|
6
|
+
* Subdir ends with '/' (can be empty)
|
|
7
|
+
*
|
|
8
|
+
* Should return:
|
|
9
|
+
* - false, null or undefined to skip file
|
|
10
|
+
* - true to include file (subdir + file + extension)
|
|
11
|
+
* - string to include custom string (such as file without extension)
|
|
12
|
+
* - custom object to return custom object
|
|
13
|
+
*/
|
|
14
|
+
declare type ScanDirectoryCallbackFalseResult = boolean | null | undefined;
|
|
15
|
+
declare type ScanDirectoryCallbackStringResult = ScanDirectoryCallbackFalseResult | string;
|
|
16
|
+
declare type ScanDirectoryCallbackAsString = (ext: string, file: string, subdir: string, path: string) => ScanDirectoryCallbackStringResult | Promise<ScanDirectoryCallbackStringResult>;
|
|
17
|
+
declare type ScanDirectoryCallbackAsCustom<T> = (ext: string, file: string, subdir: string, path: string) => T | ScanDirectoryCallbackFalseResult | Promise<T | ScanDirectoryCallbackFalseResult>;
|
|
18
|
+
export declare type ScanDirectoryCallback = ScanDirectoryCallbackAsCustom<unknown> | ScanDirectoryCallbackAsString;
|
|
19
|
+
/**
|
|
20
|
+
* Find all files in directory
|
|
21
|
+
*/
|
|
22
|
+
export declare function scanDirectory(path: string, callback: ScanDirectoryCallbackAsString, subdirs?: boolean): Promise<string[]>;
|
|
23
|
+
export declare function scanDirectory<T>(path: string, callback: ScanDirectoryCallbackAsCustom<T>, subdirs?: boolean): Promise<T[]>;
|
|
24
|
+
export {};
|
package/lib/misc/scan.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.scanDirectory = void 0;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
async function scanDirectory(path, callback, subdirs = true) {
|
|
6
|
+
const results = [];
|
|
7
|
+
if (path.length && path.slice(-1) !== '/') {
|
|
8
|
+
path += '/';
|
|
9
|
+
}
|
|
10
|
+
async function scan(subdir) {
|
|
11
|
+
const files = await fs_1.promises.readdir(path + subdir);
|
|
12
|
+
for (let i = 0; i < files.length; i++) {
|
|
13
|
+
const filename = files[i];
|
|
14
|
+
if (filename.slice(0, 1) === '.') {
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
const stat = await fs_1.promises.lstat(path + subdir + filename);
|
|
18
|
+
if (stat.isDirectory()) {
|
|
19
|
+
if (subdirs) {
|
|
20
|
+
await scan(subdir + filename + '/');
|
|
21
|
+
}
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
if (!stat.isFile()) {
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
const parts = filename.split('.');
|
|
28
|
+
const ext = parts.length > 1 ? '.' + parts.pop() : '';
|
|
29
|
+
const file = parts.join('.');
|
|
30
|
+
// Callback
|
|
31
|
+
let callbackResult = callback(ext, file, subdir, path);
|
|
32
|
+
if (callbackResult instanceof Promise) {
|
|
33
|
+
callbackResult = await callbackResult;
|
|
34
|
+
}
|
|
35
|
+
if (callbackResult === void 0 ||
|
|
36
|
+
callbackResult === false ||
|
|
37
|
+
callbackResult === null) {
|
|
38
|
+
// Skip file
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
// Add item
|
|
42
|
+
results.push(callbackResult === true ? subdir + filename : callbackResult);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
await scan('');
|
|
46
|
+
return results;
|
|
47
|
+
}
|
|
48
|
+
exports.scanDirectory = scanDirectory;
|