mirror of
https://github.com/lucide-icons/lucide.git
synced 2025-12-16 16:57:44 +01:00
Deprecate tags.json (#896)
* Deprecates tags.json and icons.json * Removed tags.json dependency from Figma plugin * Add JSON descriptor information to readme * Restore packages/index.tsx * Update packages/lucide-figma/src/api/fetchIcons.ts Add multiple fetches to `Promise.all` * Added caching to API endpoints * Updates pnpm-lock.yaml * Add tags to static * Trigger site build * Added prebuild script to generate api caches at build time * Migrated NextCache function from arrow to regular to simplify markup * test if contents are read from cache * Add cache clear to prebuild * removes debug object --------- Co-authored-by: Karsa <karsa@karsa.org> Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
This commit is contained in:
2
.github/PULL_REQUEST_TEMPLATE/new-icon.md
vendored
2
.github/PULL_REQUEST_TEMPLATE/new-icon.md
vendored
@@ -9,7 +9,7 @@ at https://github.com/lucide-icons/lucide/blob/main/docs/ICON_DESIGN_GUIDE.md be
|
||||
and please fill everything below. -->
|
||||
|
||||
- **Name of the icon** : <!-- `icon` -->
|
||||
- **Tags (alternative names for this icon)** (add them in tags.json) :
|
||||
- **Tags (alternative names for this icon)** (add them in as a separate json file using the same icon name) :
|
||||
- **What is the purpose of this icon?** : <!-- Shows that one can click it to... / Is used to denote or label... -->
|
||||
- **100% scale preview** : <!-- upload an image -->
|
||||
- **Have you considered alternative possibilities** for its naming or design? :
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -18,3 +18,5 @@ packages/**/src/icons/*.ts
|
||||
packages/**/src/icons/*.tsx
|
||||
packages/**/src/aliases.ts
|
||||
packages/**/LICENSE
|
||||
categories.json
|
||||
tags.json
|
||||
|
||||
1558
categories.json
1558
categories.json
File diff suppressed because it is too large
Load Diff
@@ -80,3 +80,21 @@ For each icon these attributes are applied, corresponding to the above rules.
|
||||
Code of paths can get really big.
|
||||
To reduce file size we like to minify the code.
|
||||
We recommend to use the [SVGOMG](https://jakearchibald.github.io/svgomg/) to minify paths.
|
||||
|
||||
### JSON metadata descriptor
|
||||
|
||||
Each icon added must also come with a matching JSON file listing tags and categories for the icon.
|
||||
Please use the following template:
|
||||
|
||||
```json
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"tags": [
|
||||
"foo",
|
||||
"bar"
|
||||
],
|
||||
"categories": [
|
||||
"devices"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
9682
icons.json
9682
icons.json
File diff suppressed because it is too large
Load Diff
@@ -1,84 +0,0 @@
|
||||
{
|
||||
"$id": "https://lucide.dev/icons.schema.json",
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$vocabulary": {
|
||||
"https://json-schema.org/draft/2020-12/vocab/core": true,
|
||||
"https://json-schema.org/draft/2020-12/vocab/applicator": true,
|
||||
"https://json-schema.org/draft/2020-12/vocab/unevaluated": true,
|
||||
"https://json-schema.org/draft/2020-12/vocab/validation": true,
|
||||
"https://json-schema.org/draft/2020-12/vocab/meta-data": true,
|
||||
"https://json-schema.org/draft/2020-12/vocab/format-annotation": true,
|
||||
"https://json-schema.org/draft/2020-12/vocab/content": true
|
||||
},
|
||||
|
||||
"title": "Lucide Icons schema",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"icons": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/$defs/types/icon"
|
||||
}
|
||||
},
|
||||
"categories": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/$defs/types/category"
|
||||
}
|
||||
}
|
||||
},
|
||||
"$defs": {
|
||||
"types": {
|
||||
"icon": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"tags": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 1,
|
||||
"uniqueItems": true
|
||||
},
|
||||
"categories": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/$defs/types/category-reference"
|
||||
},
|
||||
"uniqueItems": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"category": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"icon": {
|
||||
"$ref": "#/$defs/types/icon-reference"
|
||||
},
|
||||
"weight": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"title",
|
||||
"icon"
|
||||
]
|
||||
},
|
||||
"icon-reference": {
|
||||
"type": "string",
|
||||
"format": "uri-reference"
|
||||
},
|
||||
"category-reference": {
|
||||
"type": "string",
|
||||
"format": "uri-reference"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "A JSON Schema for icons, tags & categories defined by Lucide Icons."
|
||||
}
|
||||
@@ -4,8 +4,7 @@
|
||||
"arrow",
|
||||
"expand",
|
||||
"horizontal",
|
||||
"unfold",
|
||||
"horizonal"
|
||||
"unfold"
|
||||
],
|
||||
"categories": [
|
||||
"arrows"
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
"arrow",
|
||||
"collapse",
|
||||
"fold",
|
||||
"horizontal",
|
||||
"horizonal"
|
||||
"horizontal"
|
||||
],
|
||||
"categories": [
|
||||
"arrows"
|
||||
|
||||
9
icons/subtitles.json
Normal file
9
icons/subtitles.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"tags": [
|
||||
"captions",
|
||||
"closed captions",
|
||||
"accessibility"
|
||||
],
|
||||
"categories": []
|
||||
}
|
||||
@@ -16,13 +16,12 @@
|
||||
"build:outline-icons": "pnpm --filter outline-svg start",
|
||||
"generate:supersprite": "node ./scripts/generateSuperSVG.mjs",
|
||||
"optimize": "node ./scripts/optimizeSvgs.mjs",
|
||||
"addtags": "node ./scripts/addMissingKeysToTags.mjs",
|
||||
"addjsons": "node scripts/addMissingIconJsonFiles.mjs",
|
||||
"checkIcons": "node scripts/checkIconsAndCategories.mjs --presets @babel/env",
|
||||
"tags2icons": "node scripts/migrateTagsToIcons.mjs --presets @babel/env",
|
||||
"icons2tags": "node scripts/migrateIconsToTags.mjs --presets @babel/env",
|
||||
"icons2categories": "node scripts/migrateIconsToCategories.mjs --presets @babel/env",
|
||||
"categories2icons": "node scripts/migrateCategoriesToIcons.mjs --presets @babel/env",
|
||||
"icons2files": "node scripts/migrateIconsToJsonFiles.mjs --presets @babel/env",
|
||||
"generate:changelog": "node ./scripts/generateChangelog.mjs",
|
||||
"postinstall": "husky install",
|
||||
"lint": "eslint --ext .ts,.js,.mjs ./{packages/lucide,scripts}"
|
||||
|
||||
@@ -23,8 +23,10 @@ export const fetchIcons = async (cachedIcons? : LucideIcons): Promise<LucideIcon
|
||||
return cachedIcons
|
||||
}
|
||||
|
||||
const iconNodesResponse = await fetch(`https://unpkg.com/lucide-static@${packageJson.version}/icon-nodes.json`)
|
||||
const tagsResponse = await fetch('https://unpkg.com/lucide-static@latest/tags.json')
|
||||
const [iconNodesResponse, tagsResponse] = await Promise.all([
|
||||
fetch('https://lucide.dev/api/icon-nodes'),
|
||||
fetch('https://lucide.dev/api/tags')
|
||||
])
|
||||
|
||||
const iconNodes = await iconNodesResponse.json();
|
||||
const tags = await tagsResponse.json();
|
||||
|
||||
@@ -12,11 +12,11 @@
|
||||
"main": "lib/index.js",
|
||||
"scripts": {
|
||||
"copy:icons": "cp -r ../../icons icons",
|
||||
"copy:tags": "cp ../../tags.json tags.json",
|
||||
"copy:license": "cp ../../LICENSE ./LICENSE",
|
||||
"build": "pnpm clean && pnpm copy:license && pnpm copy:icons && pnpm copy:tags && pnpm build:lib",
|
||||
"build:tags": "node ../../scripts/migrateIconsToTags.mjs",
|
||||
"build": "pnpm clean && pnpm copy:license && pnpm copy:icons && pnpm build:lib && pnpm build:tags",
|
||||
"build:lib": "node ./scripts/buildLib.mjs",
|
||||
"clean": "rm -rf lib && rm -rf build && rm -rf icons && rm -f sprite.svg && rm -f tags.json",
|
||||
"clean": "rm -rf lib && rm -rf build && rm -rf icons && rm -f sprite.svg",
|
||||
"version": "pnpm version --git-tag-version=false"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
100
pnpm-lock.yaml
generated
100
pnpm-lock.yaml
generated
@@ -407,6 +407,9 @@ importers:
|
||||
react-dom: 17.0.2
|
||||
react-svg-loader: ^3.0.3
|
||||
react-test-renderer: 17.0.2
|
||||
svgson: ^5.2.1
|
||||
ts-node: ~10.9.1
|
||||
tslib: ^2.4.0
|
||||
typescript: ^4.3.5
|
||||
dependencies:
|
||||
'@chakra-ui/react': 1.8.8_vt5jn3lkv6hocyebmjm7gusm6e
|
||||
@@ -431,6 +434,7 @@ importers:
|
||||
react-color: 2.19.3_react@17.0.2
|
||||
react-dom: 17.0.2_react@17.0.2
|
||||
react-svg-loader: 3.0.3
|
||||
svgson: 5.2.1
|
||||
devDependencies:
|
||||
'@next/eslint-plugin-next': 12.2.5
|
||||
'@testing-library/dom': 7.31.2
|
||||
@@ -447,9 +451,11 @@ importers:
|
||||
babel-loader: 8.2.5_webpack@5.74.0
|
||||
eslint: 8.22.0
|
||||
eslint-config-prettier: 8.5.0_eslint@8.22.0
|
||||
jest: 26.6.3
|
||||
jest: 26.6.3_ts-node@10.9.1
|
||||
prettier: 2.7.1
|
||||
react-test-renderer: 17.0.2_react@17.0.2
|
||||
ts-node: 10.9.1_gqqbkana4qauswgj6o2wzoub7a
|
||||
tslib: 2.4.0
|
||||
typescript: 4.8.4
|
||||
|
||||
tools/build-icons:
|
||||
@@ -7487,7 +7493,7 @@ packages:
|
||||
slash: 3.0.0
|
||||
dev: true
|
||||
|
||||
/@jest/core/26.6.3:
|
||||
/@jest/core/26.6.3_ts-node@10.9.1:
|
||||
resolution: {integrity: sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==}
|
||||
engines: {node: '>= 10.14.2'}
|
||||
dependencies:
|
||||
@@ -7502,14 +7508,14 @@ packages:
|
||||
exit: 0.1.2
|
||||
graceful-fs: 4.2.10
|
||||
jest-changed-files: 26.6.2
|
||||
jest-config: 26.6.3
|
||||
jest-config: 26.6.3_ts-node@10.9.1
|
||||
jest-haste-map: 26.6.2
|
||||
jest-message-util: 26.6.2
|
||||
jest-regex-util: 26.0.0
|
||||
jest-resolve: 26.6.2
|
||||
jest-resolve-dependencies: 26.6.3
|
||||
jest-runner: 26.6.3
|
||||
jest-runtime: 26.6.3
|
||||
jest-runner: 26.6.3_ts-node@10.9.1
|
||||
jest-runtime: 26.6.3_ts-node@10.9.1
|
||||
jest-snapshot: 26.6.2
|
||||
jest-util: 26.6.2
|
||||
jest-validate: 26.6.2
|
||||
@@ -7632,15 +7638,15 @@ packages:
|
||||
collect-v8-coverage: 1.0.1
|
||||
dev: true
|
||||
|
||||
/@jest/test-sequencer/26.6.3:
|
||||
/@jest/test-sequencer/26.6.3_ts-node@10.9.1:
|
||||
resolution: {integrity: sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==}
|
||||
engines: {node: '>= 10.14.2'}
|
||||
dependencies:
|
||||
'@jest/test-result': 26.6.2
|
||||
graceful-fs: 4.2.10
|
||||
jest-haste-map: 26.6.2
|
||||
jest-runner: 26.6.3
|
||||
jest-runtime: 26.6.3
|
||||
jest-runner: 26.6.3_ts-node@10.9.1
|
||||
jest-runtime: 26.6.3_ts-node@10.9.1
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- canvas
|
||||
@@ -10147,14 +10153,6 @@ packages:
|
||||
acorn: 8.8.1
|
||||
dev: true
|
||||
|
||||
/acorn-jsx/5.3.2_acorn@8.8.0:
|
||||
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
|
||||
peerDependencies:
|
||||
acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
|
||||
dependencies:
|
||||
acorn: 8.8.0
|
||||
dev: true
|
||||
|
||||
/acorn-jsx/5.3.2_acorn@8.8.1:
|
||||
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
|
||||
peerDependencies:
|
||||
@@ -14113,8 +14111,8 @@ packages:
|
||||
resolution: {integrity: sha512-ORs1Rt/uQTqUKjDdGCyrtYxbazf5umATSf/K4qxjmZHORR6HJk+2s/2Pqe+Kk49HHINC/xNIrGfgh8sZcll0ng==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
dependencies:
|
||||
acorn: 8.8.0
|
||||
acorn-jsx: 5.3.2_acorn@8.8.0
|
||||
acorn: 8.8.1
|
||||
acorn-jsx: 5.3.2_acorn@8.8.1
|
||||
eslint-visitor-keys: 3.3.0
|
||||
dev: true
|
||||
|
||||
@@ -16097,12 +16095,12 @@ packages:
|
||||
throat: 5.0.0
|
||||
dev: true
|
||||
|
||||
/jest-cli/26.6.3:
|
||||
/jest-cli/26.6.3_ts-node@10.9.1:
|
||||
resolution: {integrity: sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==}
|
||||
engines: {node: '>= 10.14.2'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
'@jest/core': 26.6.3
|
||||
'@jest/core': 26.6.3_ts-node@10.9.1
|
||||
'@jest/test-result': 26.6.2
|
||||
'@jest/types': 26.6.2
|
||||
chalk: 4.1.2
|
||||
@@ -16110,7 +16108,7 @@ packages:
|
||||
graceful-fs: 4.2.10
|
||||
import-local: 3.1.0
|
||||
is-ci: 2.0.0
|
||||
jest-config: 26.6.3
|
||||
jest-config: 26.6.3_ts-node@10.9.1
|
||||
jest-util: 26.6.2
|
||||
jest-validate: 26.6.2
|
||||
prompts: 2.4.2
|
||||
@@ -16123,7 +16121,7 @@ packages:
|
||||
- utf-8-validate
|
||||
dev: true
|
||||
|
||||
/jest-config/26.6.3:
|
||||
/jest-config/26.6.3_ts-node@10.9.1:
|
||||
resolution: {integrity: sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==}
|
||||
engines: {node: '>= 10.14.2'}
|
||||
peerDependencies:
|
||||
@@ -16133,7 +16131,7 @@ packages:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/core': 7.20.2
|
||||
'@jest/test-sequencer': 26.6.3
|
||||
'@jest/test-sequencer': 26.6.3_ts-node@10.9.1
|
||||
'@jest/types': 26.6.2
|
||||
babel-jest: 26.6.3_@babel+core@7.20.2
|
||||
chalk: 4.1.2
|
||||
@@ -16143,13 +16141,14 @@ packages:
|
||||
jest-environment-jsdom: 26.6.2
|
||||
jest-environment-node: 26.6.2
|
||||
jest-get-type: 26.3.0
|
||||
jest-jasmine2: 26.6.3
|
||||
jest-jasmine2: 26.6.3_ts-node@10.9.1
|
||||
jest-regex-util: 26.0.0
|
||||
jest-resolve: 26.6.2
|
||||
jest-util: 26.6.2
|
||||
jest-validate: 26.6.2
|
||||
micromatch: 4.0.5
|
||||
pretty-format: 26.6.2
|
||||
ts-node: 10.9.1_gqqbkana4qauswgj6o2wzoub7a
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- canvas
|
||||
@@ -16278,7 +16277,7 @@ packages:
|
||||
fsevents: 2.3.2
|
||||
dev: true
|
||||
|
||||
/jest-jasmine2/26.6.3:
|
||||
/jest-jasmine2/26.6.3_ts-node@10.9.1:
|
||||
resolution: {integrity: sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==}
|
||||
engines: {node: '>= 10.14.2'}
|
||||
dependencies:
|
||||
@@ -16295,7 +16294,7 @@ packages:
|
||||
jest-each: 26.6.2
|
||||
jest-matcher-utils: 26.6.2
|
||||
jest-message-util: 26.6.2
|
||||
jest-runtime: 26.6.3
|
||||
jest-runtime: 26.6.3_ts-node@10.9.1
|
||||
jest-snapshot: 26.6.2
|
||||
jest-util: 26.6.2
|
||||
pretty-format: 26.6.2
|
||||
@@ -16421,7 +16420,7 @@ packages:
|
||||
slash: 3.0.0
|
||||
dev: true
|
||||
|
||||
/jest-runner/26.6.3:
|
||||
/jest-runner/26.6.3_ts-node@10.9.1:
|
||||
resolution: {integrity: sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==}
|
||||
engines: {node: '>= 10.14.2'}
|
||||
dependencies:
|
||||
@@ -16434,13 +16433,13 @@ packages:
|
||||
emittery: 0.7.2
|
||||
exit: 0.1.2
|
||||
graceful-fs: 4.2.10
|
||||
jest-config: 26.6.3
|
||||
jest-config: 26.6.3_ts-node@10.9.1
|
||||
jest-docblock: 26.0.0
|
||||
jest-haste-map: 26.6.2
|
||||
jest-leak-detector: 26.6.2
|
||||
jest-message-util: 26.6.2
|
||||
jest-resolve: 26.6.2
|
||||
jest-runtime: 26.6.3
|
||||
jest-runtime: 26.6.3_ts-node@10.9.1
|
||||
jest-util: 26.6.2
|
||||
jest-worker: 26.6.2
|
||||
source-map-support: 0.5.21
|
||||
@@ -16453,7 +16452,7 @@ packages:
|
||||
- utf-8-validate
|
||||
dev: true
|
||||
|
||||
/jest-runtime/26.6.3:
|
||||
/jest-runtime/26.6.3_ts-node@10.9.1:
|
||||
resolution: {integrity: sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==}
|
||||
engines: {node: '>= 10.14.2'}
|
||||
hasBin: true
|
||||
@@ -16473,7 +16472,7 @@ packages:
|
||||
exit: 0.1.2
|
||||
glob: 7.2.3
|
||||
graceful-fs: 4.2.10
|
||||
jest-config: 26.6.3
|
||||
jest-config: 26.6.3_ts-node@10.9.1
|
||||
jest-haste-map: 26.6.2
|
||||
jest-message-util: 26.6.2
|
||||
jest-mock: 26.6.2
|
||||
@@ -16618,14 +16617,14 @@ packages:
|
||||
supports-color: 8.1.1
|
||||
dev: true
|
||||
|
||||
/jest/26.6.3:
|
||||
/jest/26.6.3_ts-node@10.9.1:
|
||||
resolution: {integrity: sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q==}
|
||||
engines: {node: '>= 10.14.2'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
'@jest/core': 26.6.3
|
||||
'@jest/core': 26.6.3_ts-node@10.9.1
|
||||
import-local: 3.1.0
|
||||
jest-cli: 26.6.3
|
||||
jest-cli: 26.6.3_ts-node@10.9.1
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- canvas
|
||||
@@ -22243,7 +22242,7 @@ packages:
|
||||
jest-worker: 27.5.1
|
||||
schema-utils: 3.1.1
|
||||
serialize-javascript: 6.0.0
|
||||
terser: 5.14.2
|
||||
terser: 5.16.1
|
||||
webpack: 5.74.0
|
||||
dev: true
|
||||
|
||||
@@ -22495,6 +22494,37 @@ packages:
|
||||
yn: 3.1.1
|
||||
dev: true
|
||||
|
||||
/ts-node/10.9.1_gqqbkana4qauswgj6o2wzoub7a:
|
||||
resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
'@swc/core': '>=1.2.50'
|
||||
'@swc/wasm': '>=1.2.50'
|
||||
'@types/node': '*'
|
||||
typescript: '>=2.7'
|
||||
peerDependenciesMeta:
|
||||
'@swc/core':
|
||||
optional: true
|
||||
'@swc/wasm':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@cspotcode/source-map-support': 0.8.1
|
||||
'@tsconfig/node10': 1.0.9
|
||||
'@tsconfig/node12': 1.0.11
|
||||
'@tsconfig/node14': 1.0.3
|
||||
'@tsconfig/node16': 1.0.3
|
||||
'@types/node': 14.18.25
|
||||
acorn: 8.8.1
|
||||
acorn-walk: 8.2.0
|
||||
arg: 4.1.3
|
||||
create-require: 1.1.1
|
||||
diff: 4.0.2
|
||||
make-error: 1.3.6
|
||||
typescript: 4.8.4
|
||||
v8-compile-cache-lib: 3.0.1
|
||||
yn: 3.1.1
|
||||
dev: true
|
||||
|
||||
/ts-toolbelt/9.6.0:
|
||||
resolution: {integrity: sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==}
|
||||
dev: true
|
||||
|
||||
21
scripts/addMissingIconJsonFiles.mjs
Normal file
21
scripts/addMissingIconJsonFiles.mjs
Normal file
@@ -0,0 +1,21 @@
|
||||
import path from 'path';
|
||||
import {getCurrentDirPath, readAllMetadata, readSvgDirectory, writeFile} from './helpers.mjs';
|
||||
|
||||
const currentDir = getCurrentDirPath(import.meta.url);
|
||||
const ICONS_DIR = path.resolve(currentDir, '../icons');
|
||||
const icons = readAllMetadata(ICONS_DIR);
|
||||
|
||||
const svgFiles = readSvgDirectory(ICONS_DIR);
|
||||
|
||||
const iconNames = svgFiles.map((icon) => icon.split('.')[0]);
|
||||
|
||||
iconNames.forEach(iconName => {
|
||||
if (typeof icons[iconName] === 'undefined') {
|
||||
const iconContent = JSON.stringify({
|
||||
"$schema": "../icon.schema.json",
|
||||
"tags": [],
|
||||
"categories": []
|
||||
}, null, 2);
|
||||
writeFile(iconContent, `${iconName}.json`, path.resolve(currentDir, '..'));
|
||||
}
|
||||
});
|
||||
@@ -1,42 +0,0 @@
|
||||
import path from 'path';
|
||||
import tags from '../tags.json' assert { type: 'json' };
|
||||
import { readSvgDirectory, writeFile, getCurrentDirPath } from './helpers.mjs';
|
||||
|
||||
const currentDir = getCurrentDirPath(import.meta.url);
|
||||
const ICONS_DIR = path.resolve(currentDir, '../icons');
|
||||
|
||||
console.log(`Read all tags`);
|
||||
|
||||
const svgFiles = readSvgDirectory(ICONS_DIR);
|
||||
|
||||
const iconNames = svgFiles.map((icon) => icon.split('.')[0]);
|
||||
|
||||
const iconTags = iconNames
|
||||
.map((iconName) => ({
|
||||
name: iconName,
|
||||
tags: tags[iconName] || [],
|
||||
}))
|
||||
.sort((a, b) => {
|
||||
const nameA = a.name;
|
||||
const nameB = b.name;
|
||||
|
||||
if (nameA < nameB) {
|
||||
return -1;
|
||||
}
|
||||
if (nameA > nameB) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// names must be equal
|
||||
return 0;
|
||||
});
|
||||
|
||||
const newTags = iconTags.reduce((acc, { name, tags }) => {
|
||||
acc[name] = tags;
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
const tagsContent = JSON.stringify(newTags, null, 2);
|
||||
|
||||
writeFile(tagsContent, 'tags.json', path.resolve(currentDir, '..'));
|
||||
@@ -1,50 +1,51 @@
|
||||
import path from 'path';
|
||||
import icons from '../icons.json' assert { type: 'json' };
|
||||
import { readSvgDirectory, getCurrentDirPath } from './helpers.mjs';
|
||||
import { readSvgDirectory, getCurrentDirPath, readAllMetadata } from './helpers.mjs';
|
||||
|
||||
const currentDir = getCurrentDirPath(import.meta.url)
|
||||
const ICONS_DIR = path.resolve(currentDir, '../icons');
|
||||
const icons = readAllMetadata(ICONS_DIR);
|
||||
const CATEGORIES_DIR = path.resolve(currentDir, '../categories');
|
||||
const categories = readAllMetadata(CATEGORIES_DIR);
|
||||
|
||||
console.log(`Read all icons`);
|
||||
|
||||
const svgFiles = readSvgDirectory(ICONS_DIR);
|
||||
|
||||
const iconNames = svgFiles.map(icon => icon.split('.')[0]);
|
||||
|
||||
let error = false;
|
||||
|
||||
iconNames.forEach(iconName => {
|
||||
if (typeof icons.icons[iconName] === 'undefined') {
|
||||
console.error(`'${iconName}.svg' is not present in 'icons.json'.`);
|
||||
if (typeof icons[iconName] === 'undefined') {
|
||||
console.error(`'${iconName}.svg' does not have a matching JSON file.`);
|
||||
error = true;
|
||||
}
|
||||
});
|
||||
|
||||
Object.keys(icons.icons).forEach(iconName => {
|
||||
const icon = icons.icons[iconName];
|
||||
Object.keys(icons).forEach(iconName => {
|
||||
const icon = icons[iconName];
|
||||
if (iconNames.indexOf(iconName) === -1) {
|
||||
console.error(`'${iconName}.svg' does not exist.`);
|
||||
error = true;
|
||||
}
|
||||
icon.categories.forEach(categoryName => {
|
||||
if (typeof icons.categories[categoryName] === 'undefined') {
|
||||
if (typeof categories[categoryName] === 'undefined') {
|
||||
console.error(`Icon '${iconName}' refers to the non-existing category '${categoryName}'.`);
|
||||
error = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Object.keys(icons.categories).forEach(categoryName => {
|
||||
const category = icons.categories[categoryName];
|
||||
Object.keys(categories).forEach(categoryName => {
|
||||
const category = categories[categoryName];
|
||||
if (!category.icon) {
|
||||
console.error(`Category '${categoryName}' does not use an icon '${category.icon}'.`);
|
||||
error = true;
|
||||
} else if (typeof icons.icons[category.icon] === 'undefined') {
|
||||
} else if (typeof icons[category.icon] === 'undefined') {
|
||||
console.error(`Category '${categoryName}' uses the non-existing icon '${category.icon}'.`);
|
||||
error = true;
|
||||
}
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw new Error('At least one error in icons.json prevents from committing changes.');
|
||||
throw new Error('At least one error in icon JSONs prevents from committing changes.');
|
||||
}
|
||||
|
||||
@@ -70,6 +70,30 @@ export const appendFile = (content, fileName, outputDirectory) =>
|
||||
export const writeFile = (content, fileName, outputDirectory) =>
|
||||
fs.writeFileSync(path.join(outputDirectory, fileName), content, 'utf-8');
|
||||
|
||||
/**
|
||||
* Reads metadata from the icons/categories directories
|
||||
*
|
||||
* @param {string} directory
|
||||
* @returns {object} A map of icon or category metadata
|
||||
*/
|
||||
export const readAllMetadata = (directory) =>
|
||||
fs.readdirSync(directory).filter((file) => path.extname(file) === '.json').reduce(
|
||||
(acc, fileName, i) => {
|
||||
acc[path.basename(fileName, '.json')] = readMetadata(fileName, directory);
|
||||
return acc;
|
||||
}, {}
|
||||
);
|
||||
|
||||
/**
|
||||
* Reads metadata for an icon or category
|
||||
*
|
||||
* @param {string} fileName
|
||||
* @param {string} directory
|
||||
* @returns {object} The metadata for the icon or category
|
||||
*/
|
||||
export const readMetadata = (fileName, directory) =>
|
||||
JSON.parse(fs.readFileSync(path.join(directory, fileName), 'utf-8'));
|
||||
|
||||
/**
|
||||
* reads the icon directory
|
||||
*
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
import path from 'path';
|
||||
import icons from '../icons.json' assert { type: 'json' };
|
||||
import categories from '../categories.json' assert { type: 'json' };
|
||||
import { mergeArrays, writeFile, getCurrentDirPath } from './helpers.mjs';
|
||||
import { mergeArrays, writeFile, readAllMetadata, getCurrentDirPath } from './helpers.mjs';
|
||||
|
||||
const currentDir = getCurrentDirPath(import.meta.url)
|
||||
const ICONS_DIR = path.resolve(currentDir, '../icons');
|
||||
const icons = readAllMetadata(ICONS_DIR);
|
||||
|
||||
Object.keys(categories).forEach(categoryName => {
|
||||
categories[categoryName].forEach(iconName => {
|
||||
mergeArrays(icons.icons[iconName].categories, [categoryName]);
|
||||
icons[iconName].categories = mergeArrays(icons[iconName].categories, [categoryName]);
|
||||
});
|
||||
});
|
||||
|
||||
const iconsContent = JSON.stringify(icons, null, 2);
|
||||
Object.keys(icons).forEach(iconName => {
|
||||
const iconContent = JSON.stringify(icons[iconName], null, 2);
|
||||
writeFile(iconContent, `${iconName}.json`, path.resolve(currentDir, '../icons'));
|
||||
})
|
||||
|
||||
writeFile(iconsContent, 'icons.json', path.resolve(currentDir, '..'));
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import path from 'path';
|
||||
import icons from '../icons.json' assert { type: 'json' };
|
||||
import { writeFile, getCurrentDirPath } from './helpers.mjs';
|
||||
import { writeFile, getCurrentDirPath, readAllMetadata } from './helpers.mjs';
|
||||
|
||||
const currentDir = getCurrentDirPath(import.meta.url)
|
||||
const ICONS_DIR = path.resolve(currentDir, '../icons');
|
||||
const icons = readAllMetadata(ICONS_DIR);
|
||||
|
||||
const newCategories = {};
|
||||
Object.keys(icons.icons).forEach(iconName => {
|
||||
icons.icons[iconName].categories.forEach(categoryName => {
|
||||
Object.keys(icons).forEach(iconName => {
|
||||
icons[iconName].categories.forEach(categoryName => {
|
||||
newCategories[categoryName] = newCategories[categoryName] || [];
|
||||
newCategories[categoryName].push(iconName);
|
||||
});
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
import path from 'path';
|
||||
import icons from '../icons.json' assert { type: 'json' };
|
||||
import { writeFile, getCurrentDirPath } from './helpers.mjs';
|
||||
|
||||
const currentDir = getCurrentDirPath(import.meta.url)
|
||||
|
||||
Object.keys(icons.icons).forEach(iconName => {
|
||||
const icon = {
|
||||
"$schema": "../icon.schema.json",
|
||||
...icons.icons[iconName]
|
||||
};
|
||||
const iconContent = JSON.stringify(icon, null, 2);
|
||||
writeFile(iconContent, 'icons/'+iconName+'.json', path.resolve(currentDir, '..'));
|
||||
});
|
||||
|
||||
Object.keys(icons.categories).forEach(categoryName => {
|
||||
const category = {
|
||||
"$schema": "../category.schema.json",
|
||||
...icons.categories[categoryName]
|
||||
};
|
||||
const categoryContent = JSON.stringify(category, null, 2);
|
||||
writeFile(categoryContent, 'categories/'+categoryName+'.json', path.resolve(currentDir, '..'));
|
||||
});
|
||||
@@ -1,44 +1,17 @@
|
||||
import path from 'path';
|
||||
import tags from '../tags.json' assert { type: 'json' };
|
||||
import icons from '../icons.json' assert { type: 'json' };
|
||||
import { readSvgDirectory, writeFile, mergeArrays, getCurrentDirPath } from './helpers.mjs';
|
||||
import { writeFile, getCurrentDirPath, readAllMetadata } from './helpers.mjs';
|
||||
|
||||
const currentDir = getCurrentDirPath(import.meta.url)
|
||||
const currentDir = getCurrentDirPath(import.meta.url);
|
||||
const ICONS_DIR = path.resolve(currentDir, '../icons');
|
||||
const icons = readAllMetadata(ICONS_DIR);
|
||||
|
||||
console.log(`Read all icons`);
|
||||
|
||||
const svgFiles = readSvgDirectory(ICONS_DIR);
|
||||
|
||||
const iconNames = svgFiles.map(icon => icon.split('.')[0]);
|
||||
|
||||
const iconList = iconNames
|
||||
.map(iconName => ({
|
||||
name: iconName,
|
||||
icon: icons.icons[iconName] || { tags: [] },
|
||||
tags: tags[iconName] || [],
|
||||
}))
|
||||
.sort((a, b) => {
|
||||
const nameA = a.name;
|
||||
const nameB = b.name;
|
||||
|
||||
if (nameA < nameB) {
|
||||
return -1;
|
||||
}
|
||||
if (nameA > nameB) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// names must be equal
|
||||
return 0;
|
||||
});
|
||||
|
||||
const newTags = iconList.reduce((acc, { name, icon, tags }) => {
|
||||
acc[name] = mergeArrays(icon.tags, tags);
|
||||
|
||||
const tags = Object.keys(icons)
|
||||
.sort()
|
||||
.reduce((acc, iconName) => {
|
||||
acc[iconName] = icons[iconName].tags;
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
const tagsContent = JSON.stringify(newTags, null, 2);
|
||||
const tagsContent = JSON.stringify(tags, null, 2);
|
||||
|
||||
writeFile(tagsContent, 'tags.json', path.resolve(currentDir, '..'));
|
||||
writeFile(tagsContent, 'tags.json', path.resolve(process.cwd()));
|
||||
|
||||
@@ -1,47 +1,21 @@
|
||||
import path from 'path';
|
||||
import tags from '../tags.json' assert { type: 'json' };
|
||||
import icons from '../icons.json' assert { type: 'json' };
|
||||
import { readSvgDirectory, writeFile, mergeArrays, getCurrentDirPath } from './helpers.mjs';
|
||||
import { readSvgDirectory, readAllMetadata, writeFile, mergeArrays, getCurrentDirPath } from './helpers.mjs';
|
||||
|
||||
const currentDir = getCurrentDirPath(import.meta.url)
|
||||
const ICONS_DIR = path.resolve(currentDir, '../icons');
|
||||
|
||||
console.log(`Read all icons`);
|
||||
|
||||
const icons = readAllMetadata(ICONS_DIR);
|
||||
const svgFiles = readSvgDirectory(ICONS_DIR);
|
||||
|
||||
const iconNames = svgFiles.map(icon => icon.split('.')[0]);
|
||||
const iconNames = svgFiles.map((icon) => icon.split('.')[0]);
|
||||
|
||||
const iconList = iconNames
|
||||
.map(iconName => ({
|
||||
name: iconName,
|
||||
icon: icons.icons[iconName] || { tags: [], categories: [] },
|
||||
tags: tags[iconName] || [],
|
||||
}))
|
||||
.sort((a, b) => {
|
||||
const nameA = a.name;
|
||||
const nameB = b.name;
|
||||
|
||||
if (nameA < nameB) {
|
||||
return -1;
|
||||
}
|
||||
if (nameA > nameB) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// names must be equal
|
||||
return 0;
|
||||
});
|
||||
|
||||
const newIcons = icons;
|
||||
|
||||
newIcons.icons = iconList.reduce((acc, { name, icon, tags }) => {
|
||||
acc[name] = icon;
|
||||
acc[name].tags = mergeArrays(icon.tags, tags);
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
const iconsContent = JSON.stringify(newIcons, null, 2);
|
||||
|
||||
writeFile(iconsContent, 'icons.json', path.resolve(currentDir, '..'));
|
||||
iconNames.forEach(iconName => {
|
||||
icons[iconName] = icons[iconName] || {
|
||||
"$schema": "../icon.schema.json",
|
||||
"tags": [],
|
||||
"categories": []
|
||||
};
|
||||
icons[iconName].tags = mergeArrays(icons[iconName].tags, tags[iconName]);
|
||||
const iconContent = JSON.stringify(icons[iconName], null, 2);
|
||||
writeFile(iconContent, `${iconName}.json`, path.resolve(currentDir, '../icons'));
|
||||
})
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
{
|
||||
"name": "@lucide/site",
|
||||
"private": true,
|
||||
"name": "site",
|
||||
"version": "1.0.0",
|
||||
"author": "John Letey",
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"copy-assets": "mkdir -p ./public/docs/images && cp -rf ../docs/images ./public/docs",
|
||||
"build": "pnpm copy-assets && next build",
|
||||
"prebuild": "ts-node scripts/preBuild.tsx",
|
||||
"build": "pnpm copy-assets && pnpm prebuild && next build",
|
||||
"export": "next export -o build",
|
||||
"deploy": "pnpm build && pnpm export",
|
||||
"lint": "eslint .",
|
||||
@@ -36,7 +37,8 @@
|
||||
"react": "17.0.2",
|
||||
"react-color": "^2.19.3",
|
||||
"react-dom": "17.0.2",
|
||||
"react-svg-loader": "^3.0.3"
|
||||
"react-svg-loader": "^3.0.3",
|
||||
"svgson": "^5.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@next/eslint-plugin-next": "^12.2.5",
|
||||
@@ -57,6 +59,8 @@
|
||||
"jest": "^26.5.2",
|
||||
"prettier": "^2.3.2",
|
||||
"react-test-renderer": "17.0.2",
|
||||
"ts-node": "~10.9.1",
|
||||
"tslib": "^2.4.0",
|
||||
"typescript": "^4.3.5"
|
||||
}
|
||||
}
|
||||
|
||||
17
site/scripts/preBuild.tsx
Normal file
17
site/scripts/preBuild.tsx
Normal file
@@ -0,0 +1,17 @@
|
||||
import {fetchTags} from "../src/lib/fetchTags";
|
||||
import {fetchIconNodes} from "../src/lib/fetchIconNodes";
|
||||
import NextCache from "../src/lib/nextCache";
|
||||
|
||||
const clearCache = async () => {
|
||||
await NextCache.clear('api-tags', 'api-icon-nodes')
|
||||
}
|
||||
|
||||
const buildCache = async () => {
|
||||
await Promise.all([fetchTags(), fetchIconNodes()])
|
||||
}
|
||||
|
||||
const rebuildCache = async () => {
|
||||
await Promise.all([clearCache(), buildCache()])
|
||||
}
|
||||
|
||||
rebuildCache().then(() => null)
|
||||
@@ -40,7 +40,6 @@ const Header = ({ data }: HeaderProps) => {
|
||||
const { iconsRef } = useCustomizeIconContext();
|
||||
|
||||
const downloadAllIcons = async () => {
|
||||
console.log(iconsRef);
|
||||
setZippingIcons(true);
|
||||
|
||||
let iconEntries: IconContent[] = Object.entries(iconsRef.current).map(([name, svgEl]) => [
|
||||
|
||||
15
site/src/lib/fetchIconNodes.tsx
Normal file
15
site/src/lib/fetchIconNodes.tsx
Normal file
@@ -0,0 +1,15 @@
|
||||
import NextCache from './nextCache';
|
||||
import {parseSync} from 'svgson';
|
||||
import {getAllData} from './icons';
|
||||
|
||||
export type IconNode = [string, object, IconNode[]];
|
||||
export type IconNodes = {[iconName: string]: IconNode};
|
||||
|
||||
export function fetchIconNodes(writeCache = true): Promise<IconNodes> {
|
||||
return NextCache.resolve('api-icon-nodes', async () => {
|
||||
return (await getAllData()).reduce((acc, icon) => {
|
||||
acc[icon.name] = parseSync(icon.src).children.map(({name, attributes}) => [name, attributes]);
|
||||
return acc;
|
||||
}, {});
|
||||
}, writeCache);
|
||||
}
|
||||
13
site/src/lib/fetchTags.tsx
Normal file
13
site/src/lib/fetchTags.tsx
Normal file
@@ -0,0 +1,13 @@
|
||||
import NextCache from './nextCache';
|
||||
import {getAllData} from './icons';
|
||||
|
||||
export type Tags = {[iconName: string]: string[]};
|
||||
|
||||
export function fetchTags(writeCache = true): Promise<Tags> {
|
||||
return NextCache.resolve('api-tags', async () => {
|
||||
return (await getAllData()).reduce((acc, icon) => {
|
||||
acc[icon.name] = icon.tags;
|
||||
return acc;
|
||||
}, {});
|
||||
}, writeCache);
|
||||
}
|
||||
@@ -1,31 +1,32 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { parseSync } from 'svgson';
|
||||
import tags from '../../../tags.json';
|
||||
import { IconEntity } from "../types";
|
||||
import { getContributors } from "./fetchAllContributors";
|
||||
|
||||
const directory = path.join(process.cwd(), "../icons");
|
||||
|
||||
export function getAllNames() {
|
||||
const fileNames = fs.readdirSync(directory).filter((file) => path.extname(file) === '.svg');
|
||||
const fileNames = fs.readdirSync(directory).filter((file) => path.extname(file) === '.json');
|
||||
|
||||
return fileNames.map((fileName) => {
|
||||
return fileName.replace(/\.svg$/, "");
|
||||
});
|
||||
return fileNames
|
||||
.filter((fileName) => fs.existsSync(directory + '/' + path.basename(fileName, '.json') + '.svg'))
|
||||
.map((fileName) => path.basename(fileName, '.json'));
|
||||
}
|
||||
|
||||
export async function getData(name: string) {
|
||||
const fullPath = path.join(directory, `${name}.svg`);
|
||||
const fileContent = fs.readFileSync(fullPath, "utf8");
|
||||
const svgPath = path.join(directory, `${name}.svg`);
|
||||
const svgContent = fs.readFileSync(svgPath, "utf8");
|
||||
const jsonPath = path.join(directory, `${name}.json`);
|
||||
const jsonContent = fs.readFileSync(jsonPath, "utf8");
|
||||
const iconJson = JSON.parse(jsonContent);
|
||||
|
||||
const contributors = await getContributors(name);
|
||||
|
||||
return {
|
||||
...iconJson,
|
||||
name,
|
||||
tags: tags[name] || [],
|
||||
contributors,
|
||||
src: fileContent
|
||||
src: svgContent
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
53
site/src/lib/nextCache.tsx
Normal file
53
site/src/lib/nextCache.tsx
Normal file
@@ -0,0 +1,53 @@
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
|
||||
const cacheDir = path.join(process.cwd(), '.next/cache');
|
||||
const cachePath = (cacheKey: string) => path.join(cacheDir, `${cacheKey}.json`);
|
||||
|
||||
type AtomicCacheable = object|string|number|boolean|null;
|
||||
type Cacheable = AtomicCacheable|AtomicCacheable[];
|
||||
|
||||
function read<T extends Cacheable>(cacheKey: string): T {
|
||||
if (fs.existsSync(cachePath(cacheKey))) {
|
||||
const iconCache = fs.readFileSync(cachePath(cacheKey), "utf8")
|
||||
return JSON.parse(iconCache)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
function write<T extends Cacheable>(cacheKey: string, content: T): void {
|
||||
if (!fs.existsSync(cacheDir)) {
|
||||
fs.mkdirSync(cacheDir)
|
||||
}
|
||||
|
||||
fs.writeFileSync(cachePath(cacheKey), JSON.stringify(content), 'utf-8')
|
||||
}
|
||||
|
||||
function clear(...cacheKeys: string[]) {
|
||||
for (const cacheKey of cacheKeys) {
|
||||
const itemCachePath = cachePath(cacheKey)
|
||||
if (fs.existsSync(itemCachePath)) {
|
||||
fs.unlinkSync(itemCachePath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function resolve<T extends Cacheable>(cacheKey: string, contentResolver: () => Promise<T>|T, writeCache = true): Promise<T> {
|
||||
try {
|
||||
let cacheItem = await read<T>(cacheKey)
|
||||
if (cacheItem === null) {
|
||||
cacheItem = await contentResolver()
|
||||
if (writeCache) {
|
||||
write(cacheKey, cacheItem)
|
||||
}
|
||||
}
|
||||
return cacheItem;
|
||||
} catch (error) {
|
||||
throw new Error(error)
|
||||
}
|
||||
}
|
||||
|
||||
const NextCache = {read, write, resolve, clear}
|
||||
|
||||
export default NextCache
|
||||
8
site/src/pages/api/icon-nodes/index.tsx
Normal file
8
site/src/pages/api/icon-nodes/index.tsx
Normal file
@@ -0,0 +1,8 @@
|
||||
import {fetchIconNodes} from '../../../lib/fetchIconNodes';
|
||||
|
||||
export default async function handler(req, res) {
|
||||
res.setHeader(
|
||||
'Cache-Control',
|
||||
'public, max-age=86400'
|
||||
).status(200).json(await fetchIconNodes(false));
|
||||
}
|
||||
8
site/src/pages/api/tags/index.tsx
Normal file
8
site/src/pages/api/tags/index.tsx
Normal file
@@ -0,0 +1,8 @@
|
||||
import {fetchTags} from '../../../lib/fetchTags';
|
||||
|
||||
export default async function handler(req, res) {
|
||||
res.setHeader(
|
||||
'Cache-Control',
|
||||
'public, max-age=86400'
|
||||
).status(200).json(await fetchTags(false));
|
||||
}
|
||||
@@ -1,4 +1,9 @@
|
||||
{
|
||||
"ts-node": {
|
||||
"compilerOptions": {
|
||||
"module": "commonjs"
|
||||
}
|
||||
},
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
"lib": [
|
||||
|
||||
Reference in New Issue
Block a user