mirror of
https://github.com/lucide-icons/lucide.git
synced 2026-11-10 13:18:25 +00:00
ci(lint): split lint jobs and annotate Prettier and JSON schema errors in PRs (#4982)
* ci: split lint-code into ESLint, Prettier and JSON Schema jobs with PR annotations - ESLint: annotations via setup-node's built-in eslint-stylish problem matcher. - Prettier: new scripts/lintFormat.mts formats unformatted files in memory, diffs them and emits line-level `::error` annotations with the expected code. - JSON Schema: replace ajv-cli with a local ESLint rule (Ajv draft 2020-12) that validates icons/categories JSON against their `$schema` and reports at the offending property. eslint-plugin-json-schema-validator was not used because it runs Ajv in draft-07 mode and ignores `dependentRequired`. All annotations use workflow commands, so they work on fork PRs with a read-only token. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FVxEtqNswEDq1N23taZYh8 * Improve root value check and property error handling Enhance error reporting for JSON schema validation. Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * style(lint): format jsonSchemaPlugin with Prettier Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FVxEtqNswEDq1N23taZYh8 * test commit * fix(lint): annotate syntax errors from Prettier and ESLint in PRs - ESLint/JSON Schema jobs use a small GitHub formatter that prints `::error` workflow commands. setup-node's eslint-stylish matcher skipped parsing errors because they have no rule id. - lintFormat.mts annotates Prettier syntax errors (exit code 2) at their line and column instead of only printing stderr, and still checks the other files. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FVxEtqNswEDq1N23taZYh8 * ci(lint): spell check icon and category metadata with cspell annotations - New "Spelling" job runs scripts/lintSpelling.mts, which turns cspell findings into `::error` annotations (with cspell's suggested fix when it has one). - cspell accepts both US and British English, ignores contributor usernames and deprecated `alias.typo` aliases. - Add existing search tags and domain terms to .cspell/custom-words.txt so the current metadata passes. - Add `lint:spelling` to `pnpm lint` and lint-staged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FVxEtqNswEDq1N23taZYh8 * fix(lint): pin JSON schemas per file set and drop typo tags - json-schema/no-invalid now takes the schema from config (icon.schema.json for icons, category.schema.json for categories) and reports a `$schema` that points elsewhere, so metadata can't opt out of validation. - Remove the misspelled `frigerator` and `sterisk` tags and their allowlist entries. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FVxEtqNswEDq1N23taZYh8 * fix(icons): split joined-word tags into separate words Tags like `groupchat` and `timemachine` become `group chat` and `time machine` so they read naturally and pass the spell check without allowlisting. Where the spaced tag already existed (`smart home`) the joined one is dropped. cspell now skips all alias names, since they are icon names that can't change (e.g. the deprecated `palmtree` alias). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FVxEtqNswEDq1N23taZYh8 * Revert * Try another error * Revert error --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
Copilot Autofix powered by AI
parent
62c584a5f2
commit
55b9969b82
@@ -11,3 +11,42 @@ ungroup
|
||||
toc
|
||||
sunlounger
|
||||
monstera
|
||||
|
||||
# Search tags and terms used in icon and category metadata
|
||||
ageusia
|
||||
artboard
|
||||
barbeque
|
||||
choy
|
||||
ecommerce
|
||||
enby
|
||||
flexbox
|
||||
futbol
|
||||
gddr
|
||||
glassmorphism
|
||||
gltf
|
||||
interpoint
|
||||
interpunct
|
||||
middot
|
||||
mistwarp
|
||||
moleskine
|
||||
nonbinary
|
||||
pantone
|
||||
phonendoscope
|
||||
quadcopter
|
||||
reapproval
|
||||
rubygems
|
||||
showreel
|
||||
solera
|
||||
timesheets
|
||||
turbowarp
|
||||
unbook
|
||||
unguard
|
||||
unkeys
|
||||
unlabel
|
||||
unprevented
|
||||
unqueue
|
||||
unsalvageable
|
||||
unshield
|
||||
unstar
|
||||
vitamizer
|
||||
wayfinding
|
||||
|
||||
@@ -7,7 +7,8 @@ permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
lint-code:
|
||||
eslint:
|
||||
name: ESLint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
@@ -20,5 +21,57 @@ jobs:
|
||||
- name: Install Dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Run Linter
|
||||
run: pnpm lint
|
||||
# The formatter prints workflow commands, which GitHub shows as inline annotations.
|
||||
- name: Run ESLint
|
||||
run: pnpm lint:es --format ./scripts/eslint/githubFormatter.mjs
|
||||
|
||||
prettier:
|
||||
name: Prettier
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
|
||||
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||
with:
|
||||
cache: 'pnpm'
|
||||
node-version-file: 'package.json'
|
||||
|
||||
- name: Install Dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Check formatting
|
||||
run: pnpm lint:format:ci
|
||||
|
||||
json-schema:
|
||||
name: JSON Schema
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
|
||||
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||
with:
|
||||
cache: 'pnpm'
|
||||
node-version-file: 'package.json'
|
||||
|
||||
- name: Install Dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Validate icon and category JSON
|
||||
run: pnpm lint:json --format ./scripts/eslint/githubFormatter.mjs
|
||||
|
||||
spelling:
|
||||
name: Spelling
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
|
||||
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||
with:
|
||||
cache: 'pnpm'
|
||||
node-version-file: 'package.json'
|
||||
|
||||
- name: Install Dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Spell check icon and category metadata
|
||||
run: pnpm lint:spelling:ci
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"language": "en,en-GB",
|
||||
"dictionaries": ["en-us", "custom-words"],
|
||||
"dictionaryDefinitions": [
|
||||
{
|
||||
@@ -6,5 +7,9 @@
|
||||
"path": "./.cspell/custom-words.txt",
|
||||
"addWords": true
|
||||
}
|
||||
],
|
||||
"ignoreRegExpList": [
|
||||
"/\"contributors\"\\s*:\\s*\\[[^\\]]*\\]/g",
|
||||
"/\"name\"\\s*:\\s*\"[^\"]*\"/g"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ import htmlEslint from '@html-eslint/eslint-plugin';
|
||||
import htmlParser from '@html-eslint/parser';
|
||||
import defaultAttrs from './tools/build-icons/render/default-attrs.json' with { type: 'json' };
|
||||
import tseslint from 'typescript-eslint';
|
||||
import jsonSchema from './scripts/eslint/jsonSchemaPlugin.mjs';
|
||||
import * as jsoncParser from 'jsonc-eslint-parser';
|
||||
|
||||
const gitignorePath = path.join(import.meta.dirname, '.gitignore');
|
||||
|
||||
@@ -152,4 +154,25 @@ export default defineConfig([
|
||||
'@html-eslint/quotes': 'error',
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['icons/*.json', 'categories/*.json'],
|
||||
languageOptions: {
|
||||
parser: jsoncParser,
|
||||
},
|
||||
plugins: {
|
||||
'json-schema': jsonSchema,
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['icons/*.json'],
|
||||
rules: {
|
||||
'json-schema/no-invalid': ['error', { schema: 'icon.schema.json' }],
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['categories/*.json'],
|
||||
rules: {
|
||||
'json-schema/no-invalid': ['error', { schema: 'category.schema.json' }],
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
"use-cases": [],
|
||||
"tags": [
|
||||
"symbol",
|
||||
"sterisk",
|
||||
"mark",
|
||||
"pointer",
|
||||
"pencil",
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"payment",
|
||||
"bdt",
|
||||
"৳",
|
||||
"currencysymbol",
|
||||
"currency symbol",
|
||||
"cash",
|
||||
"banknote",
|
||||
"price",
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
"startup",
|
||||
"registration",
|
||||
"onboarding",
|
||||
"realestate",
|
||||
"real estate",
|
||||
"property"
|
||||
],
|
||||
"categories": [
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"tags": [
|
||||
"battery",
|
||||
"automobile",
|
||||
"powercell",
|
||||
"power cell",
|
||||
"electric",
|
||||
"power",
|
||||
"electricity",
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
"bytes",
|
||||
"servers",
|
||||
"backup",
|
||||
"timemachine",
|
||||
"time machine",
|
||||
"rotate",
|
||||
"synchronize",
|
||||
"synchronise",
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
"bytes",
|
||||
"servers",
|
||||
"backup",
|
||||
"timemachine",
|
||||
"time machine",
|
||||
"rotate",
|
||||
"arrow",
|
||||
"left"
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
"nautical",
|
||||
"harbor",
|
||||
"shore",
|
||||
"lightbeam",
|
||||
"light beam",
|
||||
"wayfinding",
|
||||
"guidance",
|
||||
"onboarding",
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
"unread",
|
||||
"scheduled",
|
||||
"delayed",
|
||||
"sendlater",
|
||||
"send later",
|
||||
"delivery",
|
||||
"reminder",
|
||||
"pending",
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
"interview",
|
||||
"debate",
|
||||
"group",
|
||||
"groupchat",
|
||||
"group chat",
|
||||
"threads",
|
||||
"unread",
|
||||
"bubble",
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"eco-friendly",
|
||||
"kraft",
|
||||
"retail",
|
||||
"doggybag"
|
||||
"doggy bag"
|
||||
],
|
||||
"categories": [
|
||||
"food-beverage",
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
],
|
||||
"use-cases": [],
|
||||
"tags": [
|
||||
"frigerator",
|
||||
"fridge",
|
||||
"freezer",
|
||||
"cooler",
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
"housekeeping",
|
||||
"tool",
|
||||
"maintenance",
|
||||
"smarthome",
|
||||
"sweeping",
|
||||
"hygiene",
|
||||
"chores",
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"tags": [
|
||||
"barcode",
|
||||
"scan",
|
||||
"qrcode",
|
||||
"qr code",
|
||||
"url",
|
||||
"information",
|
||||
"digital",
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@
|
||||
"beach",
|
||||
"sand",
|
||||
"holiday",
|
||||
"sealife",
|
||||
"sea life",
|
||||
"fossil",
|
||||
"ammonite",
|
||||
"biology",
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
"admin",
|
||||
"verification",
|
||||
"crest",
|
||||
"shieldcog",
|
||||
"shield cog",
|
||||
"bravery",
|
||||
"knight",
|
||||
"foot soldier",
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
"performance",
|
||||
"lens",
|
||||
"leaderboard",
|
||||
"followspot",
|
||||
"follow spot",
|
||||
"best",
|
||||
"highlight"
|
||||
],
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
"handle",
|
||||
"plaque",
|
||||
"toothpaste",
|
||||
"selfcare",
|
||||
"self care",
|
||||
"grooming",
|
||||
"fresh",
|
||||
"clean"
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
"handle",
|
||||
"plaque",
|
||||
"toothpaste",
|
||||
"selfcare",
|
||||
"self care",
|
||||
"grooming"
|
||||
],
|
||||
"categories": [
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
],
|
||||
"use-cases": [],
|
||||
"tags": [
|
||||
"flatscreen",
|
||||
"flat screen",
|
||||
"television",
|
||||
"stream",
|
||||
"display",
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
],
|
||||
"use-cases": [],
|
||||
"tags": [
|
||||
"flatscreen",
|
||||
"flat screen",
|
||||
"television",
|
||||
"stream",
|
||||
"display",
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
/**
|
||||
* @param {string[]} filenames
|
||||
* @returns {string}
|
||||
*/
|
||||
const filenamesToAjvOption = (filenames) => filenames.map((filename) => `-d ${filename}`).join(' ');
|
||||
|
||||
/** @satisfies {import('lint-staged').Config} */
|
||||
const config = {
|
||||
'icons/*.svg': (filenames) => [
|
||||
@@ -12,11 +6,13 @@ const config = {
|
||||
`prettier --write ${filenames.join(' ')}`,
|
||||
],
|
||||
'icons/*.json': (filenames) => [
|
||||
`ajv --spec=draft2020 -s icon.schema.json ${filenamesToAjvOption(filenames)}`,
|
||||
`eslint ${filenames.join(' ')}`,
|
||||
`cspell --no-progress ${filenames.join(' ')}`,
|
||||
`prettier --write ${filenames.join(' ')}`,
|
||||
],
|
||||
'categories/*.json': (filenames) => [
|
||||
`ajv --spec=draft2020 -s category.schema.json ${filenamesToAjvOption(filenames)}`,
|
||||
`eslint ${filenames.join(' ')}`,
|
||||
`cspell --no-progress ${filenames.join(' ')}`,
|
||||
`prettier --write ${filenames.join(' ')}`,
|
||||
],
|
||||
};
|
||||
|
||||
+10
-6
@@ -34,16 +34,19 @@
|
||||
"suggest:metadata:debug": "node --env-file .env ./scripts/suggestMetaData.mts --debug",
|
||||
"suggest:metadata:watch": "node --env-file .env --watch ./scripts/suggestMetaData.mts",
|
||||
"postinstall": "husky",
|
||||
"lint:es": "eslint .",
|
||||
"lint:es": "eslint . --ignore-pattern 'icons/*.json' --ignore-pattern 'categories/*.json'",
|
||||
"lint:format": "prettier \"**/*.{js,mjs,ts,jsx,tsx,html,css,scss,json,yml,yaml}\" --check",
|
||||
"lint:format-fix": "prettier \"**/*.{js,mjs,ts,jsx,tsx,html,css,scss,json,yml,yaml}\" --write",
|
||||
"lint:icons": "prettier \"icons/*.svg\" --check",
|
||||
"lint:icons-fix": "prettier \"icons/*.svg\" --write",
|
||||
"lint:json:icons": "ajv --spec=draft2020 -s icon.schema.json -d 'icons/*.json' > /dev/null",
|
||||
"lint:json:categories": "ajv --spec=draft2020 -s category.schema.json -d 'categories/*.json' > /dev/null",
|
||||
"lint:json": "pnpm run lint:json:icons && pnpm run lint:json:categories",
|
||||
"lint:format:ci": "node ./scripts/lintFormat.mts",
|
||||
"lint:json:icons": "eslint 'icons/*.json'",
|
||||
"lint:json:categories": "eslint 'categories/*.json'",
|
||||
"lint:json": "eslint 'icons/*.json' 'categories/*.json'",
|
||||
"lint:spelling": "cspell --no-progress 'icons/*.json' 'categories/*.json'",
|
||||
"lint:spelling:ci": "node ./scripts/lintSpelling.mts",
|
||||
"lint:icons:all": "pnpm run lint:icons && pnpm run lint:json:icons",
|
||||
"lint": "pnpm lint:es && pnpm lint:format && pnpm lint:json && pnpm lint:icons",
|
||||
"lint": "pnpm lint:es && pnpm lint:format && pnpm lint:json && pnpm lint:spelling && pnpm lint:icons",
|
||||
"format": "prettier \"**/*.{js,mjs,ts,jsx,tsx,html,css,scss,json,yml,yaml}\" --write",
|
||||
"prepare": "husky",
|
||||
"gi": "node ./scripts/generate/generateIcons.mts",
|
||||
@@ -63,7 +66,7 @@
|
||||
"@typescript-eslint/parser": "^8.69.0",
|
||||
"@vitest/coverage-v8": "5.0.3",
|
||||
"@vitest/ui": "5.0.3",
|
||||
"ajv-cli": "^5.0.0",
|
||||
"ajv": "^8.20.0",
|
||||
"cpy-cli": "^7.0.0",
|
||||
"cspell": "^10.2.0",
|
||||
"dotenv": "^17.4.2",
|
||||
@@ -72,6 +75,7 @@
|
||||
"eslint-plugin-import-x": "^4.17.1",
|
||||
"husky": "^9.1.7",
|
||||
"jsdom": "^30.0.1",
|
||||
"jsonc-eslint-parser": "^3.3.0",
|
||||
"lint-staged": "^17.4.1",
|
||||
"minimist": "^1.2.8",
|
||||
"openai": "^7.9.0",
|
||||
|
||||
Generated
+16
-316
@@ -56,9 +56,9 @@ importers:
|
||||
'@vitest/ui':
|
||||
specifier: 5.0.3
|
||||
version: 5.0.3(vitest@5.0.3)
|
||||
ajv-cli:
|
||||
specifier: ^5.0.0
|
||||
version: 5.0.0(ts-node@10.9.2(@swc/core@1.7.23(@swc/helpers@0.5.23))(@types/node@26.4.1)(typescript@6.0.3))
|
||||
ajv:
|
||||
specifier: ^8.20.0
|
||||
version: 8.20.0
|
||||
cpy-cli:
|
||||
specifier: ^7.0.0
|
||||
version: 7.0.0
|
||||
@@ -83,6 +83,9 @@ importers:
|
||||
jsdom:
|
||||
specifier: ^30.0.1
|
||||
version: 30.0.1
|
||||
jsonc-eslint-parser:
|
||||
specifier: ^3.3.0
|
||||
version: 3.3.0
|
||||
lint-staged:
|
||||
specifier: ^17.4.1
|
||||
version: 17.4.1
|
||||
@@ -2816,10 +2819,6 @@ packages:
|
||||
resolution: {integrity: sha512-TIgG/pCkgo3SiayAbV0CorYPdnaNkYWfJFKHhSBTKIdBDwK4YwcbbDlXWGCTJ6gxhhwnrNhcw4jDjz8jejKS4A==}
|
||||
engines: {node: '>=22.18.0'}
|
||||
|
||||
'@cspotcode/source-map-support@0.8.1':
|
||||
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
'@csstools/color-helpers@6.1.1':
|
||||
resolution: {integrity: sha512-gLNsunvwf3mCi5u5o46/Z/JcJMnhbHSaZ69rkgPzNM3J4s8hWwpPUQB6/tt0EDFyCiWzxANlx+2LJwpYj4zS1w==}
|
||||
engines: {node: '>=20.19.0'}
|
||||
@@ -3767,9 +3766,6 @@ packages:
|
||||
'@jridgewell/trace-mapping@0.3.31':
|
||||
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
|
||||
|
||||
'@jridgewell/trace-mapping@0.3.9':
|
||||
resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
|
||||
|
||||
'@kwsites/file-exists@1.1.1':
|
||||
resolution: {integrity: sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==}
|
||||
|
||||
@@ -5729,88 +5725,9 @@ packages:
|
||||
svelte: ^5.46.4
|
||||
vite: ^8.3.2
|
||||
|
||||
'@swc/core-darwin-arm64@1.7.23':
|
||||
resolution: {integrity: sha512-yyOHPfti6yKlQulfVWMt7BVKst+SyEZYCWuQSGMn1KgmNCH/bYufRWfQXIhkGSj44ZkEepJmsJ8tDyIb4k5WyA==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@swc/core-darwin-x64@1.7.23':
|
||||
resolution: {integrity: sha512-GzqHwQ0Y1VyjdI/bBKFX2GKm5HD3PIB6OhuAQtWZMTtEr2yIrlT0YK2T+XKh7oIg31JwxGBeQdBk3KTI7DARmQ==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@swc/core-linux-arm-gnueabihf@1.7.23':
|
||||
resolution: {integrity: sha512-qwX4gB41OS6/OZkHcpTqLFGsdmvoZyffnJIlgB/kZKwH3lfeJWzv6vx57zXtNpM/t7GoQEe0VZUVdmNjxSxBZw==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@swc/core-linux-arm64-gnu@1.7.23':
|
||||
resolution: {integrity: sha512-TsrbUZdMaUwzI7+g/8rHPLWbntMKYSu5Bn5IBSqVKPeyqaXxNnlIUnWXgXcUcRAc+T+Y8ADfr7EiFz9iz5DuSA==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@swc/core-linux-arm64-musl@1.7.23':
|
||||
resolution: {integrity: sha512-JEdtwdthazKq4PBz53KSubwwK8MvqODAihGSAzc8u3Unq4ojcvaS8b0CwLBeD+kTQ78HpxOXTt3DsFIxpgaCAA==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@swc/core-linux-x64-gnu@1.7.23':
|
||||
resolution: {integrity: sha512-V51gFPWaVAHbI1yg9ahsoya3aB4uawye3SZ5uQWgcP7wdCdiv60dw4F5nuPJf5Z1oXD3U/BslXuamv8Oh9vXqQ==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@swc/core-linux-x64-musl@1.7.23':
|
||||
resolution: {integrity: sha512-BBqQi4+UdeRqag3yM4IJjaHG4yc1o3l9ksENHToE0o/u2DT0FY5+K/DiYGZLC1JHbSFzNqRCYsa7DIzRtZ0A1A==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@swc/core-win32-arm64-msvc@1.7.23':
|
||||
resolution: {integrity: sha512-JPk6pvCKncL6bXG7p+NLZf8PWx4FakVvKNdwGeMrYunb+yk1IZf7qf9LJk8+GDGF5QviDXPs8opZrTrfsW80fA==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@swc/core-win32-ia32-msvc@1.7.23':
|
||||
resolution: {integrity: sha512-2Whxi8d+bLQBzJcQ5qYPHlk02YYVGsMVav0fWk+FnX2z1QRREIu1L1xvrpi7gBpjXp6BIU40ya8GiKeekNT2bg==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
|
||||
'@swc/core-win32-x64-msvc@1.7.23':
|
||||
resolution: {integrity: sha512-82fARk4/yJ40kwWKY/gdKDisPdtgJE9jgpl/vkNG3alyJxrCzuNM7+CtiKoYbXLeqM8GQTS3wlvCaJu9oQ8dag==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@swc/core@1.7.23':
|
||||
resolution: {integrity: sha512-VDNkpDvDlreGh2E3tlDj8B3piiuLhhQA/7rIVZpiLUvG1YpucAa6N7iDXA7Gc/+Hah8spaCg/qvEaBkCmcIYCQ==}
|
||||
engines: {node: '>=10'}
|
||||
peerDependencies:
|
||||
'@swc/helpers': '*'
|
||||
peerDependenciesMeta:
|
||||
'@swc/helpers':
|
||||
optional: true
|
||||
|
||||
'@swc/counter@0.1.3':
|
||||
resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==}
|
||||
|
||||
'@swc/helpers@0.5.23':
|
||||
resolution: {integrity: sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==}
|
||||
|
||||
'@swc/types@0.1.27':
|
||||
resolution: {integrity: sha512-K6h3iUlqeM946U4sXFYeahefR1YBbXJvko+hv8WS8/0BNJ4OHiHRywMnQUJCqkR7Y9+hqQ1TvEpiKqUhz7NEFg==}
|
||||
|
||||
'@tanstack/history@1.162.1':
|
||||
resolution: {integrity: sha512-DR9t6lfLVdrjgCwpglrR9DR7Ok8/HlXjcOE+goWXF3zyuLUO/ug7vMbSFxTqrQTtbRghJfyhmIZ0S6LhPIy44w==}
|
||||
engines: {node: '>=20.19'}
|
||||
@@ -6083,18 +6000,6 @@ packages:
|
||||
'@tokenizer/token@0.3.0':
|
||||
resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==}
|
||||
|
||||
'@tsconfig/node10@1.0.12':
|
||||
resolution: {integrity: sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==}
|
||||
|
||||
'@tsconfig/node12@1.0.11':
|
||||
resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==}
|
||||
|
||||
'@tsconfig/node14@1.0.3':
|
||||
resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==}
|
||||
|
||||
'@tsconfig/node16@1.0.4':
|
||||
resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==}
|
||||
|
||||
'@tsconfig/node24@24.0.5':
|
||||
resolution: {integrity: sha512-DWC54fGPuhZgg3Ighg4Y/A/bA3ZdB5hnzAuv/MkQ/X85sVsBsMQxu8t7khutdYeiNksBbFdDyeqv1HSW2Zl8aA==}
|
||||
|
||||
@@ -7100,10 +7005,6 @@ packages:
|
||||
peerDependencies:
|
||||
acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
|
||||
|
||||
acorn-walk@8.3.5:
|
||||
resolution: {integrity: sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
|
||||
acorn@8.18.0:
|
||||
resolution: {integrity: sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
@@ -7117,15 +7018,6 @@ packages:
|
||||
resolution: {integrity: sha512-TQf59BsZnytt8GdJKLPfUZ54g/iaUL2OWDSFCCvMOhsHduDQxO8xC4PNeyIkVcA5KwL2phPSv0douC0fgWzmnA==}
|
||||
engines: {node: '>= 20'}
|
||||
|
||||
ajv-cli@5.0.0:
|
||||
resolution: {integrity: sha512-LY4m6dUv44HTyhV+u2z5uX4EhPYTM38Iv1jdgDJJJCyOOuqB8KtZEGjPZ2T+sh5ZIJrXUfgErYx/j3gLd3+PlQ==}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
ts-node: '>=9.0.0'
|
||||
peerDependenciesMeta:
|
||||
ts-node:
|
||||
optional: true
|
||||
|
||||
ajv-draft-04@1.0.0:
|
||||
resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==}
|
||||
peerDependencies:
|
||||
@@ -7236,15 +7128,9 @@ packages:
|
||||
resolution: {integrity: sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==}
|
||||
engines: {node: '>= 14'}
|
||||
|
||||
arg@4.1.3:
|
||||
resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
|
||||
|
||||
arg@5.0.2:
|
||||
resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
|
||||
|
||||
argparse@1.0.10:
|
||||
resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==}
|
||||
|
||||
argparse@2.0.1:
|
||||
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
|
||||
|
||||
@@ -7943,9 +7829,6 @@ packages:
|
||||
resolution: {integrity: sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==}
|
||||
engines: {node: '>= 14'}
|
||||
|
||||
create-require@1.1.1:
|
||||
resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
|
||||
|
||||
crelt@1.0.7:
|
||||
resolution: {integrity: sha512-aK6BbWfhf4U/wCcLHKPJl/xa6VkVstRaPywWtMKGwuOLc/wZTyQYuoxgvZnNsBvv7Kg3YTBQYYBCggcviQczuA==}
|
||||
|
||||
@@ -8252,10 +8135,6 @@ packages:
|
||||
devlop@1.1.0:
|
||||
resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
|
||||
|
||||
diff@4.0.4:
|
||||
resolution: {integrity: sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==}
|
||||
engines: {node: '>=0.3.1'}
|
||||
|
||||
diff@8.0.4:
|
||||
resolution: {integrity: sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==}
|
||||
engines: {node: '>=0.3.1'}
|
||||
@@ -8711,9 +8590,6 @@ packages:
|
||||
resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==}
|
||||
engines: {node: '>=8.6.0'}
|
||||
|
||||
fast-json-patch@3.1.1:
|
||||
resolution: {integrity: sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==}
|
||||
|
||||
fast-json-stable-stringify@2.1.0:
|
||||
resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
|
||||
|
||||
@@ -9668,10 +9544,6 @@ packages:
|
||||
js-tokens@4.0.0:
|
||||
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
||||
|
||||
js-yaml@3.15.2:
|
||||
resolution: {integrity: sha512-6EuL879VkRA+1Cz578mKMiKvjPNEuk6+r1JaFzoSWejZmtf7xWbIyw1e3KkxlkzTIt9Taw6JBhEppG7utc1P+w==}
|
||||
hasBin: true
|
||||
|
||||
js-yaml@4.3.2:
|
||||
resolution: {integrity: sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==}
|
||||
hasBin: true
|
||||
@@ -9696,9 +9568,6 @@ packages:
|
||||
json-buffer@3.0.1:
|
||||
resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
|
||||
|
||||
json-schema-migrate@2.0.0:
|
||||
resolution: {integrity: sha512-r38SVTtojDRp4eD6WsCqiE0eNDt4v1WalBXb9cyZYw9ai5cGtBwzRNWjHzJl38w6TxFkXAIA7h+fyX3tnrAFhQ==}
|
||||
|
||||
json-schema-traverse@0.4.1:
|
||||
resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
|
||||
|
||||
@@ -9720,6 +9589,10 @@ packages:
|
||||
resolution: {integrity: sha512-1e4qoRgnn448pRuMvKGsFFymUCquZV0mpGgOyIKNgD3JVDTsVJyRBGH/Fm0tBb8WsWGgmB1mDe6/yJMQM37DUA==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
|
||||
jsonc-eslint-parser@3.3.0:
|
||||
resolution: {integrity: sha512-hYTGkHGNRZnXOFZ1urhINADoqDrGfpy53cjw+dxk84QE0pUDujQzeUeamNs6Mz44/TKD49z2x6/GVSu4ZrtA+Q==}
|
||||
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
|
||||
|
||||
jsonc-parser@2.3.1:
|
||||
resolution: {integrity: sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==}
|
||||
|
||||
@@ -9993,9 +9866,6 @@ packages:
|
||||
resolution: {integrity: sha512-IfpFq6UM39dUNiphpA6uDezNx/AvWyhwfICWPR3t1VspkgkMZrL+Rk1RbN1bx+aeNYwOrqGJgEgV3yotk+ZUVw==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
make-error@1.3.6:
|
||||
resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
|
||||
|
||||
make-fetch-happen@14.0.3:
|
||||
resolution: {integrity: sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ==}
|
||||
engines: {node: ^18.17.0 || >=20.5.0}
|
||||
@@ -12252,9 +12122,6 @@ packages:
|
||||
resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
sprintf-js@1.0.3:
|
||||
resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
|
||||
|
||||
srvx@0.11.22:
|
||||
resolution: {integrity: sha512-LqZxxBDMKuMAZzFzJnDCkFOrs9MZQZr0LvHiO/SuSZVdQaXD7xQ5UWTUxheJrQPve1qk9MG2B/yttUvJxw8egQ==}
|
||||
engines: {node: '>=20.16.0'}
|
||||
@@ -12703,20 +12570,6 @@ packages:
|
||||
ts-interface-checker@0.1.13:
|
||||
resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
|
||||
|
||||
ts-node@10.9.2:
|
||||
resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==}
|
||||
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
|
||||
|
||||
tslib@2.8.1:
|
||||
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
|
||||
|
||||
@@ -13101,9 +12954,6 @@ packages:
|
||||
resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==}
|
||||
engines: {node: '>= 0.4.0'}
|
||||
|
||||
v8-compile-cache-lib@3.0.1:
|
||||
resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
|
||||
|
||||
valibot@1.4.2:
|
||||
resolution: {integrity: sha512-gjdCvJ6d3RyHAneqxMYMW9QMCwYMb3jpOO0IyHZV1bnRHFBHrX3VkIILt5XYR0WhwHiH7Mty8ovuPZ/O3gamrg==}
|
||||
peerDependencies:
|
||||
@@ -13803,10 +13653,6 @@ packages:
|
||||
resolution: {integrity: sha512-FemWD5/UqNm8ffj8oZIbjWXIF2KE0mZssggYpdaQkWDDgXBQ/35PNIxEuz6/YLn9o0kOxDBNJe8x8k9ljD7k/g==}
|
||||
engines: {node: '>=18.16.0'}
|
||||
|
||||
yn@3.1.1:
|
||||
resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
yocto-queue@0.1.0:
|
||||
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -15637,11 +15483,6 @@ snapshots:
|
||||
|
||||
'@cspell/url@10.2.0': {}
|
||||
|
||||
'@cspotcode/source-map-support@0.8.1':
|
||||
dependencies:
|
||||
'@jridgewell/trace-mapping': 0.3.9
|
||||
optional: true
|
||||
|
||||
'@csstools/color-helpers@6.1.1': {}
|
||||
|
||||
'@csstools/css-calc@3.3.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)':
|
||||
@@ -16559,12 +16400,6 @@ snapshots:
|
||||
'@jridgewell/resolve-uri': 3.1.2
|
||||
'@jridgewell/sourcemap-codec': 1.6.0
|
||||
|
||||
'@jridgewell/trace-mapping@0.3.9':
|
||||
dependencies:
|
||||
'@jridgewell/resolve-uri': 3.1.2
|
||||
'@jridgewell/sourcemap-codec': 1.6.0
|
||||
optional: true
|
||||
|
||||
'@kwsites/file-exists@1.1.1(supports-color@10.2.2)':
|
||||
dependencies:
|
||||
debug: 4.4.3(supports-color@10.2.2)
|
||||
@@ -18366,66 +18201,10 @@ snapshots:
|
||||
vite: 8.3.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@10.2.2))(sass-embedded@1.105.1)(sass@1.105.1)(stylus@0.56.0(supports-color@10.2.2))(terser@5.51.2)(yaml@2.9.0)
|
||||
vitefu: 1.1.3(vite@8.3.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@10.2.2))(sass-embedded@1.105.1)(sass@1.105.1)(stylus@0.56.0(supports-color@10.2.2))(terser@5.51.2)(yaml@2.9.0))
|
||||
|
||||
'@swc/core-darwin-arm64@1.7.23':
|
||||
optional: true
|
||||
|
||||
'@swc/core-darwin-x64@1.7.23':
|
||||
optional: true
|
||||
|
||||
'@swc/core-linux-arm-gnueabihf@1.7.23':
|
||||
optional: true
|
||||
|
||||
'@swc/core-linux-arm64-gnu@1.7.23':
|
||||
optional: true
|
||||
|
||||
'@swc/core-linux-arm64-musl@1.7.23':
|
||||
optional: true
|
||||
|
||||
'@swc/core-linux-x64-gnu@1.7.23':
|
||||
optional: true
|
||||
|
||||
'@swc/core-linux-x64-musl@1.7.23':
|
||||
optional: true
|
||||
|
||||
'@swc/core-win32-arm64-msvc@1.7.23':
|
||||
optional: true
|
||||
|
||||
'@swc/core-win32-ia32-msvc@1.7.23':
|
||||
optional: true
|
||||
|
||||
'@swc/core-win32-x64-msvc@1.7.23':
|
||||
optional: true
|
||||
|
||||
'@swc/core@1.7.23(@swc/helpers@0.5.23)':
|
||||
dependencies:
|
||||
'@swc/counter': 0.1.3
|
||||
'@swc/types': 0.1.27
|
||||
optionalDependencies:
|
||||
'@swc/core-darwin-arm64': 1.7.23
|
||||
'@swc/core-darwin-x64': 1.7.23
|
||||
'@swc/core-linux-arm-gnueabihf': 1.7.23
|
||||
'@swc/core-linux-arm64-gnu': 1.7.23
|
||||
'@swc/core-linux-arm64-musl': 1.7.23
|
||||
'@swc/core-linux-x64-gnu': 1.7.23
|
||||
'@swc/core-linux-x64-musl': 1.7.23
|
||||
'@swc/core-win32-arm64-msvc': 1.7.23
|
||||
'@swc/core-win32-ia32-msvc': 1.7.23
|
||||
'@swc/core-win32-x64-msvc': 1.7.23
|
||||
'@swc/helpers': 0.5.23
|
||||
optional: true
|
||||
|
||||
'@swc/counter@0.1.3':
|
||||
optional: true
|
||||
|
||||
'@swc/helpers@0.5.23':
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
|
||||
'@swc/types@0.1.27':
|
||||
dependencies:
|
||||
'@swc/counter': 0.1.3
|
||||
optional: true
|
||||
|
||||
'@tanstack/history@1.162.1': {}
|
||||
|
||||
'@tanstack/history@1.162.4': {}
|
||||
@@ -18817,18 +18596,6 @@ snapshots:
|
||||
|
||||
'@tokenizer/token@0.3.0': {}
|
||||
|
||||
'@tsconfig/node10@1.0.12':
|
||||
optional: true
|
||||
|
||||
'@tsconfig/node12@1.0.11':
|
||||
optional: true
|
||||
|
||||
'@tsconfig/node14@1.0.3':
|
||||
optional: true
|
||||
|
||||
'@tsconfig/node16@1.0.4':
|
||||
optional: true
|
||||
|
||||
'@tsconfig/node24@24.0.5': {}
|
||||
|
||||
'@tsconfig/svelte@5.0.8': {}
|
||||
@@ -19848,29 +19615,12 @@ snapshots:
|
||||
dependencies:
|
||||
acorn: 8.18.0
|
||||
|
||||
acorn-walk@8.3.5:
|
||||
dependencies:
|
||||
acorn: 8.18.0
|
||||
optional: true
|
||||
|
||||
acorn@8.18.0: {}
|
||||
|
||||
agent-base@7.1.4: {}
|
||||
|
||||
agent-base@9.0.0: {}
|
||||
|
||||
ajv-cli@5.0.0(ts-node@10.9.2(@swc/core@1.7.23(@swc/helpers@0.5.23))(@types/node@26.4.1)(typescript@6.0.3)):
|
||||
dependencies:
|
||||
ajv: 8.20.0
|
||||
fast-json-patch: 3.1.1
|
||||
glob: 7.2.3
|
||||
js-yaml: 3.15.2
|
||||
json-schema-migrate: 2.0.0
|
||||
json5: 2.2.3
|
||||
minimist: 1.2.8
|
||||
optionalDependencies:
|
||||
ts-node: 10.9.2(@swc/core@1.7.23(@swc/helpers@0.5.23))(@types/node@26.4.1)(typescript@6.0.3)
|
||||
|
||||
ajv-draft-04@1.0.0(ajv@8.20.0):
|
||||
optionalDependencies:
|
||||
ajv: 8.20.0
|
||||
@@ -20002,15 +19752,8 @@ snapshots:
|
||||
- bare-buffer
|
||||
- react-native-b4a
|
||||
|
||||
arg@4.1.3:
|
||||
optional: true
|
||||
|
||||
arg@5.0.2: {}
|
||||
|
||||
argparse@1.0.10:
|
||||
dependencies:
|
||||
sprintf-js: 1.0.3
|
||||
|
||||
argparse@2.0.1: {}
|
||||
|
||||
argparse@3.0.1: {}
|
||||
@@ -20811,9 +20554,6 @@ snapshots:
|
||||
crc-32: 1.2.2
|
||||
readable-stream: 4.7.0
|
||||
|
||||
create-require@1.1.1:
|
||||
optional: true
|
||||
|
||||
crelt@1.0.7: {}
|
||||
|
||||
croner@10.0.1: {}
|
||||
@@ -21179,9 +20919,6 @@ snapshots:
|
||||
dependencies:
|
||||
dequal: 2.0.3
|
||||
|
||||
diff@4.0.4:
|
||||
optional: true
|
||||
|
||||
diff@8.0.4: {}
|
||||
|
||||
diff@9.0.0: {}
|
||||
@@ -21755,8 +21492,6 @@ snapshots:
|
||||
merge2: 1.4.1
|
||||
micromatch: 4.0.8
|
||||
|
||||
fast-json-patch@3.1.1: {}
|
||||
|
||||
fast-json-stable-stringify@2.1.0: {}
|
||||
|
||||
fast-levenshtein@2.0.6: {}
|
||||
@@ -22753,11 +22488,6 @@ snapshots:
|
||||
|
||||
js-tokens@4.0.0: {}
|
||||
|
||||
js-yaml@3.15.2:
|
||||
dependencies:
|
||||
argparse: 1.0.10
|
||||
esprima: 4.0.1
|
||||
|
||||
js-yaml@4.3.2:
|
||||
dependencies:
|
||||
argparse: 2.0.1
|
||||
@@ -22794,10 +22524,6 @@ snapshots:
|
||||
|
||||
json-buffer@3.0.1: {}
|
||||
|
||||
json-schema-migrate@2.0.0:
|
||||
dependencies:
|
||||
ajv: 8.20.0
|
||||
|
||||
json-schema-traverse@0.4.1: {}
|
||||
|
||||
json-schema-traverse@1.0.0: {}
|
||||
@@ -22815,6 +22541,12 @@ snapshots:
|
||||
espree: 9.6.1
|
||||
semver: 7.8.5
|
||||
|
||||
jsonc-eslint-parser@3.3.0:
|
||||
dependencies:
|
||||
acorn: 8.18.0
|
||||
eslint-visitor-keys: 5.0.1
|
||||
verkit: 0.3.2
|
||||
|
||||
jsonc-parser@2.3.1: {}
|
||||
|
||||
jsonc-parser@3.3.1: {}
|
||||
@@ -23147,9 +22879,6 @@ snapshots:
|
||||
make-dir@5.1.0:
|
||||
optional: true
|
||||
|
||||
make-error@1.3.6:
|
||||
optional: true
|
||||
|
||||
make-fetch-happen@14.0.3(supports-color@10.2.2):
|
||||
dependencies:
|
||||
'@npmcli/agent': 3.0.0(supports-color@10.2.2)
|
||||
@@ -26123,8 +25852,6 @@ snapshots:
|
||||
|
||||
speakingurl@14.0.1: {}
|
||||
|
||||
sprintf-js@1.0.3: {}
|
||||
|
||||
srvx@0.11.22: {}
|
||||
|
||||
srvx@0.12.8: {}
|
||||
@@ -26603,27 +26330,6 @@ snapshots:
|
||||
|
||||
ts-interface-checker@0.1.13: {}
|
||||
|
||||
ts-node@10.9.2(@swc/core@1.7.23(@swc/helpers@0.5.23))(@types/node@26.4.1)(typescript@6.0.3):
|
||||
dependencies:
|
||||
'@cspotcode/source-map-support': 0.8.1
|
||||
'@tsconfig/node10': 1.0.12
|
||||
'@tsconfig/node12': 1.0.11
|
||||
'@tsconfig/node14': 1.0.3
|
||||
'@tsconfig/node16': 1.0.4
|
||||
'@types/node': 26.4.1
|
||||
acorn: 8.18.0
|
||||
acorn-walk: 8.3.5
|
||||
arg: 4.1.3
|
||||
create-require: 1.1.1
|
||||
diff: 4.0.4
|
||||
make-error: 1.3.6
|
||||
typescript: 6.0.3
|
||||
v8-compile-cache-lib: 3.0.1
|
||||
yn: 3.1.1
|
||||
optionalDependencies:
|
||||
'@swc/core': 1.7.23(@swc/helpers@0.5.23)
|
||||
optional: true
|
||||
|
||||
tslib@2.8.1: {}
|
||||
|
||||
ttf2eot@3.1.0:
|
||||
@@ -27028,9 +26734,6 @@ snapshots:
|
||||
|
||||
utils-merge@1.0.1: {}
|
||||
|
||||
v8-compile-cache-lib@3.0.1:
|
||||
optional: true
|
||||
|
||||
valibot@1.4.2(typescript@6.0.3):
|
||||
optionalDependencies:
|
||||
typescript: 6.0.3
|
||||
@@ -27872,9 +27575,6 @@ snapshots:
|
||||
|
||||
yerror@8.0.0: {}
|
||||
|
||||
yn@3.1.1:
|
||||
optional: true
|
||||
|
||||
yocto-queue@0.1.0: {}
|
||||
|
||||
yocto-queue@1.2.2: {}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
import path from 'node:path';
|
||||
|
||||
/**
|
||||
* ESLint formatter for GitHub Actions. Prints each problem as a readable line plus a workflow
|
||||
* command (`::error file=…`), so it shows up as an inline annotation in the PR diff.
|
||||
*
|
||||
* Unlike setup-node's `eslint-stylish` problem matcher, this also annotates parsing errors, which
|
||||
* have no rule id.
|
||||
*
|
||||
* Usage: eslint --format ./scripts/eslint/githubFormatter.mjs
|
||||
*/
|
||||
|
||||
/** Escape data for a workflow command, see https://github.com/actions/toolkit/blob/main/packages/core/src/command.ts */
|
||||
const escapeData = (/** @type {string} */ value) =>
|
||||
value.replaceAll('%', '%25').replaceAll('\r', '%0D').replaceAll('\n', '%0A');
|
||||
const escapeProperty = (/** @type {string} */ value) =>
|
||||
escapeData(value).replaceAll(':', '%3A').replaceAll(',', '%2C');
|
||||
|
||||
/** @type {import('eslint').ESLint.FormatterFunction} */
|
||||
const formatter = (results) => {
|
||||
const lines = [];
|
||||
let errors = 0;
|
||||
let warnings = 0;
|
||||
|
||||
for (const result of results) {
|
||||
const file = path.relative(process.cwd(), result.filePath);
|
||||
|
||||
for (const message of result.messages) {
|
||||
const severity = message.severity === 2 ? 'error' : 'warning';
|
||||
if (severity === 'error') errors++;
|
||||
else warnings++;
|
||||
|
||||
const rule = message.ruleId ?? 'parse';
|
||||
const line = message.line ?? 1;
|
||||
const column = message.column ?? 1;
|
||||
lines.push(`${file}:${line}:${column} ${severity} ${message.message} (${rule})`);
|
||||
|
||||
const properties = [
|
||||
`file=${escapeProperty(file)}`,
|
||||
`line=${line}`,
|
||||
`col=${column}`,
|
||||
message.endLine ? `endLine=${message.endLine}` : '',
|
||||
message.endColumn ? `endColumn=${message.endColumn}` : '',
|
||||
`title=${escapeProperty(`ESLint (${rule})`)}`,
|
||||
].filter(Boolean);
|
||||
lines.push(`::${severity} ${properties.join(',')}::${escapeData(message.message)}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (errors + warnings > 0) {
|
||||
const plural = (/** @type {number} */ count, /** @type {string} */ word) =>
|
||||
`${count} ${word}${count === 1 ? '' : 's'}`;
|
||||
lines.push(
|
||||
'',
|
||||
`✖ ${plural(errors + warnings, 'problem')} (${plural(errors, 'error')}, ${plural(warnings, 'warning')})`,
|
||||
);
|
||||
}
|
||||
return lines.join('\n');
|
||||
};
|
||||
|
||||
export default formatter;
|
||||
@@ -0,0 +1,147 @@
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { Ajv2020 } from 'ajv/dist/2020.js';
|
||||
import { getStaticJSONValue } from 'jsonc-eslint-parser';
|
||||
|
||||
/**
|
||||
* ESLint plugin that validates JSON files against a configured JSON Schema (draft 2020-12),
|
||||
* reporting each error at the offending property. It also requires the file's `$schema` field to
|
||||
* point at that schema.
|
||||
*
|
||||
* Off-the-shelf plugins (e.g. eslint-plugin-json-schema-validator) only run Ajv in draft-07 mode,
|
||||
* which silently skips 2020-12 keywords such as `dependentRequired`.
|
||||
*/
|
||||
|
||||
const ajv = new Ajv2020({ allErrors: true });
|
||||
/** @type {Map<string, import('ajv').ValidateFunction>} */
|
||||
const validators = new Map();
|
||||
|
||||
/** @param {string} schemaPath */
|
||||
const getValidator = (schemaPath) => {
|
||||
let validate = validators.get(schemaPath);
|
||||
if (!validate) {
|
||||
validate = ajv.compile(JSON.parse(fs.readFileSync(schemaPath, 'utf-8')));
|
||||
validators.set(schemaPath, validate);
|
||||
}
|
||||
return validate;
|
||||
};
|
||||
|
||||
/**
|
||||
* Find the AST node for a JSON pointer (e.g. `/aliases/0/name`). Returns the property node for
|
||||
* object members so the report points at the key, falling back to the closest existing parent.
|
||||
*
|
||||
* @param {any} node
|
||||
* @param {string} pointer
|
||||
*/
|
||||
const findNode = (node, pointer) => {
|
||||
const segments = pointer
|
||||
.split('/')
|
||||
.slice(1)
|
||||
.map((segment) => segment.replaceAll('~1', '/').replaceAll('~0', '~'));
|
||||
let current = node;
|
||||
let reportNode = node;
|
||||
for (const segment of segments) {
|
||||
if (current?.type === 'JSONObjectExpression') {
|
||||
const property = current.properties.find(
|
||||
(/** @type {any} */ prop) => (prop.key.value ?? prop.key.name) === segment,
|
||||
);
|
||||
if (!property) break;
|
||||
reportNode = property;
|
||||
current = property.value;
|
||||
} else if (current?.type === 'JSONArrayExpression') {
|
||||
const element = current.elements[Number(segment)];
|
||||
if (!element) break;
|
||||
reportNode = element;
|
||||
current = element;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return { node: current, reportNode };
|
||||
};
|
||||
|
||||
/** @type {import('eslint').Rule.RuleModule} */
|
||||
const noInvalid = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'Validate JSON files against a JSON Schema and require `$schema` to point at it',
|
||||
},
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
// Path to the schema, relative to the ESLint working directory (the repo root).
|
||||
schema: { type: 'string' },
|
||||
},
|
||||
required: ['schema'],
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
create(context) {
|
||||
return {
|
||||
/** @param {any} program */
|
||||
Program(program) {
|
||||
const root = program.body[0]?.expression;
|
||||
if (root?.type !== 'JSONObjectExpression') {
|
||||
context.report({ node: root ?? program, message: 'Root value must be an object.' });
|
||||
return;
|
||||
}
|
||||
|
||||
const data = getStaticJSONValue(root);
|
||||
if (typeof data?.$schema !== 'string') {
|
||||
context.report({ node: root, message: 'Missing `$schema` field.' });
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate against the configured schema, not whatever `$schema` points at, so a file can't
|
||||
// opt out of validation by referencing a more permissive schema.
|
||||
const schemaPath = path.resolve(context.cwd, context.options[0].schema);
|
||||
const expectedRef = path
|
||||
.relative(path.dirname(context.filename), schemaPath)
|
||||
.split(path.sep)
|
||||
.join('/');
|
||||
if (path.resolve(path.dirname(context.filename), data.$schema) !== schemaPath) {
|
||||
context.report({
|
||||
node: findNode(root, '/$schema').reportNode,
|
||||
message: `\`$schema\` must be "${expectedRef}".`,
|
||||
});
|
||||
}
|
||||
|
||||
const validate = getValidator(schemaPath);
|
||||
if (validate(data)) return;
|
||||
|
||||
for (const error of validate.errors ?? []) {
|
||||
const { node, reportNode } = findNode(root, error.instancePath);
|
||||
const location = error.instancePath || '(root)';
|
||||
|
||||
if (error.keyword === 'additionalProperties' && node?.type === 'JSONObjectExpression') {
|
||||
const property = findNode(
|
||||
node,
|
||||
`/${error.params.additionalProperty.replaceAll('~', '~0').replaceAll('/', '~1')}`,
|
||||
).reportNode;
|
||||
context.report({
|
||||
node: property,
|
||||
message: `${location} has unexpected property "${error.params.additionalProperty}".`,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
const isContainer =
|
||||
reportNode.type === 'JSONObjectExpression' || reportNode.type === 'JSONArrayExpression';
|
||||
context.report({
|
||||
// Report objects and arrays at their opening bracket only, not their whole range.
|
||||
loc: isContainer ? reportNode.loc.start : reportNode.loc,
|
||||
message: `${location} ${error.message}.`,
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
export default {
|
||||
meta: { name: 'json-schema' },
|
||||
rules: { 'no-invalid': noInvalid },
|
||||
};
|
||||
@@ -0,0 +1,123 @@
|
||||
/**
|
||||
* Checks formatting with Prettier and reports every unformatted range as a GitHub Actions
|
||||
* annotation (`::error file=…,line=…`), so it shows up inline in the PR diff.
|
||||
*
|
||||
* `prettier --check` only reports file names, so this formats each listed file in memory and
|
||||
* diffs it against the original to find the exact lines.
|
||||
*/
|
||||
import fs from 'fs';
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
import process from 'process';
|
||||
import { spawnSync } from 'child_process';
|
||||
import { createRequire } from 'module';
|
||||
import * as prettier from 'prettier';
|
||||
|
||||
const PATTERNS = ['**/*.{js,mjs,ts,jsx,tsx,html,css,scss,json,yml,yaml}', 'icons/*.svg'];
|
||||
|
||||
const prettierBin = createRequire(import.meta.url).resolve('prettier/bin/prettier.cjs');
|
||||
|
||||
const listDifferent = spawnSync(
|
||||
process.execPath,
|
||||
[prettierBin, '--list-different', '--no-color', ...PATTERNS],
|
||||
{ encoding: 'utf-8', maxBuffer: 64 * 1024 * 1024 },
|
||||
);
|
||||
|
||||
/** Escape data for a workflow command, see https://github.com/actions/toolkit/blob/main/packages/core/src/command.ts */
|
||||
const escapeData = (value: string) =>
|
||||
value.replaceAll('%', '%25').replaceAll('\r', '%0D').replaceAll('\n', '%0A');
|
||||
const escapeProperty = (value: string) =>
|
||||
escapeData(value).replaceAll(':', '%3A').replaceAll(',', '%2C');
|
||||
|
||||
let problems = 0;
|
||||
|
||||
// Exit code 2 means Prettier could not process a file, e.g. because of a syntax error.
|
||||
if (listDifferent.status !== 0 && listDifferent.status !== 1) {
|
||||
console.log('::group::Prettier errors');
|
||||
console.log(listDifferent.stderr);
|
||||
console.log('::endgroup::');
|
||||
|
||||
const syntaxError = /^\[error\] (.+?): (\w*Error: .+) \((\d+):(\d+)\)$/;
|
||||
for (const line of listDifferent.stderr.split('\n')) {
|
||||
const match = line.match(syntaxError);
|
||||
if (!match) continue;
|
||||
const [, file, message, errorLine, column] = match;
|
||||
console.log(
|
||||
`::error file=${escapeProperty(file)},line=${errorLine},col=${column},title=Prettier::${escapeData(message)}`,
|
||||
);
|
||||
problems++;
|
||||
}
|
||||
|
||||
if (problems === 0) {
|
||||
console.log(
|
||||
`::error title=Prettier::${escapeData(listDifferent.stderr.trim() || 'Prettier failed.')}`,
|
||||
);
|
||||
problems++;
|
||||
}
|
||||
}
|
||||
|
||||
const files = listDifferent.stdout.split('\n').filter(Boolean);
|
||||
|
||||
if (files.length === 0 && problems === 0) {
|
||||
console.log('All matched files use Prettier code style!');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'lint-format-'));
|
||||
const hunkHeader = /^@@ -(\d+)(?:,(\d+))? \+\d+(?:,\d+)? @@/;
|
||||
|
||||
for (const file of files) {
|
||||
const source = fs.readFileSync(file, 'utf-8');
|
||||
const options = await prettier.resolveConfig(file);
|
||||
const formatted = await prettier.format(source, { ...options, filepath: file });
|
||||
|
||||
const formattedFile = path.join(tmpDir, 'formatted');
|
||||
fs.writeFileSync(formattedFile, formatted);
|
||||
|
||||
const { stdout: diff } = spawnSync(
|
||||
'git',
|
||||
['diff', '--no-index', '--no-color', '-U0', '--', file, formattedFile],
|
||||
{ encoding: 'utf-8', maxBuffer: 64 * 1024 * 1024 },
|
||||
);
|
||||
|
||||
console.log(`::group::${file}`);
|
||||
console.log(diff);
|
||||
console.log('::endgroup::');
|
||||
|
||||
const lines = diff.split('\n');
|
||||
for (let index = 0; index < lines.length; index++) {
|
||||
const match = lines[index].match(hunkHeader);
|
||||
if (!match) continue;
|
||||
|
||||
const start = Number(match[1]);
|
||||
const count = match[2] === undefined ? 1 : Number(match[2]);
|
||||
|
||||
const expected: string[] = [];
|
||||
while (index + 1 < lines.length && /^[-+\\ ]/.test(lines[index + 1])) {
|
||||
index++;
|
||||
if (lines[index].startsWith('+')) expected.push(lines[index].slice(1));
|
||||
}
|
||||
|
||||
// A pure insertion (count 0) happens after `start`, so point at that line.
|
||||
const line = Math.max(start, 1);
|
||||
const endLine = count === 0 ? line : start + count - 1;
|
||||
|
||||
const message =
|
||||
expected.length > 0
|
||||
? `Code is not formatted with Prettier. Expected:\n${expected.join('\n')}`
|
||||
: 'Code is not formatted with Prettier. Remove these lines.';
|
||||
|
||||
console.log(
|
||||
`::error file=${escapeProperty(file)},line=${line},endLine=${endLine},title=Prettier::${escapeData(message)}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fs.rmSync(tmpDir, { recursive: true, force: true });
|
||||
|
||||
if (files.length > 0) {
|
||||
console.log(
|
||||
`\n${files.length} file(s) not formatted with Prettier. Run \`pnpm lint:format-fix\` and \`pnpm lint:icons-fix\` to fix.`,
|
||||
);
|
||||
}
|
||||
process.exit(1);
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* Spell checks icon and category metadata with cspell and reports every unknown word as a GitHub
|
||||
* Actions annotation (`::error file=…,line=…`), so it shows up inline in the PR diff.
|
||||
*
|
||||
* Words that are correct but unknown to cspell go in `.cspell/custom-words.txt`.
|
||||
*/
|
||||
import process from 'process';
|
||||
import { spawnSync } from 'child_process';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const PATTERNS = ['icons/*.json', 'categories/*.json'];
|
||||
|
||||
// cspell only exports its bin for `import`, so resolve it the ESM way.
|
||||
const cspellBin = fileURLToPath(import.meta.resolve('cspell/bin.mjs'));
|
||||
|
||||
const cspell = spawnSync(
|
||||
process.execPath,
|
||||
[cspellBin, '--no-color', '--no-progress', '--no-summary', ...PATTERNS],
|
||||
{ encoding: 'utf-8', maxBuffer: 64 * 1024 * 1024 },
|
||||
);
|
||||
|
||||
/** Escape data for a workflow command, see https://github.com/actions/toolkit/blob/main/packages/core/src/command.ts */
|
||||
const escapeData = (value: string) =>
|
||||
value.replaceAll('%', '%25').replaceAll('\r', '%0D').replaceAll('\n', '%0A');
|
||||
const escapeProperty = (value: string) =>
|
||||
escapeData(value).replaceAll(':', '%3A').replaceAll(',', '%2C');
|
||||
|
||||
const issue = /^(.+?):(\d+):(\d+) - Unknown word \((.+?)\)(?: fix: \((.+?)\))?/;
|
||||
let problems = 0;
|
||||
|
||||
for (const line of cspell.stdout.split('\n')) {
|
||||
const match = line.match(issue);
|
||||
if (!match) continue;
|
||||
|
||||
const [, file, lineNumber, column, word, fix] = match;
|
||||
const suggestion = fix ? ` Did you mean "${fix}"?` : '';
|
||||
const message = `Unknown word "${word}".${suggestion} Fix the typo or add the word to .cspell/custom-words.txt.`;
|
||||
|
||||
console.log(line);
|
||||
console.log(
|
||||
`::error file=${escapeProperty(file)},line=${lineNumber},col=${column},endColumn=${Number(column) + word.length},title=cspell::${escapeData(message)}`,
|
||||
);
|
||||
problems++;
|
||||
}
|
||||
|
||||
if (cspell.status !== 0 && problems === 0) {
|
||||
process.stderr.write(cspell.stderr);
|
||||
console.log(`::error title=cspell::${escapeData(cspell.stderr.trim() || 'cspell failed.')}`);
|
||||
process.exit(cspell.status ?? 1);
|
||||
}
|
||||
|
||||
if (problems > 0) {
|
||||
console.log(`\n${problems} spelling issue(s) found.`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log('No spelling issues found.');
|
||||
Reference in New Issue
Block a user