trueicon 0.1.1 → 0.2.1
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 +88 -14
- package/dist/providers/adapters/antdesign.d.ts +3 -0
- package/dist/providers/adapters/antdesign.js +60 -0
- package/dist/providers/adapters/antdesign.js.map +1 -0
- package/dist/providers/adapters/carbon.d.ts +10 -0
- package/dist/providers/adapters/carbon.js +129 -0
- package/dist/providers/adapters/carbon.js.map +1 -0
- package/dist/providers/adapters/fluentui.d.ts +7 -0
- package/dist/providers/adapters/fluentui.js +71 -0
- package/dist/providers/adapters/fluentui.js.map +1 -0
- package/dist/providers/adapters/iconoir.d.ts +4 -0
- package/dist/providers/adapters/iconoir.js +58 -0
- package/dist/providers/adapters/iconoir.js.map +1 -0
- package/dist/providers/adapters/index.js +12 -0
- package/dist/providers/adapters/index.js.map +1 -1
- package/dist/providers/adapters/lucide.js +67 -20
- package/dist/providers/adapters/lucide.js.map +1 -1
- package/dist/providers/adapters/phosphor.d.ts +4 -0
- package/dist/providers/adapters/phosphor.js +78 -0
- package/dist/providers/adapters/phosphor.js.map +1 -0
- package/dist/providers/adapters/tabler.d.ts +8 -0
- package/dist/providers/adapters/tabler.js +77 -0
- package/dist/providers/adapters/tabler.js.map +1 -0
- package/dist/providers/registry.js +31 -1
- package/dist/providers/registry.js.map +1 -1
- package/dist/providers/svg.d.ts +2 -1
- package/dist/providers/svg.js +16 -0
- package/dist/providers/svg.js.map +1 -1
- package/dist/search/search.d.ts +5 -1
- package/dist/search/search.js +20 -6
- package/dist/search/search.js.map +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js +1 -1
- package/dist/tools/getIcon.js +8 -1
- package/dist/tools/getIcon.js.map +1 -1
- package/package.json +13 -3
package/README.md
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
# TrueIcon
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/trueicon)
|
|
4
|
+
[](https://insiders.vscode.dev/redirect/mcp/install?name=trueicon&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22trueicon%22%5D%2C%22env%22%3A%7B%22TRUEICON_PROJECT_DIR%22%3A%22%24%7BworkspaceFolder%7D%22%7D%7D)
|
|
5
|
+
[](https://insiders.vscode.dev/redirect/mcp/install?name=trueicon&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22trueicon%22%5D%2C%22env%22%3A%7B%22TRUEICON_PROJECT_DIR%22%3A%22%24%7BworkspaceFolder%7D%22%7D%7D&quality=insiders)
|
|
6
|
+
[](https://cursor.com/en/install-mcp?name=trueicon&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsInRydWVpY29uIl0sImVudiI6eyJUUlVFSUNPTl9QUk9KRUNUX0RJUiI6IiR7d29ya3NwYWNlRm9sZGVyfSJ9fQ%3D%3D)
|
|
7
|
+
|
|
8
|
+
TrueIcon is an [MCP](https://modelcontextprotocol.io) server that gives AI coding assistants exact, version-correct icon references. Your assistant searches the icon packages your project actually uses (`lucide-react`, `react-icons`, `@heroicons/react`, `@phosphor-icons/react`, `@tabler/icons-react`, `iconoir-react`, `@fluentui/react-icons`, `@carbon/icons-react`, `@ant-design/icons`) and gets back real icon names, import paths and a ready-to-paste `import` line.
|
|
4
9
|
|
|
5
10
|
## Why
|
|
6
11
|
|
|
@@ -12,13 +17,19 @@ AI assistants often guess icon names. The guess can be an icon that never existe
|
|
|
12
17
|
|
|
13
18
|
## Supported providers
|
|
14
19
|
|
|
15
|
-
| Provider id | npm package
|
|
16
|
-
| ------------- |
|
|
17
|
-
| `lucide` | `lucide-react`
|
|
18
|
-
| `heroicons` | `@heroicons/react`
|
|
19
|
-
| `react-icons` | `react-icons`
|
|
20
|
+
| Provider id | npm package | Icon naming |
|
|
21
|
+
| ------------- | ----------------------- | -------------------------------------------------------------------------------------------------------- |
|
|
22
|
+
| `lucide` | `lucide-react` | Lucide's file names, e.g. `trash-2` → `Trash2` |
|
|
23
|
+
| `heroicons` | `@heroicons/react` | `<icon>-<size>-<style>`, e.g. `trash-24-outline` → `TrashIcon` |
|
|
24
|
+
| `react-icons` | `react-icons` | `<set>-<icon>`, e.g. `fa6-beer-mug-empty` → `FaBeerMugEmpty` |
|
|
25
|
+
| `phosphor` | `@phosphor-icons/react` | `<icon>` for the regular weight, `<icon>-<weight>` otherwise, e.g. `trash-bold` → `TrashIcon` with `weight="bold"` |
|
|
26
|
+
| `tabler` | `@tabler/icons-react` | Tabler's icon names, e.g. `trash` → `IconTrash`, `trash-filled` → `IconTrashFilled` |
|
|
27
|
+
| `iconoir` | `iconoir-react` | `<icon>` for regular, `<icon>-solid` for solid, e.g. `trash-solid` → `TrashSolid` |
|
|
28
|
+
| `fluentui` | `@fluentui/react-icons` | `<icon>-<style>` with style `regular`, `filled` or `color`, e.g. `delete-regular` → `DeleteRegular`. Only the scalable (1em) icons are indexed, not the size-specific variants |
|
|
29
|
+
| `carbon` | `@carbon/icons-react` | Carbon's export names in kebab case, e.g. `trash-can` → `TrashCan`. Variants add `-filled`, `-alt` or `-color`, e.g. `accessibility-filled` → `AccessibilityFilled` |
|
|
30
|
+
| `antdesign` | `@ant-design/icons` | `<icon>-<theme>` with theme `outlined`, `filled` or `two-tone`, e.g. `delete-outlined` → `DeleteOutlined` |
|
|
20
31
|
|
|
21
|
-
Tools accept either the provider id or the npm package name (`"lucide"` or `"lucide-react"`). Usage snippets are for React.
|
|
32
|
+
Tools accept either the provider id or the npm package name (`"lucide"` or `"lucide-react"`). Usage snippets are for React. Phosphor weights all share one component, so pass the record's `style` as the `weight` prop (e.g. `<TrashIcon weight="bold" />`); the usage snippet only shows the import.
|
|
22
33
|
|
|
23
34
|
## Install
|
|
24
35
|
|
|
@@ -33,7 +44,7 @@ npm i -g trueicon
|
|
|
33
44
|
trueicon
|
|
34
45
|
```
|
|
35
46
|
|
|
36
|
-
`trueicon` is a stdio MCP server. Your MCP client starts it; running it by hand only prints `trueicon: v0.
|
|
47
|
+
`trueicon` is a stdio MCP server. Your MCP client starts it; running it by hand only prints `trueicon: v0.2.0 running on stdio` to stderr and waits for JSON-RPC on stdin.
|
|
37
48
|
|
|
38
49
|
## Quick start
|
|
39
50
|
|
|
@@ -68,7 +79,7 @@ TrueIcon looks for `.iconmcp.json` in the project directory. That is `$TRUEICON_
|
|
|
68
79
|
| Field | Type | Required | Meaning |
|
|
69
80
|
| ----------------------- | ------ | -------- | ---------------------------------------------------------------------------------------- |
|
|
70
81
|
| `providers` | array | yes | Icon packages the project uses. `search_icons` searches all of them by default. |
|
|
71
|
-
| `providers[].package` | string | yes | npm package name: `lucide-react`, `react-icons` or `@
|
|
82
|
+
| `providers[].package` | string | yes | npm package name: `lucide-react`, `react-icons`, `@heroicons/react`, `@phosphor-icons/react`, `@tabler/icons-react`, `iconoir-react`, `@fluentui/react-icons`, `@carbon/icons-react` or `@ant-design/icons`. |
|
|
72
83
|
| `providers[].version` | string | no | Exact version or npm range. If omitted, it is read from `package.json` (see below). |
|
|
73
84
|
|
|
74
85
|
- If the file is missing, no providers are configured. `search_icons` then only works when you pass `provider` explicitly, and `get_icon` still works.
|
|
@@ -148,6 +159,28 @@ Claude Desktop doesn't start servers in your project directory, so set `TRUEICON
|
|
|
148
159
|
|
|
149
160
|
Restart Claude Desktop after editing the file.
|
|
150
161
|
|
|
162
|
+
## Using it in VS Code and Cursor
|
|
163
|
+
|
|
164
|
+
Use the install badges at the top of this README. They add TrueIcon with `TRUEICON_PROJECT_DIR` set to `${workspaceFolder}`, so it searches the project you have open.
|
|
165
|
+
|
|
166
|
+
To add it by hand in VS Code, create `.vscode/mcp.json` in your project:
|
|
167
|
+
|
|
168
|
+
```json
|
|
169
|
+
{
|
|
170
|
+
"servers": {
|
|
171
|
+
"trueicon": {
|
|
172
|
+
"command": "npx",
|
|
173
|
+
"args": ["-y", "trueicon"],
|
|
174
|
+
"env": {
|
|
175
|
+
"TRUEICON_PROJECT_DIR": "${workspaceFolder}"
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
In Cursor, use the same entry under `"mcpServers"` in `.cursor/mcp.json`.
|
|
183
|
+
|
|
151
184
|
## Tools
|
|
152
185
|
|
|
153
186
|
Every tool returns a single JSON text block. On failure, the block is `{"error": "..."}` and the MCP result is flagged with `isError: true`.
|
|
@@ -161,7 +194,7 @@ Searches the index and returns ranked matches with import statements.
|
|
|
161
194
|
| `query` | string | yes | What the icon should depict, e.g. `"trash"` |
|
|
162
195
|
| `provider` | string | no | Provider id or package. Default: every provider in `.iconmcp.json` |
|
|
163
196
|
| `version` | string | no | Version or range. Default: resolved as described in [Versions](#versions) |
|
|
164
|
-
| `style` | string | no | Exact style filter
|
|
197
|
+
| `style` | string | no | Exact style filter, e.g. `"outline"`, `"solid"`, `"filled"` (tabler), `"regular"` (fluentui), `"two-tone"` (antdesign) or a phosphor weight such as `"bold"`. Lucide icons are all `outline`; base carbon icons have no style |
|
|
165
198
|
| `set` | string | no | Exact set filter, e.g. `"fa6"` or `"md"` for react-icons |
|
|
166
199
|
| `limit` | integer | no | Maximum results, 1 to 50, default 10 |
|
|
167
200
|
|
|
@@ -194,7 +227,7 @@ How search works:
|
|
|
194
227
|
- `provider`, `style` and `set` are exact, case-insensitive filters. They are applied before ranking.
|
|
195
228
|
- Ranking uses [Fuse.js](https://www.fusejs.io/) fuzzy matching over the icon name, import name, keywords and tags. Small typos are tolerated: `"detele"` finds `Delete`.
|
|
196
229
|
- `score` runs from `0` (perfect) to `1`, so lower is better. Results from several providers are merged and sorted by score.
|
|
197
|
-
-
|
|
230
|
+
- Multi-word queries are tokenized: each word is matched on its own, only icons that match every word are kept, and they are ranked by their average score. So `"trash can"` finds `trash-can` icons. Short keyword queries (`"trash"`, `"settings"`, `"beer"`) still cast the widest net.
|
|
198
231
|
- If one provider fails, for example because its version can't be resolved or the download fails, its results are skipped and a `warnings` array explains why. The other providers still return results.
|
|
199
232
|
|
|
200
233
|
### `list_providers`
|
|
@@ -210,7 +243,13 @@ Takes no arguments. Returns the providers configured in `.iconmcp.json` with the
|
|
|
210
243
|
"registry": [
|
|
211
244
|
{ "id": "react-icons", "package": "react-icons", "description": "Aggregated icon sets (Font Awesome, Material, Feather, and more) as React components" },
|
|
212
245
|
{ "id": "lucide", "package": "lucide-react", "description": "Lucide icons as React components" },
|
|
213
|
-
{ "id": "heroicons", "package": "@heroicons/react", "description": "Heroicons by the Tailwind CSS team as React components" }
|
|
246
|
+
{ "id": "heroicons", "package": "@heroicons/react", "description": "Heroicons by the Tailwind CSS team as React components" },
|
|
247
|
+
{ "id": "phosphor", "package": "@phosphor-icons/react", "description": "Phosphor icons in six weights (thin, light, regular, bold, fill, duotone) as React components" },
|
|
248
|
+
{ "id": "tabler", "package": "@tabler/icons-react", "description": "Tabler icons (outline and filled) as React components" },
|
|
249
|
+
{ "id": "iconoir", "package": "iconoir-react", "description": "Iconoir icons (regular and solid) as React components" },
|
|
250
|
+
{ "id": "fluentui", "package": "@fluentui/react-icons", "description": "Microsoft Fluent UI System icons (regular, filled and color) as React components" },
|
|
251
|
+
{ "id": "carbon", "package": "@carbon/icons-react", "description": "IBM Carbon Design System icons as React components" },
|
|
252
|
+
{ "id": "antdesign", "package": "@ant-design/icons", "description": "Ant Design icons (outlined, filled and two-tone) as React components" }
|
|
214
253
|
]
|
|
215
254
|
}
|
|
216
255
|
```
|
|
@@ -300,6 +339,39 @@ npm run typecheck # tsc --noEmit
|
|
|
300
339
|
|
|
301
340
|
CI runs lint, typecheck and tests on Node 20 and 22 for every push and pull request.
|
|
302
341
|
|
|
342
|
+
### Tests
|
|
343
|
+
|
|
344
|
+
| Command | What it checks | Network |
|
|
345
|
+
| --- | --- | --- |
|
|
346
|
+
| `npm test` | Adapter parsing and every tool (`search_icons`, `get_icon`, `list_providers`) for all 9 providers, using the small fixtures in `tests/fixtures/` | No |
|
|
347
|
+
| `npm run smoke` | Every provider against the real npm packages: several pinned releases plus the current latest, checking the icon count and a few well-known icons | Yes |
|
|
348
|
+
|
|
349
|
+
The fixtures only change when someone edits them, so they can't catch a provider that changes its package format upstream. `npm run smoke` does. Run `npm run smoke -- lucide tabler` to check only some providers. CI runs it on pull requests that change `src/providers/`, `src/indexer/` or `src/cache/`, and every Monday against the latest releases.
|
|
350
|
+
|
|
351
|
+
### Testing and debugging locally
|
|
352
|
+
|
|
353
|
+
These scripts build the server and run it against `playground/`, a sample project that lists all 9 providers at their latest versions. They use a separate cache in `.cache/dev/`, so your real `~/.trueicon` cache is untouched.
|
|
354
|
+
|
|
355
|
+
```sh
|
|
356
|
+
# Call one tool and print the result
|
|
357
|
+
npm run dev:call -- list_providers
|
|
358
|
+
npm run dev:call -- search_icons query="trash can" limit=5
|
|
359
|
+
npm run dev:call -- search_icons query=trash provider=lucide version=1.47.0
|
|
360
|
+
npm run dev:call -- get_icon name=Trash2 provider=lucide
|
|
361
|
+
|
|
362
|
+
# Open the MCP Inspector web UI on the local build
|
|
363
|
+
npm run dev:inspect
|
|
364
|
+
|
|
365
|
+
# Same, with the Node debugger on port 9229
|
|
366
|
+
npm run dev:debug
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
- **Arguments** are `key=value` pairs. Numbers and booleans are parsed, so `limit=5` is sent as a number.
|
|
370
|
+
- **Another project:** set `TRUEICON_PROJECT_DIR` to test against its `package.json` and `.iconmcp.json`, e.g. `TRUEICON_PROJECT_DIR=~/code/my-app npm run dev:inspect`.
|
|
371
|
+
- **Rebuild indexes:** add `--fresh` to delete the dev cache first, e.g. `npm run dev:call -- --fresh search_icons query=trash`. Use it after changing an adapter.
|
|
372
|
+
- **Breakpoints:** run `npm run dev:debug`, then in VS Code use **Debug: Attach to Node Process**, or open `chrome://inspect` in Chrome. Source maps are on, so breakpoints work in the `.ts` files under `src/`. Set them, then call a tool from the Inspector.
|
|
373
|
+
- **Logging:** stdout carries the MCP protocol, so log with `console.error`. It shows in the terminal for `dev:call` and in the Inspector's server log for `dev:inspect`.
|
|
374
|
+
|
|
303
375
|
### Extending `synonyms.json`
|
|
304
376
|
|
|
305
377
|
`src/synonyms/synonyms.json` maps a term to extra search terms:
|
|
@@ -321,13 +393,15 @@ CI runs lint, typecheck and tests on Node 20 and 22 for every push and pull requ
|
|
|
321
393
|
|
|
322
394
|
1. **Register it** in `src/providers/registry.ts` with a stable `id`, the npm `package` and a short `description`.
|
|
323
395
|
2. **Write an adapter** in `src/providers/adapters/<provider>.ts` that exports `parseIcons(packageDir: string): RawIcon[]` (see `src/providers/adapter.ts`). It gets the extracted package directory and returns one `RawIcon` per icon:
|
|
324
|
-
- `name`: kebab-case and **unique within the package**, because it becomes part of the record id. Use `toKebabCase` from `adapter.ts`. If the package has variants with clashing component names, add the variant to the name, as the heroicons
|
|
396
|
+
- `name`: kebab-case and **unique within the package**, because it becomes part of the record id. Use `toKebabCase` from `adapter.ts`. If the package has variants with clashing component names, add the variant to the name, as the heroicons, react-icons, phosphor and iconoir adapters do.
|
|
325
397
|
- `importName` and `importPath`: the exact export and module specifier a user would import.
|
|
326
|
-
- `svg`: the inner SVG markup. `LiteralCursor` (`src/providers/jsLiteral.ts`) parses JS object and array literals without executing code. `toSvgAttrs` and `renderSvg` (`src/providers/svg.ts`) turn React props into SVG markup.
|
|
398
|
+
- `svg`: the inner SVG markup. `LiteralCursor` (`src/providers/jsLiteral.ts`) parses JS object and array literals without executing code. `toSvgAttrs` and `renderSvg` (`src/providers/svg.ts`) turn React props into SVG markup, and `parseCreateElement` reads compiled `createElement(...)` trees.
|
|
327
399
|
- Optional `style`, `set`, `categories` and `tags`.
|
|
328
400
|
- Put a comment at the top of the adapter describing the package's file layout, as the existing adapters do.
|
|
329
401
|
3. **Wire it up** in `src/providers/adapters/index.ts` by adding it to `ADAPTERS` under the provider id.
|
|
330
402
|
4. **Test it.** Add a small pinned fixture under `tests/fixtures/<provider>/` that mirrors the package layout, with a few real icon files plus any files the adapter must skip. Then add `tests/adapters/<provider>.test.ts`, covering name mapping, import paths, SVG output and `buildIndex` record ids like the existing adapter tests. `tests/adapters/common.test.ts` fails if a registered provider has no adapter.
|
|
403
|
+
5. **Add it to the tool tests** by adding a case to `CASES` in `tests/providers-tools.test.ts`: the fixture, a search query, one icon with its exact import line, and a deprecated alias if the package has them. The test fails if a registered provider has no case.
|
|
404
|
+
6. **Add smoke targets** to `TARGETS` in `scripts/smoke.mjs`: a few well-known import names and a minimum icon count well below the real one. Then run `npm run smoke -- <provider>` to check it against the real published package.
|
|
331
405
|
|
|
332
406
|
## License
|
|
333
407
|
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { readdirSync, readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { toKebabCase } from "../adapter.js";
|
|
4
|
+
/*
|
|
5
|
+
* @ant-design/icons layout: lib/icons/<Name><Theme>.js, one CommonJS module per icon, with Theme
|
|
6
|
+
* one of Filled, Outlined or TwoTone (DeleteOutlined.js, DeleteTwoTone.js). The artwork itself
|
|
7
|
+
* lives in @ant-design/icons-svg as an abstract node tree, but every icon module carries a
|
|
8
|
+
* generated preview comment with the full SVG:
|
|
9
|
+
*
|
|
10
|
+
* /** *\/
|
|
11
|
+
*
|
|
12
|
+
* The preview is decoded and the root <svg> element stripped. It hardcodes the default preview
|
|
13
|
+
* colors (the twotone fills, for example) where the component uses currentColor and a
|
|
14
|
+
* configurable twotone color. lib/icons/index.js is a barrel and is skipped. Ant Design ships
|
|
15
|
+
* no categories.
|
|
16
|
+
*/
|
|
17
|
+
const ICONS_DIR = join("lib", "icons");
|
|
18
|
+
const ICON_FILE = /^\w+(Filled|Outlined|TwoTone)\.js$/;
|
|
19
|
+
const PREVIEW = /\/\*\*!\[[^\]]*\]\(data:image\/svg\+xml;base64,([A-Za-z0-9+/=]+)\)\s*\*\//;
|
|
20
|
+
const SVG_ROOT = /^\s*<svg\b[^>]*>([\s\S]*)<\/svg>\s*$/;
|
|
21
|
+
// Returns the inner markup of the base64 SVG preview comment in an icon module.
|
|
22
|
+
export function previewSvg(src) {
|
|
23
|
+
const preview = PREVIEW.exec(src);
|
|
24
|
+
if (!preview)
|
|
25
|
+
throw new Error("SVG preview comment not found");
|
|
26
|
+
const svg = Buffer.from(preview[1], "base64").toString("utf8");
|
|
27
|
+
const root = SVG_ROOT.exec(svg);
|
|
28
|
+
if (!root)
|
|
29
|
+
throw new Error("SVG preview has no root <svg> element");
|
|
30
|
+
return root[1].trim();
|
|
31
|
+
}
|
|
32
|
+
export function parseIcons(packageDir) {
|
|
33
|
+
const dir = join(packageDir, ICONS_DIR);
|
|
34
|
+
const icons = [];
|
|
35
|
+
for (const file of readdirSync(dir).sort()) {
|
|
36
|
+
const theme = ICON_FILE.exec(file)?.[1];
|
|
37
|
+
if (!theme)
|
|
38
|
+
continue;
|
|
39
|
+
const importName = file.slice(0, -".js".length);
|
|
40
|
+
let svg;
|
|
41
|
+
try {
|
|
42
|
+
svg = previewSvg(readFileSync(join(dir, file), "utf8"));
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
throw new Error(`${file}: ${err.message}`, { cause: err });
|
|
46
|
+
}
|
|
47
|
+
icons.push({
|
|
48
|
+
name: toKebabCase(importName),
|
|
49
|
+
importName,
|
|
50
|
+
importPath: "@ant-design/icons",
|
|
51
|
+
style: toKebabCase(theme),
|
|
52
|
+
set: "antdesign",
|
|
53
|
+
categories: [],
|
|
54
|
+
tags: [],
|
|
55
|
+
svg,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
return icons;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=antdesign.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"antdesign.js","sourceRoot":"","sources":["../../../src/providers/adapters/antdesign.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAgB,MAAM,eAAe,CAAC;AAE1D;;;;;;;;;;;;GAYG;AAEH,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;AACvC,MAAM,SAAS,GAAG,oCAAoC,CAAC;AACvD,MAAM,OAAO,GAAG,2EAA2E,CAAC;AAC5F,MAAM,QAAQ,GAAG,sCAAsC,CAAC;AAExD,gFAAgF;AAChF,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IAC/D,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAE,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAChE,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChC,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IACpE,OAAO,IAAI,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,UAAkB;IAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;IACxC,MAAM,KAAK,GAAc,EAAE,CAAC;IAC5B,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QAC3C,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACxC,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAChD,IAAI,GAAW,CAAC;QAChB,IAAI,CAAC;YACH,GAAG,GAAG,UAAU,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QAC1D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,KAAM,GAAa,CAAC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;QACxE,CAAC;QACD,KAAK,CAAC,IAAI,CAAC;YACT,IAAI,EAAE,WAAW,CAAC,UAAU,CAAC;YAC7B,UAAU;YACV,UAAU,EAAE,mBAAmB;YAC/B,KAAK,EAAE,WAAW,CAAC,KAAK,CAAC;YACzB,GAAG,EAAE,WAAW;YAChB,UAAU,EAAE,EAAE;YACd,IAAI,EAAE,EAAE;YACR,GAAG;SACJ,CAAC,CAAC;IACL,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type RawIcon } from "../adapter.js";
|
|
2
|
+
import { LiteralCursor } from "../jsLiteral.js";
|
|
3
|
+
import { type SvgNode } from "../svg.js";
|
|
4
|
+
export declare function parseJsxElement(cursor: LiteralCursor): SvgNode;
|
|
5
|
+
export declare function parseJsxElements(src: string): SvgNode[];
|
|
6
|
+
export declare function parseBucket(src: string): {
|
|
7
|
+
importName: string;
|
|
8
|
+
nodes: SvgNode[];
|
|
9
|
+
}[];
|
|
10
|
+
export declare function parseIcons(packageDir: string): RawIcon[];
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { readdirSync, readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { toKebabCase } from "../adapter.js";
|
|
4
|
+
import { LiteralCursor } from "../jsLiteral.js";
|
|
5
|
+
import { renderSvg, toSvgAttrs } from "../svg.js";
|
|
6
|
+
/*
|
|
7
|
+
* @carbon/icons-react layout: the package barrel (es/index.js) re-exports every icon from
|
|
8
|
+
* es/generated/bucket-<n>.js, each holding ~125 icons:
|
|
9
|
+
*
|
|
10
|
+
* const Accessibility = /*#__PURE__*\/ React.forwardRef(function Accessibility({ children, size = 16, ...rest }, ref) {
|
|
11
|
+
* return React.createElement(Icon, { width: size, ..., ...rest },
|
|
12
|
+
* /* @__PURE__ *\/ jsx("path", { d: "..." }), /* @__PURE__ *\/ jsx("path", { d: "..." }), children);
|
|
13
|
+
* });
|
|
14
|
+
* ...
|
|
15
|
+
* export { Accessibility, ..., Object$1 as Object, _4K };
|
|
16
|
+
*
|
|
17
|
+
* The buckets are read instead of the per-icon es/<Name>.js modules because they carry the
|
|
18
|
+
* barrel export names: es/Q/H.js and es/watson-health/*.js export local names ("H") that the
|
|
19
|
+
* barrel publishes as "QH" and "WatsonHealth...".
|
|
20
|
+
*
|
|
21
|
+
* A few icons nest elements: jsx("switch", { children: jsxs("g", { children: [jsx(...), ...] }) }).
|
|
22
|
+
* Variants are separate exports suffixed Filled, Alt or Color; they get that suffix as their
|
|
23
|
+
* style, while base icons have no style. Carbon ships no categories.
|
|
24
|
+
*/
|
|
25
|
+
const BUCKETS_DIR = join("es", "generated");
|
|
26
|
+
const ICON_DEF = /const ([\w$]+) = \/\*#__PURE__\*\/ React\.forwardRef\(/g;
|
|
27
|
+
const EXPORTS = /export\s*\{([^}]*)\}/;
|
|
28
|
+
const JSX_CALL = /(?<![\w$])(jsx|jsxs)\s*\(/g;
|
|
29
|
+
const STYLE_SUFFIX = /(Filled|Alt|Color)$/;
|
|
30
|
+
// Parses a compiled `jsx("tag", { ...attrs, children })` call, recursing into `children`.
|
|
31
|
+
export function parseJsxElement(cursor) {
|
|
32
|
+
const fn = cursor.identifier();
|
|
33
|
+
if (fn !== "jsx" && fn !== "jsxs")
|
|
34
|
+
cursor.fail(`expected jsx call, got ${fn}`);
|
|
35
|
+
cursor.expect("(");
|
|
36
|
+
const tag = cursor.string();
|
|
37
|
+
cursor.expect(",");
|
|
38
|
+
const attr = {};
|
|
39
|
+
const child = [];
|
|
40
|
+
cursor.expect("{");
|
|
41
|
+
while (!cursor.eat("}")) {
|
|
42
|
+
const ch = cursor.peek();
|
|
43
|
+
const key = ch === '"' || ch === "'" ? cursor.string() : cursor.identifier();
|
|
44
|
+
cursor.expect(":");
|
|
45
|
+
if (key === "children") {
|
|
46
|
+
if (cursor.eat("[")) {
|
|
47
|
+
while (!cursor.eat("]")) {
|
|
48
|
+
child.push(parseJsxElement(cursor));
|
|
49
|
+
if (!cursor.eat(",") && cursor.peek() !== "]")
|
|
50
|
+
cursor.fail('expected "," or "]"');
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
child.push(parseJsxElement(cursor));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
Object.assign(attr, toSvgAttrs({ [key]: cursor.value() }));
|
|
59
|
+
}
|
|
60
|
+
if (!cursor.eat(",") && cursor.peek() !== "}")
|
|
61
|
+
cursor.fail('expected "," or "}"');
|
|
62
|
+
}
|
|
63
|
+
cursor.expect(")");
|
|
64
|
+
return { tag, attr, child };
|
|
65
|
+
}
|
|
66
|
+
// Parses every top-level jsx call in `src`, skipping calls nested inside one already parsed.
|
|
67
|
+
export function parseJsxElements(src) {
|
|
68
|
+
const nodes = [];
|
|
69
|
+
let consumedEnd = 0;
|
|
70
|
+
for (const match of src.matchAll(JSX_CALL)) {
|
|
71
|
+
if (match.index < consumedEnd)
|
|
72
|
+
continue;
|
|
73
|
+
const cursor = new LiteralCursor(src, match.index);
|
|
74
|
+
nodes.push(parseJsxElement(cursor));
|
|
75
|
+
consumedEnd = cursor.pos;
|
|
76
|
+
}
|
|
77
|
+
return nodes;
|
|
78
|
+
}
|
|
79
|
+
// Maps local binding names to exported names from the bucket's `export { a, b$1 as b }` clause.
|
|
80
|
+
function exportNames(src) {
|
|
81
|
+
const clause = EXPORTS.exec(src);
|
|
82
|
+
if (!clause)
|
|
83
|
+
throw new Error("export clause not found");
|
|
84
|
+
const names = new Map();
|
|
85
|
+
for (const spec of clause[1].split(",").map((s) => s.trim()).filter(Boolean)) {
|
|
86
|
+
const [local, exported = local] = spec.split(/\s+as\s+/);
|
|
87
|
+
names.set(local, exported);
|
|
88
|
+
}
|
|
89
|
+
return names;
|
|
90
|
+
}
|
|
91
|
+
export function parseBucket(src) {
|
|
92
|
+
const exported = exportNames(src);
|
|
93
|
+
const defs = [...src.matchAll(ICON_DEF)];
|
|
94
|
+
return defs.map((def, i) => {
|
|
95
|
+
const importName = exported.get(def[1]);
|
|
96
|
+
if (!importName)
|
|
97
|
+
throw new Error(`icon ${def[1]} is not exported`);
|
|
98
|
+
const body = src.slice(def.index, defs[i + 1]?.index ?? src.length);
|
|
99
|
+
return { importName, nodes: parseJsxElements(body) };
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
// "Airport_01" -> "airport-01", "_4K" -> "4-k" (a leading underscore only makes a valid identifier).
|
|
103
|
+
function iconName(identifier) {
|
|
104
|
+
return toKebabCase(identifier.replace(/^_/, "")).replace(/_/g, "-");
|
|
105
|
+
}
|
|
106
|
+
export function parseIcons(packageDir) {
|
|
107
|
+
const dir = join(packageDir, BUCKETS_DIR);
|
|
108
|
+
const icons = [];
|
|
109
|
+
const files = readdirSync(dir).filter((f) => /^bucket-\d+\.js$/.test(f));
|
|
110
|
+
for (const file of files.sort()) {
|
|
111
|
+
for (const { importName, nodes } of parseBucket(readFileSync(join(dir, file), "utf8"))) {
|
|
112
|
+
const suffix = STYLE_SUFFIX.exec(importName)?.[1];
|
|
113
|
+
const style = suffix && suffix !== importName ? toKebabCase(suffix) : undefined;
|
|
114
|
+
const base = style ? importName.slice(0, -suffix.length) : importName;
|
|
115
|
+
icons.push({
|
|
116
|
+
name: style ? `${iconName(base)}-${style}` : iconName(base),
|
|
117
|
+
importName,
|
|
118
|
+
importPath: "@carbon/icons-react",
|
|
119
|
+
style,
|
|
120
|
+
set: "carbon",
|
|
121
|
+
categories: [],
|
|
122
|
+
tags: [],
|
|
123
|
+
svg: renderSvg(nodes),
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return icons;
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=carbon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"carbon.js","sourceRoot":"","sources":["../../../src/providers/adapters/carbon.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { readdirSync, readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { toKebabCase } from "../adapter.js";
|
|
4
|
+
import { LiteralCursor } from "../jsLiteral.js";
|
|
5
|
+
import { renderSvg, toSvgAttrs } from "../svg.js";
|
|
6
|
+
/*
|
|
7
|
+
* @fluentui/react-icons layout: lib/icons/chunk-<n>.js, many icons per chunk, one per line:
|
|
8
|
+
*
|
|
9
|
+
* export const BackpackFilled = ( /*#__PURE__*\/createFluentIcon('BackpackFilled', "1em", ["M8 8.7c0-...", ...]));
|
|
10
|
+
* export const CalendarColor = ( /*#__PURE__*\/createFluentIcon('CalendarColor', "1em", [["path", { "d": "..." }], ["g", {...}, [...]]], { color: true }));
|
|
11
|
+
*
|
|
12
|
+
* Mono-color icons pass an array of path `d` strings; color icons pass [tag, attrs, ...children]
|
|
13
|
+
* node tuples (which include their gradient/filter defs). An optional options object may follow.
|
|
14
|
+
* Every export name ends in its style: Filled, Regular or Color.
|
|
15
|
+
*
|
|
16
|
+
* lib/sizedIcons/ holds size-specific variants (Backpack12Filled, Backpack16Filled, ...) of the
|
|
17
|
+
* same artwork, about 20k near-duplicates; it is skipped and only the scalable 1em icons are
|
|
18
|
+
* indexed. Fluent ships no categories.
|
|
19
|
+
*/
|
|
20
|
+
const ICONS_DIR = join("lib", "icons");
|
|
21
|
+
const ICON_EXPORT = /export const (\w+) = \(\s*\/\*#__PURE__\*\/\s*createFluentIcon\(/g;
|
|
22
|
+
const STYLE_SUFFIX = /(Filled|Regular|Color)$/;
|
|
23
|
+
function toNode(value, cursor) {
|
|
24
|
+
if (typeof value === "string")
|
|
25
|
+
return { tag: "path", attr: { d: value }, child: [] };
|
|
26
|
+
if (!Array.isArray(value) || typeof value[0] !== "string")
|
|
27
|
+
cursor.fail("expected path data or [tag, attrs]");
|
|
28
|
+
const [tag, attrs, ...children] = value;
|
|
29
|
+
return { tag, attr: toSvgAttrs(attrs), child: children.map((child) => toNode(child, cursor)) };
|
|
30
|
+
}
|
|
31
|
+
export function parseChunk(src) {
|
|
32
|
+
const icons = [];
|
|
33
|
+
for (const match of src.matchAll(ICON_EXPORT)) {
|
|
34
|
+
const importName = match[1];
|
|
35
|
+
const cursor = new LiteralCursor(src, match.index + match[0].length);
|
|
36
|
+
if (cursor.string() !== importName)
|
|
37
|
+
cursor.fail(`display name does not match export ${importName}`);
|
|
38
|
+
cursor.expect(",");
|
|
39
|
+
cursor.string();
|
|
40
|
+
cursor.expect(",");
|
|
41
|
+
const nodes = cursor.array().map((value) => toNode(value, cursor));
|
|
42
|
+
if (cursor.eat(","))
|
|
43
|
+
cursor.object();
|
|
44
|
+
cursor.expect(")");
|
|
45
|
+
icons.push({ importName, nodes });
|
|
46
|
+
}
|
|
47
|
+
return icons;
|
|
48
|
+
}
|
|
49
|
+
export function parseIcons(packageDir) {
|
|
50
|
+
const dir = join(packageDir, ICONS_DIR);
|
|
51
|
+
const icons = [];
|
|
52
|
+
for (const file of readdirSync(dir).filter((f) => /^chunk-\d+\.js$/.test(f)).sort()) {
|
|
53
|
+
for (const { importName, nodes } of parseChunk(readFileSync(join(dir, file), "utf8"))) {
|
|
54
|
+
const style = STYLE_SUFFIX.exec(importName)?.[1];
|
|
55
|
+
if (!style)
|
|
56
|
+
throw new Error(`${file}: ${importName} has no Filled/Regular/Color suffix`);
|
|
57
|
+
icons.push({
|
|
58
|
+
name: toKebabCase(importName),
|
|
59
|
+
importName,
|
|
60
|
+
importPath: "@fluentui/react-icons",
|
|
61
|
+
style: style.toLowerCase(),
|
|
62
|
+
set: "fluentui",
|
|
63
|
+
categories: [],
|
|
64
|
+
tags: [],
|
|
65
|
+
svg: renderSvg(nodes),
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return icons;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=fluentui.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fluentui.js","sourceRoot":"","sources":["../../../src/providers/adapters/fluentui.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { toKebabCase } from "../adapter.js";
|
|
4
|
+
import { LiteralCursor } from "../jsLiteral.js";
|
|
5
|
+
import { parseCreateElement, renderSvg } from "../svg.js";
|
|
6
|
+
/*
|
|
7
|
+
* iconoir-react layout: dist/esm/regular/<Name>.mjs and dist/esm/solid/<Name>.mjs, one minified
|
|
8
|
+
* component per file whose render returns
|
|
9
|
+
*
|
|
10
|
+
* n.createElement("svg", t({width: "1.5em", viewBox: "0 0 24 24", ...}, p),
|
|
11
|
+
* n.createElement("path", {d: "...", stroke: "currentColor", strokeLinecap: "round"}), ...)
|
|
12
|
+
*
|
|
13
|
+
* where `t(..., p)` merges the default attributes with context and props. That root call holds
|
|
14
|
+
* non-literals (`ref: o`), so it is skipped; the children after it are the icon's inner SVG.
|
|
15
|
+
* The package root re-exports regular icons as "<Name>" and solid ones as "<Name>Solid", so
|
|
16
|
+
* solid icons are named "<name>-solid" to stay unique. The index.mjs barrels are skipped.
|
|
17
|
+
* Iconoir ships no categories or tags.
|
|
18
|
+
*/
|
|
19
|
+
const VARIANTS = [
|
|
20
|
+
{ dir: "regular", suffix: "" },
|
|
21
|
+
{ dir: "solid", suffix: "Solid" },
|
|
22
|
+
];
|
|
23
|
+
const SVG_CALL = /\w+\.createElement\(\s*"svg"\s*,\s*\w+\(\s*\{[^}]*\}\s*,\s*\w+\s*\)/;
|
|
24
|
+
export function parseIconFile(src) {
|
|
25
|
+
const call = SVG_CALL.exec(src);
|
|
26
|
+
if (!call)
|
|
27
|
+
throw new Error("svg createElement call not found");
|
|
28
|
+
const cursor = new LiteralCursor(src, call.index + call[0].length);
|
|
29
|
+
const nodes = [];
|
|
30
|
+
while (cursor.eat(","))
|
|
31
|
+
nodes.push(parseCreateElement(cursor));
|
|
32
|
+
cursor.expect(")");
|
|
33
|
+
return nodes;
|
|
34
|
+
}
|
|
35
|
+
export function parseIcons(packageDir) {
|
|
36
|
+
const icons = [];
|
|
37
|
+
for (const { dir, suffix } of VARIANTS) {
|
|
38
|
+
const variantDir = join(packageDir, "dist", "esm", dir);
|
|
39
|
+
if (!existsSync(variantDir))
|
|
40
|
+
continue;
|
|
41
|
+
for (const file of readdirSync(variantDir).filter((f) => /^[A-Z]\w*\.mjs$/.test(f)).sort()) {
|
|
42
|
+
const component = file.slice(0, -".mjs".length);
|
|
43
|
+
const importName = component + suffix;
|
|
44
|
+
icons.push({
|
|
45
|
+
name: toKebabCase(importName),
|
|
46
|
+
importName,
|
|
47
|
+
importPath: "iconoir-react",
|
|
48
|
+
style: dir,
|
|
49
|
+
set: "iconoir",
|
|
50
|
+
categories: [],
|
|
51
|
+
tags: [],
|
|
52
|
+
svg: renderSvg(parseIconFile(readFileSync(join(variantDir, file), "utf8"))),
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return icons;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=iconoir.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iconoir.js","sourceRoot":"","sources":["../../../src/providers/adapters/iconoir.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAgB,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAgB,MAAM,WAAW,CAAC;AAExE;;;;;;;;;;;;GAYG;AAEH,MAAM,QAAQ,GAAG;IACf,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE;IAC9B,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE;CAClC,CAAC;AACF,MAAM,QAAQ,GAAG,qEAAqE,CAAC;AAEvF,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChC,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IAC/D,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACnE,MAAM,KAAK,GAAc,EAAE,CAAC;IAC5B,OAAO,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC;IAC/D,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACnB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,UAAkB;IAC3C,MAAM,KAAK,GAAc,EAAE,CAAC;IAC5B,KAAK,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;QACvC,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;QACxD,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;YAAE,SAAS;QACtC,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YAC3F,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAChD,MAAM,UAAU,GAAG,SAAS,GAAG,MAAM,CAAC;YACtC,KAAK,CAAC,IAAI,CAAC;gBACT,IAAI,EAAE,WAAW,CAAC,UAAU,CAAC;gBAC7B,UAAU;gBACV,UAAU,EAAE,eAAe;gBAC3B,KAAK,EAAE,GAAG;gBACV,GAAG,EAAE,SAAS;gBACd,UAAU,EAAE,EAAE;gBACd,IAAI,EAAE,EAAE;gBACR,GAAG,EAAE,SAAS,CAAC,aAAa,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;aAC5E,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -1,10 +1,22 @@
|
|
|
1
|
+
import { parseIcons as parseAntDesign } from "./antdesign.js";
|
|
2
|
+
import { parseIcons as parseCarbon } from "./carbon.js";
|
|
3
|
+
import { parseIcons as parseFluentUi } from "./fluentui.js";
|
|
1
4
|
import { parseIcons as parseHeroicons } from "./heroicons.js";
|
|
5
|
+
import { parseIcons as parseIconoir } from "./iconoir.js";
|
|
2
6
|
import { parseIcons as parseLucide } from "./lucide.js";
|
|
7
|
+
import { parseIcons as parsePhosphor } from "./phosphor.js";
|
|
3
8
|
import { parseIcons as parseReactIcons } from "./react-icons.js";
|
|
9
|
+
import { parseIcons as parseTabler } from "./tabler.js";
|
|
4
10
|
// Adapter per provider id (see ../registry.ts).
|
|
5
11
|
export const ADAPTERS = {
|
|
6
12
|
"react-icons": parseReactIcons,
|
|
7
13
|
lucide: parseLucide,
|
|
8
14
|
heroicons: parseHeroicons,
|
|
15
|
+
phosphor: parsePhosphor,
|
|
16
|
+
tabler: parseTabler,
|
|
17
|
+
iconoir: parseIconoir,
|
|
18
|
+
fluentui: parseFluentUi,
|
|
19
|
+
carbon: parseCarbon,
|
|
20
|
+
antdesign: parseAntDesign,
|
|
9
21
|
};
|
|
10
22
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/providers/adapters/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,IAAI,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,EAAE,UAAU,IAAI,WAAW,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,UAAU,IAAI,eAAe,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/providers/adapters/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,IAAI,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,EAAE,UAAU,IAAI,WAAW,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,UAAU,IAAI,aAAa,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,UAAU,IAAI,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,EAAE,UAAU,IAAI,YAAY,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,UAAU,IAAI,WAAW,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,UAAU,IAAI,aAAa,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,UAAU,IAAI,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,UAAU,IAAI,WAAW,EAAE,MAAM,aAAa,CAAC;AAExD,gDAAgD;AAChD,MAAM,CAAC,MAAM,QAAQ,GAAyC;IAC5D,aAAa,EAAE,eAAe;IAC9B,MAAM,EAAE,WAAW;IACnB,SAAS,EAAE,cAAc;IACzB,QAAQ,EAAE,aAAa;IACvB,MAAM,EAAE,WAAW;IACnB,OAAO,EAAE,YAAY;IACrB,QAAQ,EAAE,aAAa;IACvB,MAAM,EAAE,WAAW;IACnB,SAAS,EAAE,cAAc;CAC1B,CAAC"}
|
|
@@ -3,55 +3,102 @@ import { join } from "node:path";
|
|
|
3
3
|
import { LiteralCursor } from "../jsLiteral.js";
|
|
4
4
|
import { renderSvg, toSvgAttrs } from "../svg.js";
|
|
5
5
|
/*
|
|
6
|
-
* lucide-react layout: dist/esm/icons/<kebab-name>.js, one ESM module per icon
|
|
6
|
+
* lucide-react layout: dist/esm/icons/<kebab-name>.js (.mjs from 1.x), one ESM module per icon.
|
|
7
|
+
* The module body has changed across releases; all three shapes are supported:
|
|
7
8
|
*
|
|
8
|
-
* const Trash2 = createLucideIcon("Trash2", [["path", { d: "...", key: "..." }], ...]);
|
|
9
|
+
* older 0.x: const Trash2 = createLucideIcon("Trash2", [["path", { d: "...", key: "..." }], ...]);
|
|
10
|
+
* later 0.x - 1.46: const __iconNode = [["path", { ... }], ...];
|
|
11
|
+
* const Trash2 = createLucideIcon("trash-2", __iconNode);
|
|
12
|
+
* 1.47+: const __iconData = { name: "trash-2", size: 24, node: [...], aliases: ["..."] };
|
|
13
|
+
* const Trash2 = createLucideIcon(__iconData);
|
|
9
14
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
15
|
+
* The import name always comes from the `const <Name> = createLucideIcon(` binding, because the
|
|
16
|
+
* string argument is the component name in older releases but the kebab name in later ones.
|
|
17
|
+
*
|
|
18
|
+
* Deprecated alias names ship as re-export modules (`export { default } from './target.js'`), and
|
|
19
|
+
* from 1.47 also in __iconData.aliases. They are not indexed separately but added to the target
|
|
20
|
+
* icon's tags so old names still match. lucide-react ships no categories or tags of its own.
|
|
13
21
|
*/
|
|
14
22
|
const ICONS_DIR = join("dist", "esm", "icons");
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
23
|
+
const MODULE_FILE = /^(?<name>[\w-]+)\.m?js$/;
|
|
24
|
+
const CREATE_CALL = /const\s+(?<importName>[\w$]+)\s*=\s*createLucideIcon\(\s*/;
|
|
25
|
+
const ICON_NODE = /const\s+__iconNode\s*=\s*/;
|
|
26
|
+
const ICON_DATA = /const\s+__iconData\s*=\s*/;
|
|
27
|
+
const ALIAS_EXPORT = /export\s*\{\s*default\s*\}\s*from\s*['"]\.\/([\w-]+)\.m?js['"]/;
|
|
28
|
+
function toNodes(cursor, nodes) {
|
|
29
|
+
if (!Array.isArray(nodes))
|
|
30
|
+
cursor.fail("expected an array of [tag, attrs]");
|
|
19
31
|
return nodes.map((node) => {
|
|
20
32
|
if (!Array.isArray(node) || typeof node[0] !== "string")
|
|
21
33
|
cursor.fail("expected [tag, attrs]");
|
|
22
34
|
return { tag: node[0], attr: toSvgAttrs(node[1]), child: [] };
|
|
23
35
|
});
|
|
24
36
|
}
|
|
37
|
+
/** Reads the value assigned by `const <binding> = ` in src. */
|
|
38
|
+
function readBinding(src, binding) {
|
|
39
|
+
const match = binding.exec(src);
|
|
40
|
+
if (!match)
|
|
41
|
+
return undefined;
|
|
42
|
+
const cursor = new LiteralCursor(src, match.index + match[0].length);
|
|
43
|
+
return { cursor, value: cursor.value() };
|
|
44
|
+
}
|
|
45
|
+
function parseModule(src) {
|
|
46
|
+
const call = CREATE_CALL.exec(src);
|
|
47
|
+
if (!call)
|
|
48
|
+
return undefined;
|
|
49
|
+
const importName = call.groups.importName;
|
|
50
|
+
const data = readBinding(src, ICON_DATA);
|
|
51
|
+
if (data) {
|
|
52
|
+
const { value } = data;
|
|
53
|
+
const cursor = data.cursor;
|
|
54
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
55
|
+
cursor.fail("expected __iconData object");
|
|
56
|
+
const aliases = Array.isArray(value.aliases) ? value.aliases.filter((a) => typeof a === "string") : [];
|
|
57
|
+
return { importName, nodes: toNodes(cursor, value.node ?? null), aliases };
|
|
58
|
+
}
|
|
59
|
+
const iconNode = readBinding(src, ICON_NODE);
|
|
60
|
+
if (iconNode)
|
|
61
|
+
return { importName, nodes: toNodes(iconNode.cursor, iconNode.value), aliases: [] };
|
|
62
|
+
// Older 0.x: createLucideIcon("<Name>", [...nodes]).
|
|
63
|
+
const cursor = new LiteralCursor(src, call.index + call[0].length);
|
|
64
|
+
cursor.string();
|
|
65
|
+
cursor.expect(",");
|
|
66
|
+
return { importName, nodes: toNodes(cursor, cursor.array()), aliases: [] };
|
|
67
|
+
}
|
|
25
68
|
export function parseIcons(packageDir) {
|
|
26
69
|
const dir = join(packageDir, ICONS_DIR);
|
|
27
70
|
const icons = new Map();
|
|
28
71
|
const aliases = [];
|
|
29
|
-
for (const file of readdirSync(dir).
|
|
30
|
-
const name =
|
|
72
|
+
for (const file of readdirSync(dir).sort()) {
|
|
73
|
+
const name = MODULE_FILE.exec(file)?.groups?.name;
|
|
74
|
+
if (!name)
|
|
75
|
+
continue;
|
|
31
76
|
const src = readFileSync(join(dir, file), "utf8");
|
|
32
|
-
const
|
|
33
|
-
if (!
|
|
77
|
+
const icon = parseModule(src);
|
|
78
|
+
if (!icon) {
|
|
34
79
|
const alias = ALIAS_EXPORT.exec(src);
|
|
35
80
|
if (alias)
|
|
36
81
|
aliases.push([name, alias[1]]);
|
|
37
82
|
continue;
|
|
38
83
|
}
|
|
39
|
-
const cursor = new LiteralCursor(src, call.index + call[0].length);
|
|
40
|
-
const importName = cursor.string();
|
|
41
|
-
cursor.expect(",");
|
|
42
84
|
icons.set(name, {
|
|
43
85
|
name,
|
|
44
|
-
importName,
|
|
86
|
+
importName: icon.importName,
|
|
45
87
|
importPath: "lucide-react",
|
|
46
88
|
style: "outline",
|
|
47
89
|
set: "lucide",
|
|
48
90
|
categories: [],
|
|
49
91
|
tags: [],
|
|
50
|
-
svg: renderSvg(
|
|
92
|
+
svg: renderSvg(icon.nodes),
|
|
51
93
|
});
|
|
94
|
+
for (const alias of icon.aliases)
|
|
95
|
+
aliases.push([alias, name]);
|
|
96
|
+
}
|
|
97
|
+
for (const [alias, target] of aliases) {
|
|
98
|
+
const tags = icons.get(target)?.tags;
|
|
99
|
+
if (tags && !tags.includes(alias))
|
|
100
|
+
tags.push(alias);
|
|
52
101
|
}
|
|
53
|
-
for (const [alias, target] of aliases)
|
|
54
|
-
icons.get(target)?.tags?.push(alias);
|
|
55
102
|
return [...icons.values()];
|
|
56
103
|
}
|
|
57
104
|
//# sourceMappingURL=lucide.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lucide.js","sourceRoot":"","sources":["../../../src/providers/adapters/lucide.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"lucide.js","sourceRoot":"","sources":["../../../src/providers/adapters/lucide.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { readdirSync, readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { toKebabCase } from "../adapter.js";
|
|
4
|
+
import { LiteralCursor } from "../jsLiteral.js";
|
|
5
|
+
import { parseCreateElement, renderSvg } from "../svg.js";
|
|
6
|
+
/*
|
|
7
|
+
* @phosphor-icons/react layout: one component module per icon in dist/csr/<Name>.es.js, which
|
|
8
|
+
* exports "<Name>Icon" (plus a deprecated "<Name>" and sometimes alias names such as
|
|
9
|
+
* "FolderNotchIcon" from Folder.es.js), and its SVG per weight in dist/defs/<Name>.es.js:
|
|
10
|
+
*
|
|
11
|
+
* const a = new Map([
|
|
12
|
+
* ["bold", e.createElement(e.Fragment, null, e.createElement("path", { d: "..." }), ...)],
|
|
13
|
+
* ["duotone", ...], ["fill", ...], ["light", ...], ["regular", ...], ["thin", ...]
|
|
14
|
+
* ]);
|
|
15
|
+
*
|
|
16
|
+
* All weights share one component and are picked with its `weight` prop, so each weight is
|
|
17
|
+
* indexed as its own record with `style` set to the weight. The default weight keeps the plain
|
|
18
|
+
* name ("acorn") and the others get a suffix ("acorn-bold"), so the default sorts first.
|
|
19
|
+
* Alias export names are added to the tags. Phosphor ships no categories.
|
|
20
|
+
*/
|
|
21
|
+
const CSR_DIR = join("dist", "csr");
|
|
22
|
+
const DEFS_DIR = join("dist", "defs");
|
|
23
|
+
const DEFAULT_WEIGHT = "regular";
|
|
24
|
+
const WEIGHT_MAP = /new Map\(\s*/;
|
|
25
|
+
const ICON_EXPORT = /\bas (\w+)Icon\b/g;
|
|
26
|
+
export function parseWeights(src) {
|
|
27
|
+
const map = WEIGHT_MAP.exec(src);
|
|
28
|
+
if (!map)
|
|
29
|
+
throw new Error("weights Map not found");
|
|
30
|
+
const cursor = new LiteralCursor(src, map.index + map[0].length);
|
|
31
|
+
const weights = [];
|
|
32
|
+
cursor.expect("[");
|
|
33
|
+
while (cursor.eat("[")) {
|
|
34
|
+
const weight = cursor.string();
|
|
35
|
+
cursor.expect(",");
|
|
36
|
+
// The Fragment wrapper: <ns>.createElement(<ns>.Fragment, null, ...children).
|
|
37
|
+
cursor.identifier();
|
|
38
|
+
cursor.expect(".createElement(");
|
|
39
|
+
cursor.identifier();
|
|
40
|
+
cursor.expect(".Fragment,");
|
|
41
|
+
cursor.expect("null");
|
|
42
|
+
const nodes = [];
|
|
43
|
+
while (cursor.eat(","))
|
|
44
|
+
nodes.push(parseCreateElement(cursor));
|
|
45
|
+
cursor.expect(")");
|
|
46
|
+
cursor.expect("]");
|
|
47
|
+
weights.push([weight, nodes]);
|
|
48
|
+
cursor.eat(",");
|
|
49
|
+
}
|
|
50
|
+
cursor.expect("]");
|
|
51
|
+
return weights;
|
|
52
|
+
}
|
|
53
|
+
export function parseIcons(packageDir) {
|
|
54
|
+
const icons = [];
|
|
55
|
+
const files = readdirSync(join(packageDir, CSR_DIR)).filter((f) => f.endsWith(".es.js"));
|
|
56
|
+
for (const file of files.sort()) {
|
|
57
|
+
const component = file.slice(0, -".es.js".length);
|
|
58
|
+
const importName = `${component}Icon`;
|
|
59
|
+
const src = readFileSync(join(packageDir, CSR_DIR, file), "utf8");
|
|
60
|
+
const aliases = [...src.matchAll(ICON_EXPORT)].map((m) => m[1]).filter((name) => name !== component);
|
|
61
|
+
const base = toKebabCase(component);
|
|
62
|
+
const weights = parseWeights(readFileSync(join(packageDir, DEFS_DIR, file), "utf8"));
|
|
63
|
+
for (const [weight, nodes] of weights) {
|
|
64
|
+
icons.push({
|
|
65
|
+
name: weight === DEFAULT_WEIGHT ? base : `${base}-${weight}`,
|
|
66
|
+
importName,
|
|
67
|
+
importPath: "@phosphor-icons/react",
|
|
68
|
+
style: weight,
|
|
69
|
+
set: "phosphor",
|
|
70
|
+
categories: [],
|
|
71
|
+
tags: aliases.map(toKebabCase),
|
|
72
|
+
svg: renderSvg(nodes),
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return icons;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=phosphor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phosphor.js","sourceRoot":"","sources":["../../../src/providers/adapters/phosphor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type RawIcon } from "../adapter.js";
|
|
2
|
+
import { type SvgNode } from "../svg.js";
|
|
3
|
+
export declare function parseIconFile(src: string): {
|
|
4
|
+
name: string;
|
|
5
|
+
style: string;
|
|
6
|
+
nodes: SvgNode[];
|
|
7
|
+
};
|
|
8
|
+
export declare function parseIcons(packageDir: string): RawIcon[];
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { toKebabCase } from "../adapter.js";
|
|
4
|
+
import { LiteralCursor } from "../jsLiteral.js";
|
|
5
|
+
import { renderSvg, toSvgAttrs } from "../svg.js";
|
|
6
|
+
/*
|
|
7
|
+
* @tabler/icons-react layout: dist/esm/icons/Icon<Name>.mjs, one ESM module per icon:
|
|
8
|
+
*
|
|
9
|
+
* const __iconNode = [["path", { "d": "M4 7l16 0", "key": "svg-0" }], ...];
|
|
10
|
+
* const IconTrash = createReactComponent("outline", "trash", "Trash", __iconNode);
|
|
11
|
+
* export { __iconNode, IconTrash as default };
|
|
12
|
+
*
|
|
13
|
+
* createReactComponent's arguments give the style ("outline" or "filled") and the kebab icon
|
|
14
|
+
* name, which already carries the variant ("trash" vs "trash-filled"), so names are unique.
|
|
15
|
+
* The package barrel (dist/esm/tabler-icons-react.mjs) re-exports some icons under old names
|
|
16
|
+
* (`export { default as Icon123, default as IconNumber123 } from './icons/IconNumber123.mjs'`);
|
|
17
|
+
* those are added to the target icon's tags. dist/esm/icons/index.mjs is a barrel and is
|
|
18
|
+
* skipped. Tabler ships no categories.
|
|
19
|
+
*/
|
|
20
|
+
const ICONS_DIR = join("dist", "esm", "icons");
|
|
21
|
+
const BARREL = join("dist", "esm", "tabler-icons-react.mjs");
|
|
22
|
+
const ICON_NODE = /const __iconNode = /;
|
|
23
|
+
const CREATE_CALL = /createReactComponent\(\s*/;
|
|
24
|
+
const BARREL_EXPORT = /export\s*\{([^}]*)\}\s*from\s*['"]\.\/icons\/(\w+)\.mjs['"]/g;
|
|
25
|
+
function parseNodes(cursor) {
|
|
26
|
+
return cursor.array().map((node) => {
|
|
27
|
+
if (!Array.isArray(node) || typeof node[0] !== "string")
|
|
28
|
+
cursor.fail("expected [tag, attrs]");
|
|
29
|
+
return { tag: node[0], attr: toSvgAttrs(node[1]), child: [] };
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
// Maps icon module name (IconNumber123) to its alias names in the barrel (["123"]).
|
|
33
|
+
function barrelAliases(packageDir) {
|
|
34
|
+
const aliases = new Map();
|
|
35
|
+
const file = join(packageDir, BARREL);
|
|
36
|
+
if (!existsSync(file))
|
|
37
|
+
return aliases;
|
|
38
|
+
for (const match of readFileSync(file, "utf8").matchAll(BARREL_EXPORT)) {
|
|
39
|
+
const target = match[2];
|
|
40
|
+
const names = [...match[1].matchAll(/default as (\w+)/g)].map((m) => m[1]).filter((n) => n !== target);
|
|
41
|
+
if (names.length > 0)
|
|
42
|
+
aliases.set(target, names.map((n) => toKebabCase(n.replace(/^Icon/, ""))));
|
|
43
|
+
}
|
|
44
|
+
return aliases;
|
|
45
|
+
}
|
|
46
|
+
export function parseIconFile(src) {
|
|
47
|
+
const iconNode = ICON_NODE.exec(src);
|
|
48
|
+
const call = CREATE_CALL.exec(src);
|
|
49
|
+
if (!iconNode || !call)
|
|
50
|
+
throw new Error("createReactComponent call not found");
|
|
51
|
+
const nodes = parseNodes(new LiteralCursor(src, iconNode.index + iconNode[0].length));
|
|
52
|
+
const cursor = new LiteralCursor(src, call.index + call[0].length);
|
|
53
|
+
const style = cursor.string();
|
|
54
|
+
cursor.expect(",");
|
|
55
|
+
return { name: cursor.string(), style, nodes };
|
|
56
|
+
}
|
|
57
|
+
export function parseIcons(packageDir) {
|
|
58
|
+
const dir = join(packageDir, ICONS_DIR);
|
|
59
|
+
const aliases = barrelAliases(packageDir);
|
|
60
|
+
const icons = [];
|
|
61
|
+
for (const file of readdirSync(dir).filter((f) => /^Icon\w+\.mjs$/.test(f)).sort()) {
|
|
62
|
+
const importName = file.slice(0, -".mjs".length);
|
|
63
|
+
const { name, style, nodes } = parseIconFile(readFileSync(join(dir, file), "utf8"));
|
|
64
|
+
icons.push({
|
|
65
|
+
name,
|
|
66
|
+
importName,
|
|
67
|
+
importPath: "@tabler/icons-react",
|
|
68
|
+
style,
|
|
69
|
+
set: "tabler",
|
|
70
|
+
categories: [],
|
|
71
|
+
tags: aliases.get(importName) ?? [],
|
|
72
|
+
svg: renderSvg(nodes),
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
return icons;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=tabler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tabler.js","sourceRoot":"","sources":["../../../src/providers/adapters/tabler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAgB,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,UAAU,EAAgB,MAAM,WAAW,CAAC;AAEhE;;;;;;;;;;;;;GAaG;AAEH,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;AAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,wBAAwB,CAAC,CAAC;AAC7D,MAAM,SAAS,GAAG,qBAAqB,CAAC;AACxC,MAAM,WAAW,GAAG,2BAA2B,CAAC;AAChD,MAAM,aAAa,GAAG,8DAA8D,CAAC;AAErF,SAAS,UAAU,CAAC,MAAqB;IACvC,OAAO,MAAM,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACjC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ;YAAE,MAAM,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QAC9F,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IAChE,CAAC,CAAC,CAAC;AACL,CAAC;AAED,oFAAoF;AACpF,SAAS,aAAa,CAAC,UAAkB;IACvC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IACtC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,OAAO,CAAC;IACtC,KAAK,MAAM,KAAK,IAAI,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;QACvE,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;QACzB,MAAM,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC;QACzG,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACnG,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACrC,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IAC/E,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,aAAa,CAAC,GAAG,EAAE,QAAQ,CAAC,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IACtF,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACnE,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;IAC9B,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACnB,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,UAAkB;IAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;IACxC,MAAM,OAAO,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC;IAC1C,MAAM,KAAK,GAAc,EAAE,CAAC;IAC5B,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QACnF,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACjD,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,aAAa,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QACpF,KAAK,CAAC,IAAI,CAAC;YACT,IAAI;YACJ,UAAU;YACV,UAAU,EAAE,qBAAqB;YACjC,KAAK;YACL,GAAG,EAAE,QAAQ;YACb,UAAU,EAAE,EAAE;YACd,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE;YACnC,GAAG,EAAE,SAAS,CAAC,KAAK,CAAC;SACtB,CAAC,CAAC;IACL,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//
|
|
1
|
+
// Supported icon providers.
|
|
2
2
|
export const PROVIDERS = [
|
|
3
3
|
{
|
|
4
4
|
id: "react-icons",
|
|
@@ -15,6 +15,36 @@ export const PROVIDERS = [
|
|
|
15
15
|
package: "@heroicons/react",
|
|
16
16
|
description: "Heroicons by the Tailwind CSS team as React components",
|
|
17
17
|
},
|
|
18
|
+
{
|
|
19
|
+
id: "phosphor",
|
|
20
|
+
package: "@phosphor-icons/react",
|
|
21
|
+
description: "Phosphor icons in six weights (thin, light, regular, bold, fill, duotone) as React components",
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
id: "tabler",
|
|
25
|
+
package: "@tabler/icons-react",
|
|
26
|
+
description: "Tabler icons (outline and filled) as React components",
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
id: "iconoir",
|
|
30
|
+
package: "iconoir-react",
|
|
31
|
+
description: "Iconoir icons (regular and solid) as React components",
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
id: "fluentui",
|
|
35
|
+
package: "@fluentui/react-icons",
|
|
36
|
+
description: "Microsoft Fluent UI System icons (regular, filled and color) as React components",
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
id: "carbon",
|
|
40
|
+
package: "@carbon/icons-react",
|
|
41
|
+
description: "IBM Carbon Design System icons as React components",
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
id: "antdesign",
|
|
45
|
+
package: "@ant-design/icons",
|
|
46
|
+
description: "Ant Design icons (outlined, filled and two-tone) as React components",
|
|
47
|
+
},
|
|
18
48
|
];
|
|
19
49
|
// Finds a provider by its id or by its npm package name.
|
|
20
50
|
export function getProvider(idOrPackage) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/providers/registry.ts"],"names":[],"mappings":"AAQA,
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/providers/registry.ts"],"names":[],"mappings":"AAQA,4BAA4B;AAC5B,MAAM,CAAC,MAAM,SAAS,GAAwB;IAC5C;QACE,EAAE,EAAE,aAAa;QACjB,OAAO,EAAE,aAAa;QACtB,WAAW,EAAE,sFAAsF;KACpG;IACD;QACE,EAAE,EAAE,QAAQ;QACZ,OAAO,EAAE,cAAc;QACvB,WAAW,EAAE,kCAAkC;KAChD;IACD;QACE,EAAE,EAAE,WAAW;QACf,OAAO,EAAE,kBAAkB;QAC3B,WAAW,EAAE,wDAAwD;KACtE;IACD;QACE,EAAE,EAAE,UAAU;QACd,OAAO,EAAE,uBAAuB;QAChC,WAAW,EAAE,+FAA+F;KAC7G;IACD;QACE,EAAE,EAAE,QAAQ;QACZ,OAAO,EAAE,qBAAqB;QAC9B,WAAW,EAAE,uDAAuD;KACrE;IACD;QACE,EAAE,EAAE,SAAS;QACb,OAAO,EAAE,eAAe;QACxB,WAAW,EAAE,uDAAuD;KACrE;IACD;QACE,EAAE,EAAE,UAAU;QACd,OAAO,EAAE,uBAAuB;QAChC,WAAW,EAAE,kFAAkF;KAChG;IACD;QACE,EAAE,EAAE,QAAQ;QACZ,OAAO,EAAE,qBAAqB;QAC9B,WAAW,EAAE,oDAAoD;KAClE;IACD;QACE,EAAE,EAAE,WAAW;QACf,OAAO,EAAE,mBAAmB;QAC5B,WAAW,EAAE,sEAAsE;KACpF;CACF,CAAC;AAEF,yDAAyD;AACzD,MAAM,UAAU,WAAW,CAAC,WAAmB;IAC7C,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,WAAW,IAAI,CAAC,CAAC,OAAO,KAAK,WAAW,CAAC,CAAC;AAClF,CAAC"}
|
package/dist/providers/svg.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { JsValue } from "./jsLiteral.js";
|
|
1
|
+
import type { JsValue, LiteralCursor } from "./jsLiteral.js";
|
|
2
2
|
export interface SvgNode {
|
|
3
3
|
tag: string;
|
|
4
4
|
attr: Record<string, string | number>;
|
|
@@ -7,3 +7,4 @@ export interface SvgNode {
|
|
|
7
7
|
export declare function svgAttrName(reactName: string): string;
|
|
8
8
|
export declare function renderSvg(nodes: readonly SvgNode[]): string;
|
|
9
9
|
export declare function toSvgAttrs(value: JsValue | undefined): Record<string, string | number>;
|
|
10
|
+
export declare function parseCreateElement(cursor: LiteralCursor): SvgNode;
|
package/dist/providers/svg.js
CHANGED
|
@@ -49,6 +49,8 @@ const CASE_SENSITIVE_ATTRS = new Set([
|
|
|
49
49
|
"calcMode",
|
|
50
50
|
"keyTimes",
|
|
51
51
|
"keySplines",
|
|
52
|
+
"requiredExtensions",
|
|
53
|
+
"systemLanguage",
|
|
52
54
|
]);
|
|
53
55
|
const SPECIAL_ATTRS = {
|
|
54
56
|
className: "class",
|
|
@@ -94,4 +96,18 @@ export function toSvgAttrs(value) {
|
|
|
94
96
|
}
|
|
95
97
|
return attrs;
|
|
96
98
|
}
|
|
99
|
+
// Parses a compiled `<ns>.createElement("tag", {attrs} | null, ...children)` call (any namespace
|
|
100
|
+
// identifier, e.g. "React" or a minified "e"), recursing into element children.
|
|
101
|
+
export function parseCreateElement(cursor) {
|
|
102
|
+
cursor.identifier();
|
|
103
|
+
cursor.expect(".createElement(");
|
|
104
|
+
const tag = cursor.string();
|
|
105
|
+
cursor.expect(",");
|
|
106
|
+
const attr = toSvgAttrs(cursor.value());
|
|
107
|
+
const child = [];
|
|
108
|
+
while (cursor.eat(","))
|
|
109
|
+
child.push(parseCreateElement(cursor));
|
|
110
|
+
cursor.expect(")");
|
|
111
|
+
return { tag, attr, child };
|
|
112
|
+
}
|
|
97
113
|
//# sourceMappingURL=svg.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"svg.js","sourceRoot":"","sources":["../../src/providers/svg.ts"],"names":[],"mappings":"AAQA,6FAA6F;AAC7F,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC;IACnC,SAAS;IACT,qBAAqB;IACrB,aAAa;IACb,YAAY;IACZ,YAAY;IACZ,cAAc;IACd,aAAa;IACb,cAAc;IACd,eAAe;IACf,mBAAmB;IACnB,cAAc;IACd,qBAAqB;IACrB,kBAAkB;IAClB,eAAe;IACf,WAAW;IACX,kBAAkB;IAClB,aAAa;IACb,gBAAgB;IAChB,aAAa;IACb,aAAa;IACb,cAAc;IACd,MAAM;IACN,MAAM;IACN,cAAc;IACd,eAAe;IACf,YAAY;IACZ,aAAa;IACb,cAAc;IACd,kBAAkB;IAClB,aAAa;IACb,cAAc;IACd,kBAAkB;IAClB,kBAAkB;IAClB,iBAAiB;IACjB,UAAU;IACV,SAAS;IACT,SAAS;IACT,kBAAkB;IAClB,kBAAkB;IAClB,mBAAmB;IACnB,WAAW;IACX,WAAW;IACX,WAAW;IACX,eAAe;IACf,eAAe;IACf,aAAa;IACb,UAAU;IACV,UAAU;IACV,YAAY;
|
|
1
|
+
{"version":3,"file":"svg.js","sourceRoot":"","sources":["../../src/providers/svg.ts"],"names":[],"mappings":"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"}
|
package/dist/search/search.d.ts
CHANGED
|
@@ -22,5 +22,9 @@ export interface SearchResult {
|
|
|
22
22
|
export declare function loadIndex(cacheDir: string): Promise<LoadedIndex>;
|
|
23
23
|
/** True when an index was built with different synonyms or an older index format. */
|
|
24
24
|
export declare function indexNeedsRebuild(meta: IndexMeta, synonyms: Synonyms): boolean;
|
|
25
|
-
/**
|
|
25
|
+
/**
|
|
26
|
+
* Filters records by provider/style/set exactly, then ranks them against the query with Fuse.js.
|
|
27
|
+
* Multi-word queries are searched token by token: only records matching every token are kept,
|
|
28
|
+
* ranked by their mean per-token score.
|
|
29
|
+
*/
|
|
26
30
|
export declare function searchIcons(records: readonly IconRecord[], query: string, options?: SearchOptions): SearchResult[];
|
package/dist/search/search.js
CHANGED
|
@@ -30,16 +30,30 @@ const FUSE_OPTIONS = {
|
|
|
30
30
|
function matches(value, filter) {
|
|
31
31
|
return filter === undefined || value?.toLowerCase() === filter.toLowerCase();
|
|
32
32
|
}
|
|
33
|
-
/**
|
|
33
|
+
/**
|
|
34
|
+
* Filters records by provider/style/set exactly, then ranks them against the query with Fuse.js.
|
|
35
|
+
* Multi-word queries are searched token by token: only records matching every token are kept,
|
|
36
|
+
* ranked by their mean per-token score.
|
|
37
|
+
*/
|
|
34
38
|
export function searchIcons(records, query, options = {}) {
|
|
35
|
-
const
|
|
36
|
-
if (
|
|
39
|
+
const tokens = query.trim().split(/\s+/).filter(Boolean);
|
|
40
|
+
if (tokens.length === 0)
|
|
37
41
|
return [];
|
|
38
42
|
const { provider, style, set, limit } = options;
|
|
39
43
|
const filtered = records.filter((r) => matches(r.provider, provider) && matches(r.style, style) && matches(r.set, set));
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
44
|
+
const fuse = new Fuse(filtered, FUSE_OPTIONS);
|
|
45
|
+
const perToken = tokens.map((token) => new Map(fuse.search(token).map((result) => [result.item, result.score ?? 0])));
|
|
46
|
+
const [first, ...rest] = perToken;
|
|
47
|
+
// Iterate in the first token's ranked order so ties keep Fuse's ordering (sort is stable).
|
|
48
|
+
const results = [];
|
|
49
|
+
for (const [record, score] of first) {
|
|
50
|
+
const others = rest.map((scores) => scores.get(record));
|
|
51
|
+
if (others.some((s) => s === undefined))
|
|
52
|
+
continue;
|
|
53
|
+
const total = others.reduce((sum, s) => sum + s, score);
|
|
54
|
+
results.push({ record, score: total / tokens.length });
|
|
55
|
+
}
|
|
56
|
+
results.sort((a, b) => a.score - b.score);
|
|
43
57
|
return limit === undefined ? results : results.slice(0, Math.max(0, limit));
|
|
44
58
|
}
|
|
45
59
|
//# sourceMappingURL=search.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/search/search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,IAA2B,MAAM,SAAS,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAyB9F,oFAAoF;AACpF,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,QAAgB;IAC9C,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACtC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAC5C,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,EAAE,MAAM,CAAC;KAC5C,CAAC,CAAC;IACH,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAiB,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAc,EAAE,CAAC;AAC7F,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,iBAAiB,CAAC,IAAe,EAAE,QAAkB;IACnE,OAAO,IAAI,CAAC,YAAY,KAAK,aAAa,IAAI,IAAI,CAAC,YAAY,KAAK,YAAY,CAAC,QAAQ,CAAC,CAAC;AAC7F,CAAC;AAED,MAAM,YAAY,GAA6B;IAC7C,IAAI,EAAE;QACJ,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE;QAC3B,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC,EAAE;QACjC,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,EAAE;QAC/B,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE;KAC5B;IACD,YAAY,EAAE,IAAI;IAClB,sGAAsG;IACtG,cAAc,EAAE,IAAI;IACpB,SAAS,EAAE,GAAG;IACd,kBAAkB,EAAE,CAAC;CACtB,CAAC;AAEF,SAAS,OAAO,CAAC,KAAyB,EAAE,MAA0B;IACpE,OAAO,MAAM,KAAK,SAAS,IAAI,KAAK,EAAE,WAAW,EAAE,KAAK,MAAM,CAAC,WAAW,EAAE,CAAC;AAC/E,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/search/search.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
CHANGED
package/dist/server.js
CHANGED
|
@@ -4,7 +4,7 @@ import { registerListProvidersTool } from "./tools/listProviders.js";
|
|
|
4
4
|
import { registerPingTool } from "./tools/ping.js";
|
|
5
5
|
import { registerSearchIconsTool } from "./tools/searchIcons.js";
|
|
6
6
|
export const SERVER_NAME = "trueicon";
|
|
7
|
-
export const SERVER_VERSION = "0.
|
|
7
|
+
export const SERVER_VERSION = "0.2.0";
|
|
8
8
|
// Builds the MCP server with all tools registered. Transport wiring lives in index.ts.
|
|
9
9
|
export function createServer() {
|
|
10
10
|
const server = new McpServer({ name: SERVER_NAME, version: SERVER_VERSION });
|
package/dist/tools/getIcon.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { ensureIndex } from "../config/ensureIndex.js";
|
|
3
3
|
import { CONFIG_FILE, loadProjectConfig } from "../config/loadConfig.js";
|
|
4
|
+
import { toKebabCase } from "../providers/adapter.js";
|
|
4
5
|
import { getProvider } from "../providers/registry.js";
|
|
5
6
|
import { loadIndex } from "../search/search.js";
|
|
6
7
|
import { jsonToolResult, resolveContext, resolveVersion, usageSnippet } from "./context.js";
|
|
@@ -9,7 +10,13 @@ function findRecord(records, name) {
|
|
|
9
10
|
if (exact)
|
|
10
11
|
return exact;
|
|
11
12
|
const lower = name.toLowerCase();
|
|
12
|
-
|
|
13
|
+
const caseInsensitive = records.find((r) => r.name.toLowerCase() === lower || r.importName.toLowerCase() === lower);
|
|
14
|
+
if (caseInsensitive)
|
|
15
|
+
return caseInsensitive;
|
|
16
|
+
// Deprecated or renamed icons are kept as alias tags on the current icon, e.g. lucide 1.47
|
|
17
|
+
// renamed trash-2 to trash, so "Trash2" resolves to the Trash record.
|
|
18
|
+
const kebab = toKebabCase(name);
|
|
19
|
+
return records.find((r) => r.tags.some((tag) => tag === lower || tag === kebab));
|
|
13
20
|
}
|
|
14
21
|
/** Looks up one icon by name or import name and returns its full record plus an import snippet. */
|
|
15
22
|
export async function getIconTool(input, ctx) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getIcon.js","sourceRoot":"","sources":["../../src/tools/getIcon.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEzE,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAoB,MAAM,cAAc,CAAC;AAY9G,SAAS,UAAU,CAAC,OAA8B,EAAE,IAAY;IAC9D,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,UAAU,KAAK,IAAI,CAAC,CAAC;IAC5E,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC;IACxB,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACjC,
|
|
1
|
+
{"version":3,"file":"getIcon.js","sourceRoot":"","sources":["../../src/tools/getIcon.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "trueicon",
|
|
3
3
|
"mcpName": "io.github.manikumarkv/trueicon",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.2.1",
|
|
5
5
|
"description": "MCP server that lets AI coding assistants search the icon packages actually installed in your project.",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"author": "manikumarkv",
|
|
@@ -20,7 +20,13 @@
|
|
|
20
20
|
"icons",
|
|
21
21
|
"lucide",
|
|
22
22
|
"heroicons",
|
|
23
|
-
"react-icons"
|
|
23
|
+
"react-icons",
|
|
24
|
+
"phosphor",
|
|
25
|
+
"tabler",
|
|
26
|
+
"iconoir",
|
|
27
|
+
"fluentui",
|
|
28
|
+
"carbon",
|
|
29
|
+
"ant-design"
|
|
24
30
|
],
|
|
25
31
|
"type": "module",
|
|
26
32
|
"bin": {
|
|
@@ -37,7 +43,11 @@
|
|
|
37
43
|
"typecheck": "tsc --noEmit",
|
|
38
44
|
"test": "vitest run",
|
|
39
45
|
"lint": "eslint",
|
|
40
|
-
"prepublishOnly": "npm run build"
|
|
46
|
+
"prepublishOnly": "npm run build",
|
|
47
|
+
"dev:call": "npm run build --silent && node scripts/dev.mjs call",
|
|
48
|
+
"dev:inspect": "npm run build --silent && node scripts/dev.mjs inspect",
|
|
49
|
+
"dev:debug": "npm run build --silent && node scripts/dev.mjs inspect --debug",
|
|
50
|
+
"smoke": "npm run build --silent && node scripts/smoke.mjs"
|
|
41
51
|
},
|
|
42
52
|
"dependencies": {
|
|
43
53
|
"@modelcontextprotocol/sdk": "^1.30.1",
|