Files
iptvnator/package.json
T
4grayandClaude Opus 5.5 dd28911ee4 ci(test): download the Electron binary once before unit specs run
pnpm skips Electron's postinstall (electron is deliberately not in
onlyBuiltDependencies), so the binary is downloaded lazily on the first
require('electron'). Since Tier A projects run concurrently (#1701),
several electron-backend and database specs resolve and exec it at the
same time; one process execs it while another is still extracting it
and fails with `spawnSync .../electron ETXTBSY`.

tools/testing/ensure-electron-binary.mjs downloads the binary once and
fails unless it runs under ELECTRON_RUN_AS_NODE and reports the pinned
version. The unit job runs it right after pnpm install, coverage:unit:ci
runs it first for local runs, and the performance journeys job runs it
before its ldd check, which passed vacuously while no binary existed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 21:47:03 +02:00

310 lines
15 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: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",
"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/testing/ensure-electron-binary.mjs && 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",
"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: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",
"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",
"fix-path": "5.0.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.1",
"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.4",
"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/crimson-pro": "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",
"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.4",
"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"
}
}
}