mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-10 10:06:15 -08:00
* fix(ui): replace icon ligatures missing from the font and guard them The download and recording queues showed the literal text "file_off" for a missing file: the bundled Material Icons font (material-design-icons-iconfont 6.7.0) has no such ligature, so it rendered as text overflowing the icon box. Use error_outline, which the missing state's tertiary palette keeps distinct from the filled error glyph of a failed download. Add `pnpm run styles:icon-ligatures:validate` (CI): it parses templates with @angular/compiler and TypeScript with the compiler API, collects static <mat-icon> text, the string results of its bindings, icon/*Icon inputs and icon-named TypeScript values, and fails on a name missing from the font's codepoints file. Two listed codepoints the font has no ligature for (rounded_corner, stairs) are excluded. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(tools): check quoted inline templates in the icon guard Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(tools): accept every codepoint and report escaped template lines The first measurement rendered the names without the package's CSS. With material-design-icons.css, all 2,193 codepoint names, rounded_corner and stairs included, draw as one glyph, so the guard accepts the whole file. Inline templates now map each cooked position back to the source through escapes, line continuations and CRLF, so a name after `\n` in a quoted template is reported on the line it is written on. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
326 lines
16 KiB
JSON
326 lines
16 KiB
JSON
{
|
|
"name": "iptvnator",
|
|
"version": "0.25.0",
|
|
"engines": {
|
|
"node": "^22.22.3 || ^24.15.0"
|
|
},
|
|
"license": "MIT",
|
|
"description": "IPTV player application.",
|
|
"homepage": "https://github.com/4gray/iptvnator",
|
|
"author": {
|
|
"name": "4gray",
|
|
"email": "fourgray@proton.me"
|
|
},
|
|
"keywords": [
|
|
"angular",
|
|
"electron",
|
|
"typescript",
|
|
"m3u",
|
|
"m3u8",
|
|
"player",
|
|
"iptv",
|
|
"video",
|
|
"tv"
|
|
],
|
|
"scripts": {
|
|
"postinstall": "electron-builder install-app-deps",
|
|
"build:frontend": "nx build web",
|
|
"build:frontend:pwa": "nx build web --configuration=pwa",
|
|
"build:backend": "nx build electron-backend --configuration=production",
|
|
"serve:frontend": "nx serve web --no-tui",
|
|
"serve:frontend:pwa": "nx serve web --configuration=pwa --no-tui",
|
|
"serve:backend": "nx serve electron-backend",
|
|
"serve:marketing-demo": "nx run-many --target=serve --projects=xtream-mock-server,electron-backend --parallel=2",
|
|
"serve:marketing-demo:web": "nx run-many --target=serve --projects=xtream-mock-server,web --parallel=2",
|
|
"test:frontend": "nx test web",
|
|
"test:backend": "nx test electron-backend",
|
|
"test:unit:all": "nx run-many --target=test --all --parallel=3",
|
|
"test:unit:ci": "nx run-many --target=test --all --parallel=3 --output-style=static",
|
|
"deps:nx:test": "node --test tools/dependencies/check-nx-version-sync.test.mjs",
|
|
"deps:nx:check": "node tools/dependencies/check-nx-version-sync.mjs",
|
|
"deps:nx:validate": "pnpm run deps:nx:test && pnpm run deps:nx:check",
|
|
"deps:vite:test": "node --test tools/dependencies/vite-transform-filter.test.mjs",
|
|
"deps:electron-builder:test": "node --test tools/dependencies/app-builder-lib-keychain-password.test.mjs",
|
|
"styles:font-weights:test": "node --test tools/nx/check-font-weights.test.mjs",
|
|
"styles:font-weights:check": "node tools/nx/check-font-weights.mjs",
|
|
"styles:font-weights:validate": "pnpm run styles:font-weights:test && pnpm run styles:font-weights:check",
|
|
"styles:inputs:test": "node --test tools/nx/check-stylesheet-inputs.test.mjs",
|
|
"styles:inputs:check": "node tools/nx/check-stylesheet-inputs.mjs",
|
|
"styles:inputs:validate": "pnpm run styles:inputs:test && pnpm run styles:inputs:check",
|
|
"styles:material-tokens:test": "node --test tools/nx/check-material-token-overrides.test.mjs",
|
|
"styles:material-tokens:check": "node tools/nx/check-material-token-overrides.mjs",
|
|
"styles:material-tokens:validate": "pnpm run styles:material-tokens:test && pnpm run styles:material-tokens:check",
|
|
"styles:icon-ligatures:test": "node --test tools/nx/check-icon-ligatures.test.mjs",
|
|
"styles:icon-ligatures:check": "node tools/nx/check-icon-ligatures.mjs",
|
|
"styles:icon-ligatures:validate": "pnpm run styles:icon-ligatures:test && pnpm run styles:icon-ligatures:check",
|
|
"e2e:task-graphs:test": "node --test tools/nx/check-e2e-task-graphs.test.mjs",
|
|
"e2e:task-graphs:check": "node tools/nx/check-e2e-task-graphs.mjs",
|
|
"e2e:task-graphs:validate": "pnpm run e2e:task-graphs:test && pnpm run e2e:task-graphs:check",
|
|
"coverage:tools:test": "node --test tools/coverage/coverage-integrity.test.mjs tools/coverage/e2e-shard-reports.test.mjs tools/coverage/coverage-run-pool.test.mjs tools/coverage/unit-coverage-scope.test.mjs",
|
|
"coverage:unit:ci": "node tools/coverage/run-tier-a-coverage.mjs",
|
|
"coverage:merge": "node tools/coverage/merge-coverage.mjs",
|
|
"coverage:health": "node tools/coverage/coverage-health.mjs",
|
|
"coverage:policy:check": "node tools/coverage/check-coverage-policy.mjs",
|
|
"coverage:ci": "pnpm run coverage:tools:test && pnpm run coverage:policy:check && pnpm run coverage:unit:ci && pnpm run coverage:merge && node tools/coverage/coverage-health.mjs --require-report",
|
|
"coverage:e2e:summary": "node tools/coverage/e2e-semantic-summary.mjs",
|
|
"coverage:e2e:v8:web": "node tools/coverage/e2e-v8-web.mjs",
|
|
"typecheck:web": "tsc -p apps/web/tsconfig.app.json --noEmit",
|
|
"typecheck:backend": "tsc -p apps/electron-backend/tsconfig.app.json --noEmit",
|
|
"typecheck:ci": "pnpm run typecheck:web && pnpm run typecheck:backend",
|
|
"typecheck:spec": "node tools/typecheck/spec-typecheck.mjs",
|
|
"typecheck:spec:test": "node --test tools/typecheck/spec-typecheck.test.mjs",
|
|
"verify:package-layout": "node tools/packaging/verify-electron-package-layout.mjs",
|
|
"embedded-mpv:build-native:homebrew": "IPTVNATOR_EMBEDDED_MPV_ALLOW_HOMEBREW=1 nx run electron-backend:build-embedded-mpv",
|
|
"embedded-mpv:build-runtime": "node tools/embedded-mpv/build-macos-runtime.mjs",
|
|
"embedded-mpv:build-runtime:linux": "node tools/embedded-mpv/build-linux-runtime.mjs",
|
|
"embedded-mpv:stage-runtime": "node tools/embedded-mpv/stage-runtime.mjs",
|
|
"embedded-mpv:stage-runtime:macos": "node tools/embedded-mpv/stage-macos-runtime.mjs",
|
|
"embedded-mpv:stage-runtime:windows-archive": "node tools/embedded-mpv/stage-windows-runtime-archive.mjs",
|
|
"embedded-mpv:windows-runtime-pin:check": "node tools/embedded-mpv/windows-runtime-pin.mjs",
|
|
"embedded-mpv:windows-runtime-pin:refresh": "node tools/embedded-mpv/update-windows-runtime-pin.mjs",
|
|
"serve:backend:embedded-mpv": "pnpm embedded-mpv:build-native:homebrew && IPTVNATOR_EMBEDDED_MPV_ALLOW_HOMEBREW=1 IPTVNATOR_ENABLE_EMBEDDED_MPV_EXPERIMENT=1 pnpm serve:backend",
|
|
"package:app": "nx run electron-backend:make --prepackageOnly",
|
|
"make:app": "nx run electron-backend:make",
|
|
"smoke:packaged": "node tools/testing/launch-packaged-electron.mjs",
|
|
"serve:website": "nx serve website",
|
|
"build:website": "nx build website",
|
|
"i18n:check": "node tools/i18n/check-drift.mjs",
|
|
"i18n:test": "node --test tools/i18n/check-drift.test.mjs",
|
|
"i18n:validate": "pnpm run i18n:test && pnpm run i18n:check",
|
|
"i18n:baseline:update": "node tools/i18n/check-drift.mjs --update-baseline",
|
|
"perf:initial-bytes": "node tools/performance/measure-initial-bytes.mjs",
|
|
"perf:initial-bytes:check": "node tools/performance/measure-initial-bytes.mjs --summary dist/performance/initial-bytes.summary.json && node tools/performance/check-journey-ratchet.mjs --summary dist/performance/initial-bytes.summary.json --only launch/renderer.initialBytes",
|
|
"perf:journeys": "nx run electron-backend-e2e:journeys",
|
|
"perf:compositing": "nx run electron-backend-e2e:compositing-report",
|
|
"perf:ratchet:check": "node tools/performance/check-journey-ratchet.mjs --summary dist/performance/journey-summary.json",
|
|
"perf:tools:test": "node --test tools/performance/measure-initial-bytes.test.mjs tools/performance/check-journey-ratchet.test.mjs tools/performance/check-baseline-direction.test.mjs tools/performance/tighten-baselines.test.mjs",
|
|
"agents:validate": "node tools/skills/validate-agent-guidance.mjs",
|
|
"skills:validate": "node tools/skills/validate-repository-skills.mjs",
|
|
"release:artwork:dry-run": "tsx --tsconfig tsconfig.base.json tools/release/generate-marketing-artwork.ts --dry-run",
|
|
"release:artwork:manifest": "tsx --tsconfig tsconfig.base.json tools/release/generate-marketing-artwork.ts --manifest",
|
|
"release:artwork:generate": "tsx --tsconfig tsconfig.base.json tools/release/generate-marketing-artwork.ts --generate",
|
|
"release:artwork:validate": "tsx --tsconfig tsconfig.base.json tools/release/generate-marketing-artwork.ts --validate",
|
|
"release:notes:validate": "node tools/release/build-release-notes.mjs --validate",
|
|
"release:notes:github": "node tools/release/build-release-notes.mjs --format github",
|
|
"release:notes:changelog": "node tools/release/build-release-notes.mjs --format changelog",
|
|
"release:notes:blog": "node tools/release/build-release-notes.mjs --format blog",
|
|
"release:notes:telegram": "node tools/release/build-release-notes.mjs --format telegram",
|
|
"release:notes:reddit": "node tools/release/build-release-notes.mjs --format reddit",
|
|
"release:verify:draft": "node tools/release/verify-draft-release.mjs",
|
|
"release:cards:dry-run": "node tools/release/generate-highlight-cards.mjs --dry-run",
|
|
"release:cards:generate": "node tools/release/generate-highlight-cards.mjs --generate",
|
|
"release:screenshots": "tsx tools/release/capture-release-screenshots.ts",
|
|
"lint": "nx run-many --target=lint --all",
|
|
"build": "nx build electron-backend"
|
|
},
|
|
"private": true,
|
|
"packageManager": "pnpm@10.33.0+sha512.10568bb4a6afb58c9eb3630da90cc9516417abebd3fabbe6739f0ae795728da1491e9db5a544c76ad8eb7570f5c4bb3d6c637b2cb41bfdcdb47fa823c8649319",
|
|
"dependencies": {
|
|
"@angular/animations": "22.1.6",
|
|
"@angular/cdk": "22.1.6",
|
|
"@angular/common": "22.1.6",
|
|
"@angular/compiler": "22.1.6",
|
|
"@angular/core": "22.1.6",
|
|
"@angular/forms": "22.1.6",
|
|
"@angular/material": "22.1.6",
|
|
"@angular/platform-browser": "22.1.6",
|
|
"@angular/platform-browser-dynamic": "22.1.6",
|
|
"@angular/router": "22.1.6",
|
|
"@ngrx/effects": "22.0.1",
|
|
"@ngrx/entity": "22.0.1",
|
|
"@ngrx/router-store": "22.0.1",
|
|
"@ngrx/signals": "22.0.1",
|
|
"@ngrx/store": "22.0.1",
|
|
"@ngrx/store-devtools": "22.0.1",
|
|
"@ngx-pwa/local-storage": "22.0.0",
|
|
"@yangkghjh/videojs-aspect-ratio-panel": "0.0.1",
|
|
"angularx-qrcode": "22.0.1",
|
|
"artplayer": "5.4.0",
|
|
"axios": "1.20.0",
|
|
"better-sqlite3": "13.0.3",
|
|
"date-fns": "4.4.0",
|
|
"drizzle-orm": "0.45.2",
|
|
"electron-conf": "1.3.0",
|
|
"electron-updater": "6.8.9",
|
|
"epg-parser": "^0.5.0",
|
|
"hls.js": "1.7.1",
|
|
"iptv-playlist-parser": "github:4gray/iptv-playlist-parser#v0.15.2-iptvnator.2",
|
|
"marked": "18.0.11",
|
|
"mpegts.js": "1.8.2",
|
|
"ms": "2.1.3",
|
|
"ngx-indexed-db": "22.0.0",
|
|
"ngx-skeleton-loader": "11.3.0",
|
|
"proxy-from-env": "2.1.0",
|
|
"rxjs": "7.8.2",
|
|
"saxes": "6.0.0",
|
|
"shaka-player": "5.2.12",
|
|
"shell-path": "3.1.0",
|
|
"video.js": "8.24.0",
|
|
"videojs-contrib-quality-levels": "4.1.0",
|
|
"videojs-quality-selector-hls": "1.1.1",
|
|
"zone.js": "0.16.3"
|
|
},
|
|
"devDependencies": {
|
|
"@angular-devkit/core": "22.1.8",
|
|
"@angular-devkit/schematics": "22.1.8",
|
|
"@angular-eslint/builder": "22.5.0",
|
|
"@angular-eslint/eslint-plugin": "22.5.0",
|
|
"@angular-eslint/eslint-plugin-template": "22.5.0",
|
|
"@angular-eslint/schematics": "22.5.0",
|
|
"@angular-eslint/template-parser": "22.5.0",
|
|
"@angular/build": "22.1.8",
|
|
"@angular/cli": "22.1.8",
|
|
"@angular/common": "22.1.6",
|
|
"@angular/compiler": "22.1.6",
|
|
"@angular/compiler-cli": "22.1.6",
|
|
"@angular/core": "22.1.6",
|
|
"@angular/forms": "22.1.6",
|
|
"@angular/language-service": "22.1.6",
|
|
"@angular/platform-browser": "22.1.6",
|
|
"@angular/platform-browser-dynamic": "22.1.6",
|
|
"@angular/router": "22.1.6",
|
|
"@angular/service-worker": "22.1.6",
|
|
"@astrojs/mdx": "7.0.7",
|
|
"@astrojs/sitemap": "3.7.4",
|
|
"@babel/core": "7.29.7",
|
|
"@electron/asar": "3.4.1",
|
|
"@eslint/eslintrc": "3.3.7",
|
|
"@eslint/js": "^9.38.0",
|
|
"@faker-js/faker": "10.6.0",
|
|
"@fontsource-variable/bricolage-grotesque": "5.3.0",
|
|
"@fontsource/dm-sans": "5.3.0",
|
|
"@fontsource/ibm-plex-mono": "5.3.0",
|
|
"@fontsource/jetbrains-mono": "5.3.0",
|
|
"@fontsource/roboto": "5.3.0",
|
|
"@ngrx/eslint-plugin": "22.0.1",
|
|
"@ngx-translate/core": "16.0.4",
|
|
"@ngx-translate/http-loader": "16.0.1",
|
|
"@nx/angular": "23.2.1",
|
|
"@nx/devkit": "23.2.1",
|
|
"@nx/esbuild": "23.2.1",
|
|
"@nx/eslint": "23.2.1",
|
|
"@nx/eslint-plugin": "23.2.1",
|
|
"@nx/jest": "23.2.1",
|
|
"@nx/js": "23.2.1",
|
|
"@nx/playwright": "23.2.1",
|
|
"@nx/web": "23.2.1",
|
|
"@nx/workspace": "23.2.1",
|
|
"@playwright/test": "^1.62.1",
|
|
"@schematics/angular": "22.1.8",
|
|
"@swc-node/register": "1.12.1",
|
|
"@swc/core": "1.16.1",
|
|
"@swc/helpers": "0.5.23",
|
|
"@tailwindcss/typography": "0.5.20",
|
|
"@types/better-sqlite3": "^9.6.0",
|
|
"@types/cors": "2.8.19",
|
|
"@types/express": "5.0.6",
|
|
"@types/jest": "^30.0.0",
|
|
"@types/jsdom": "21.1.7",
|
|
"@types/mocha": "9.0.0",
|
|
"@types/node": "20.19.9",
|
|
"@types/proxy-from-env": "1.0.4",
|
|
"@types/video.js": "7.3.58",
|
|
"@typescript-eslint/eslint-plugin": "^8.69.0",
|
|
"@typescript-eslint/parser": "^8.69.0",
|
|
"@typescript-eslint/utils": "^8.69.0",
|
|
"angular-eslint": "22.5.0",
|
|
"astro": "7.2.10",
|
|
"autoprefixer": "10.5.4",
|
|
"axe-core": "4.13.0",
|
|
"cookie": "2.0.1",
|
|
"cors": "2.8.6",
|
|
"drizzle-kit": "0.31.10",
|
|
"electron": "^43.3.0",
|
|
"electron-builder": "^26.15.7",
|
|
"electron-playwright-helpers": "1.8.2",
|
|
"esbuild": "0.28.2",
|
|
"eslint": "^9.8.0",
|
|
"eslint-config-prettier": "^10.1.8",
|
|
"eslint-plugin-import": "2.32.0",
|
|
"eslint-plugin-playwright": "^1.6.2",
|
|
"express": "5.2.1",
|
|
"github-slugger": "2.0.0",
|
|
"globals": "15.9.0",
|
|
"html-escaper": "3.0.3",
|
|
"istanbul-lib-coverage": "3.2.2",
|
|
"istanbul-lib-report": "3.0.1",
|
|
"istanbul-reports": "3.2.0",
|
|
"jest": "^30.5.1",
|
|
"jest-environment-jsdom": "^30.5.1",
|
|
"jest-environment-node": "^30.5.1",
|
|
"jest-preset-angular": "17.0.0",
|
|
"jest-util": "^30.5.1",
|
|
"jsdom": "26.1.0",
|
|
"jsonc-eslint-parser": "^2.1.0",
|
|
"material-design-icons-iconfont": "6.7.0",
|
|
"mrmime": "2.0.1",
|
|
"ng-mocks": "14.17.6",
|
|
"node-gyp": "12.4.0",
|
|
"nx": "23.2.1",
|
|
"nx-electron": "22.0.0",
|
|
"parse-srcset": "1.0.2",
|
|
"parse5": "8.0.1",
|
|
"prettier": "^3.9.6",
|
|
"sharp": "0.35.5",
|
|
"tailwindcss": "^3.4.19",
|
|
"ts-jest": "^29.4.12",
|
|
"ts-node": "10.9.2",
|
|
"tslib": "^2.8.1",
|
|
"tsx": "4.23.13",
|
|
"typescript": "6.0.3",
|
|
"typescript-eslint": "^8.69.0",
|
|
"yaml": "2.9.0",
|
|
"zod": "4.5.4"
|
|
},
|
|
"pnpm": {
|
|
"overrides": {
|
|
"@esbuild-kit/core-utils>esbuild": "0.25.12",
|
|
"@hono/node-server@1.19.9": "1.19.17",
|
|
"@humanfs/node@0.16.7": "0.16.8",
|
|
"@xmldom/xmldom@0.8.11": "0.8.15",
|
|
"ajv@6.12.6": "6.14.0",
|
|
"ajv@8.17.1": "8.20.0",
|
|
"brace-expansion@1.1.12": "1.1.18",
|
|
"browserslist@4.28.1": "4.28.8",
|
|
"defu@6.1.4": "6.1.6",
|
|
"devalue@5.6.2": "5.6.4",
|
|
"express-rate-limit@8.2.1": "8.3.0",
|
|
"fast-uri@3.1.0": "3.1.6",
|
|
"flatted@3.3.3": "3.4.2",
|
|
"follow-redirects@1.15.11": "1.16.0",
|
|
"form-data@4.0.5": "4.0.6",
|
|
"h3@1.15.5": "1.15.10",
|
|
"hono@4.12.0": "4.13.5",
|
|
"immutable@5.1.4": "5.1.9",
|
|
"ip-address@10.1.0": "10.5.0",
|
|
"js-yaml@4.1.1": "4.3.2",
|
|
"js-yaml@4.3.0": "4.3.2",
|
|
"jsdom>ws": "8.21.3",
|
|
"lodash-es@4.17.22": "4.18.1",
|
|
"minimatch@3.1.2": "3.1.5",
|
|
"node-forge@1.3.3": "1.4.0",
|
|
"path-to-regexp@0.1.12": "0.1.13",
|
|
"picomatch@2.3.1": "2.3.2",
|
|
"picomatch@4.0.3": "4.0.7",
|
|
"postcss-selector-parser@6.1.2": "6.1.4",
|
|
"postcss@8.5.6": "8.5.26",
|
|
"qs@6.14.1": "6.15.3",
|
|
"rollup@4.52.3": "4.59.0",
|
|
"serialize-javascript@6.0.2": "7.1.0",
|
|
"smol-toml@1.6.0": "1.7.1",
|
|
"smol-toml@1.6.1": "1.7.1",
|
|
"svgo@3.3.2": "3.3.3",
|
|
"svgo@4.0.0": "4.1.0",
|
|
"svgo@4.0.2": "4.1.0",
|
|
"undici@7.28.0": "7.29.0",
|
|
"uuid@8.3.2": "11.1.1",
|
|
"yaml@1.10.2": "1.10.3"
|
|
},
|
|
"patchedDependencies": {
|
|
"nx-electron@22.0.0": "patches/nx-electron@22.0.0.patch",
|
|
"app-builder-lib@26.15.7": "patches/app-builder-lib@26.15.7.patch",
|
|
"vite@8.1.5": "patches/vite@8.1.5.patch"
|
|
}
|
|
}
|
|
}
|