test(ci): [CI-TYPES-01] validate installed Audio and HLS types

This commit is contained in:
Harvey Zhao committed 2026-09-15 19:59:44 +08:00
1 parent 210484c443
commit 00c131bff1
16 files changed
+1246 -12

No files matched your search

+3 -3
View File
@@ -40,12 +40,12 @@
"test:dash-control": "node --test test/dash-control.test.js test/dash-contract.test.js test/dash-lifecycle.test.js test/dash-events.test.js test/dash-cleanup-errors.test.js",
"dev": "npx cross-env NODE_ENV=development node ./scripts/dev.js",
"build": "npx cross-env NODE_ENV=production node ./scripts/build.js",
"lint": "eslint \"packages/*/{src,public,types,package.json}\" \"scripts/*.{js,mjs}\" \"packages/artplayer-vitepress/{browser,build}/**/*.ts\" \"scripts/{docs-smoke,editor-declarations,documentation,site-build,library,pages,site-vendor,browser-validation,release}/**/*.ts\" \"scripts/plugin/*.{js,ts}\" \"test/*\" \"docs/assets/ts/*\" \"types/*.d.ts\" \"playwright*.config.js\" --no-fix",
"lint": "eslint \"packages/*/{src,public,types,package.json}\" \"scripts/*.{js,mjs}\" \"packages/artplayer-vitepress/{browser,build}/**/*.ts\" \"scripts/{docs-smoke,editor-declarations,documentation,site-build,library,pages,site-vendor,browser-validation,release,consumers}/**/*.ts\" \"scripts/plugin/*.{js,ts}\" \"test/*\" \"docs/assets/ts/*\" \"types/*.d.ts\" \"playwright*.config.js\" --no-fix",
"build:all": "yarn ci:build && yarn lint",
"check:toolchain": "node scripts/check-toolchain.mjs",
"lint:fix": "eslint \"packages/*/{src,public,types,package.json}\" \"scripts/*.{js,mjs}\" \"packages/artplayer-vitepress/{browser,build}/**/*.ts\" \"scripts/{docs-smoke,editor-declarations,documentation,site-build,library,pages,site-vendor,browser-validation,release}/**/*.ts\" \"scripts/plugin/*.{js,ts}\" \"test/*\" \"docs/assets/ts/*\" \"types/*.d.ts\" \"playwright*.config.js\" --fix",
"lint:fix": "eslint \"packages/*/{src,public,types,package.json}\" \"scripts/*.{js,mjs}\" \"packages/artplayer-vitepress/{browser,build}/**/*.ts\" \"scripts/{docs-smoke,editor-declarations,documentation,site-build,library,pages,site-vendor,browser-validation,release,consumers}/**/*.ts\" \"scripts/plugin/*.{js,ts}\" \"test/*\" \"docs/assets/ts/*\" \"types/*.d.ts\" \"playwright*.config.js\" --fix",
"check:plan": "node refactor/scripts/plan.mjs --check",
"test:node": "yarn test:unit && node --test test/toolchain.test.js test/build-docs.test.js test/package-check.test.js test/declarations.test.js test/editor-types.test.js test/coverage.test.js test/performance-report.test.js test/media-gate.test.js test/ci-summary.test.js test/package-runtime.test.js test/library-build.test.js test/site-loading.test.js test/documentation-pipeline.test.js test/site-build.test.js test/site-markdown.test.js test/site-editor.test.js test/plugin-scaffold.test.js test/dev-server.test.js test/pages-artifact.test.js test/site-notices.test.js test/monaco-provenance.test.js test/monaco-unicode.test.js test/site-console.test.js test/vconsole-lifecycle.test.js test/browser-validation.test.js test/rollback-files.test.js test/pages-recovery.test.js",
"test:node": "yarn test:unit && node --test test/toolchain.test.js test/build-docs.test.js test/package-check.test.js test/declarations.test.js test/editor-types.test.js test/coverage.test.js test/performance-report.test.js test/media-gate.test.js test/ci-summary.test.js test/package-runtime.test.js test/library-build.test.js test/site-loading.test.js test/documentation-pipeline.test.js test/site-build.test.js test/site-markdown.test.js test/site-editor.test.js test/plugin-scaffold.test.js test/dev-server.test.js test/pages-artifact.test.js test/site-notices.test.js test/monaco-provenance.test.js test/monaco-unicode.test.js test/site-console.test.js test/vconsole-lifecycle.test.js test/browser-validation.test.js test/rollback-files.test.js test/pages-recovery.test.js test/installed-types.test.js",
"test:baseline": "node --test refactor/scripts/*.test.mjs",
"ci:check": "yarn check:toolchain --strict && yarn check:commits --report && yarn check:impact --report && yarn check:ci && yarn test:contracts && yarn check:contracts --report && yarn check:plan && yarn check:release-ledger && yarn typecheck:release && yarn check:rollback-inventory && yarn lint && yarn typecheck:library && yarn typecheck:scaffold && yarn typecheck:docs-tools && yarn check:docs-smoke && yarn check:editor-types && yarn check:llm && yarn check:vconsole && yarn check:console && yarn check:site-notices && yarn typecheck:site-assets && yarn check:site-assets && yarn check:types && yarn typecheck && yarn typecheck:react && yarn lint:react && yarn typecheck:vue && yarn lint:vue && yarn test",
"ci:build": "yarn build:types && yarn build all && yarn build:i18n && yarn build:ts && yarn build:llm && yarn build:vconsole && yarn build:console && yarn build:site-notices && yarn build:test && yarn build:docs && yarn test:imports",
@@ -44,6 +44,14 @@ mute the main video. Destroying ArtPlayer releases the plugin's audio and subscr
retained plugin updates become inert. See [ARCHITECTURE.md](ARCHITECTURE.md) for module
ownership, compatibility decisions and regression commands.
Installed declaration regression: run
`yarn test:package --include=artplayer-plugin-audio-track` from the repository root.
This builds and installs tarballs outside the repository, then checks root,
legacy and `/runtime` calls from `test/types/audio-track.ts` in five compiler
modes, including every invalid call. See
[consumer maintenance](../../scripts/consumers/README.md); media synchronization
and browser validation remain separate.
## License
MIT © Harvey Zhao
@@ -13,6 +13,14 @@ The guides describe this refactor branch; its fixes have not yet been published.
[https://artplayer.org](https://artplayer.org/?libs=https://cdnjs.cloudflare.com/ajax/libs/hls.js/1.5.17/hls.min.js%0A./uncompiled/artplayer-plugin-hls-control/index.js&example=hls.control)
Installed declaration regression: run
`yarn test:package --include=artplayer-plugin-hls-control` from the repository root.
The isolated tarball consumer checks root/legacy imports, extracted option types,
custom track generics, formatter arguments and invalid calls in five compiler
modes using `test/types/hls-control.ts`. See
[consumer maintenance](../../scripts/consumers/README.md); real HLS playback and
SDK combinations remain separate validation gates.
## License
MIT © Harvey Zhao
@@ -0,0 +1,918 @@
{
"task": "CI-TYPES-01",
"baselineCommit": "210484c443077da389e048afb76a229f2b1e56bc",
"environment": {
"node": "24.21.0",
"yarn": "1.22.22",
"platform": "win32"
},
"scope": "Installed Audio/HLS type fixtures; twenty-package build/pack/install preparation. No additional runtime or browser acceptance.",
"output": "refactor/.cache/packages/run-5UdGXT",
"reportSha256": "e45e27a2a6b7841b6a34370d5b13062d2873532a0932b0346207fae5cd56f834",
"packages": [
{
"name": "artplayer",
"version": "5.4.1",
"archive": "artplayer.tgz",
"sha256": "c70d0696a6225768145850bebd9542bc1a8f13217eb43350bfcfc45ea0687b16"
},
{
"name": "artplayer-plugin-chapter",
"version": "1.1.0",
"archive": "artplayer-plugin-chapter.tgz",
"sha256": "787da05cedcea0102f2cb85661b4ef03eb2e232d781e86fe1ea9f2d705795d62"
},
{
"name": "artplayer-plugin-ambilight",
"version": "1.1.0",
"archive": "artplayer-plugin-ambilight.tgz",
"sha256": "001bd46ab0908b66b852a372de5e5516a55c7d4a099ece68a501b0daa1f36b6c"
},
{
"name": "artplayer-proxy-canvas",
"version": "1.1.0",
"archive": "artplayer-proxy-canvas.tgz",
"sha256": "2f76422a469b574e1e56a68291ca1fdca908b08e4d879fecdbff56d29f83d65b"
},
{
"name": "artplayer-plugin-document-pip",
"version": "1.1.0",
"archive": "artplayer-plugin-document-pip.tgz",
"sha256": "073023d0e0f9dacafe9104642320a5dbd936e9e12ebd91954745cb51f8f73122"
},
{
"name": "artplayer-plugin-ads",
"version": "2.1.0",
"archive": "artplayer-plugin-ads.tgz",
"sha256": "95763685a2695151cd3b1df7438c1f96e15b0245fa5473ea10bf81d6323df116"
},
{
"name": "artplayer-plugin-audio-track",
"version": "1.1.0",
"archive": "artplayer-plugin-audio-track.tgz",
"sha256": "a444570cf69b3803414b5dccfd7ae3eaddeded35984eebff40010f95d98b647b"
},
{
"name": "artplayer-plugin-vtt-thumbnail",
"version": "1.1.0",
"archive": "artplayer-plugin-vtt-thumbnail.tgz",
"sha256": "c5f8db5e0bea6fa620f1031b95c115e037a4a515d4b253ea0e411dacf88c0943"
},
{
"name": "artplayer-plugin-multiple-subtitles",
"version": "1.2.0",
"archive": "artplayer-plugin-multiple-subtitles.tgz",
"sha256": "df91ebc6e78994b8ce600d80b2182f77e187a753e48c10c857573bf1d6a7e666"
},
{
"name": "artplayer-plugin-hls-control",
"version": "1.1.0",
"archive": "artplayer-plugin-hls-control.tgz",
"sha256": "b8fde8519ca7780dd421e5394d6bbee154abc1b092549bb08668af0d0bb1b946"
},
{
"name": "artplayer-plugin-dash-control",
"version": "1.1.0",
"archive": "artplayer-plugin-dash-control.tgz",
"sha256": "e897c61ca757c46260a860a866bbbe7e10a95d6de67ffedc4ae03b1f70f614e8"
},
{
"name": "artplayer-plugin-auto-thumbnail",
"version": "1.1.0",
"archive": "artplayer-plugin-auto-thumbnail.tgz",
"sha256": "ebca33069c114dc634751dbeed8e909d702abc0924abc5ef9437f8250f46ece0"
},
{
"name": "artplayer-plugin-asr",
"version": "2.1.0",
"archive": "artplayer-plugin-asr.tgz",
"sha256": "d6d75fbd6422d5128d87f8272638a71c4b4ee87d70625dd4b7ca40b038ea14fb"
},
{
"name": "artplayer-plugin-chromecast",
"version": "1.1.0",
"archive": "artplayer-plugin-chromecast.tgz",
"sha256": "7317c9a5914099e107fc0d2cdf75c2709fb3f1b05bcd53d719a082ca66c58969"
},
{
"name": "artplayer-proxy-mediabunny",
"version": "1.2.0",
"archive": "artplayer-proxy-mediabunny.tgz",
"sha256": "7bde410f07334ab85b4ecc0714d106c132a6826698dc7ed13b3e55c21a2206fd"
},
{
"name": "artplayer-plugin-jassub",
"version": "1.1.0",
"archive": "artplayer-plugin-jassub.tgz",
"sha256": "6bec955a04295e142ea337dd715aebc3d1f6e9b2f53fd2bcfbf49d16c22c7ba2"
},
{
"name": "artplayer-plugin-danmuku",
"version": "5.3.0",
"archive": "artplayer-plugin-danmuku.tgz",
"sha256": "93a4226126eac6ae0e298078b3f700a002ccdac53c63379d624a52c64d24e7ff"
},
{
"name": "artplayer-plugin-danmuku-mask",
"version": "1.1.0",
"archive": "artplayer-plugin-danmuku-mask.tgz",
"sha256": "623ef4d889db28a69230b7a4f109cdce5550e2d5a4b758be5c4d609dd6b12b37"
},
{
"name": "artplayer-tool-iframe",
"version": "1.1.0",
"archive": "artplayer-tool-iframe.tgz",
"sha256": "ef1ad7cf60b8e08bfedb66ccdc452e55ecde0b2bb2a1c964b3c1ea088928ac8f"
},
{
"name": "artplayer-plugin-vast",
"version": "1.2.0",
"archive": "artplayer-plugin-vast.tgz",
"sha256": "87420c2069f5f50740b75d23c7aba72870899b94d4472d90f33b816ef16e2e14"
}
],
"additionalTypeScope": [
"artplayer-plugin-audio-track",
"artplayer-plugin-hls-control"
],
"pluginTypes": [
{
"name": "artplayer-plugin-audio-track",
"fixture": "test/types/audio-track.ts",
"fixtureSha256": "d9c01d2d4cb9ce28da599440f71cafe7b87c8c9521eb4d0c2ce1168ba3d2fde4",
"modes": [
{
"compiler": "5.9.3",
"mode": "node10-commonjs",
"declarations": [
"node_modules/artplayer/types/component.d.ts",
"node_modules/artplayer/types/config.d.ts",
"node_modules/artplayer/types/emitter.d.ts",
"node_modules/artplayer/types/cssVar.d.ts",
"node_modules/artplayer/types/i18n.d.ts",
"node_modules/artplayer/types/icons.d.ts",
"node_modules/artplayer/types/plugin.d.ts",
"node_modules/artplayer/types/quality.d.ts",
"node_modules/artplayer/types/setting.d.ts",
"node_modules/artplayer/types/subtitle.d.ts",
"node_modules/artplayer/types/option.d.ts",
"node_modules/artplayer/types/player.d.ts",
"node_modules/artplayer/types/events.d.ts",
"node_modules/artplayer/types/playback.d.ts",
"node_modules/artplayer/types/template.d.ts",
"node_modules/artplayer/types/utils.d.ts",
"node_modules/artplayer/types/artplayer.d.ts",
"node_modules/artplayer-plugin-audio-track/types/artplayer-plugin-audio-track.d.ts",
"node_modules/artplayer-plugin-audio-track/types/runtime/index.d.ts"
],
"negativeStatements": 12,
"negativeDiagnostics": [
{
"code": 2554,
"line": 40
},
{
"code": 2345,
"line": 42
},
{
"code": 2322,
"line": 44
},
{
"code": 2554,
"line": 46
},
{
"code": 2322,
"line": 48
},
{
"code": 2322,
"line": 50
},
{
"code": 2322,
"line": 52
},
{
"code": 2322,
"line": 54
},
{
"code": 2322,
"line": 56
},
{
"code": 2322,
"line": 58
},
{
"code": 2353,
"line": 60
},
{
"code": 2322,
"line": 62
}
]
},
{
"compiler": "5.9.3",
"mode": "nodenext-cjs",
"declarations": [
"node_modules/artplayer/types/component.d.ts",
"node_modules/artplayer/types/config.d.ts",
"node_modules/artplayer/types/emitter.d.ts",
"node_modules/artplayer/types/cssVar.d.ts",
"node_modules/artplayer/types/i18n.d.ts",
"node_modules/artplayer/types/icons.d.ts",
"node_modules/artplayer/types/plugin.d.ts",
"node_modules/artplayer/types/quality.d.ts",
"node_modules/artplayer/types/setting.d.ts",
"node_modules/artplayer/types/subtitle.d.ts",
"node_modules/artplayer/types/option.d.ts",
"node_modules/artplayer/types/player.d.ts",
"node_modules/artplayer/types/events.d.ts",
"node_modules/artplayer/types/playback.d.ts",
"node_modules/artplayer/types/template.d.ts",
"node_modules/artplayer/types/utils.d.ts",
"node_modules/artplayer/types/artplayer.d.ts",
"node_modules/artplayer/types/artplayer.d.cts",
"node_modules/artplayer-plugin-audio-track/types/artplayer-plugin-audio-track.d.ts",
"node_modules/artplayer-plugin-audio-track/types/artplayer-plugin-audio-track.d.cts",
"node_modules/artplayer-plugin-audio-track/types/runtime/index.d.cts"
],
"negativeStatements": 12,
"negativeDiagnostics": [
{
"code": 2554,
"line": 40
},
{
"code": 2345,
"line": 42
},
{
"code": 2322,
"line": 44
},
{
"code": 2554,
"line": 46
},
{
"code": 2322,
"line": 48
},
{
"code": 2322,
"line": 50
},
{
"code": 2322,
"line": 52
},
{
"code": 2322,
"line": 54
},
{
"code": 2322,
"line": 56
},
{
"code": 2322,
"line": 58
},
{
"code": 2353,
"line": 60
},
{
"code": 2322,
"line": 62
}
]
},
{
"compiler": "5.9.3",
"mode": "nodenext-esm",
"declarations": [
"node_modules/artplayer/types/component.d.ts",
"node_modules/artplayer/types/config.d.ts",
"node_modules/artplayer/types/emitter.d.ts",
"node_modules/artplayer/types/cssVar.d.ts",
"node_modules/artplayer/types/i18n.d.ts",
"node_modules/artplayer/types/icons.d.ts",
"node_modules/artplayer/types/plugin.d.ts",
"node_modules/artplayer/types/quality.d.ts",
"node_modules/artplayer/types/setting.d.ts",
"node_modules/artplayer/types/subtitle.d.ts",
"node_modules/artplayer/types/option.d.ts",
"node_modules/artplayer/types/player.d.ts",
"node_modules/artplayer/types/events.d.ts",
"node_modules/artplayer/types/playback.d.ts",
"node_modules/artplayer/types/template.d.ts",
"node_modules/artplayer/types/utils.d.ts",
"node_modules/artplayer/types/artplayer.d.ts",
"node_modules/artplayer/types/artplayer.d.cts",
"node_modules/artplayer-plugin-audio-track/types/artplayer-plugin-audio-track.d.ts",
"node_modules/artplayer-plugin-audio-track/types/artplayer-plugin-audio-track.d.cts",
"node_modules/artplayer-plugin-audio-track/types/artplayer-plugin-audio-track.d.mts",
"node_modules/artplayer/types/artplayer.d.mts",
"node_modules/artplayer-plugin-audio-track/types/runtime/index.d.cts",
"node_modules/artplayer-plugin-audio-track/types/runtime/index.d.mts"
],
"negativeStatements": 12,
"negativeDiagnostics": [
{
"code": 2554,
"line": 40
},
{
"code": 2345,
"line": 42
},
{
"code": 2322,
"line": 44
},
{
"code": 2554,
"line": 46
},
{
"code": 2322,
"line": 48
},
{
"code": 2322,
"line": 50
},
{
"code": 2322,
"line": 52
},
{
"code": 2322,
"line": 54
},
{
"code": 2322,
"line": 56
},
{
"code": 2322,
"line": 58
},
{
"code": 2353,
"line": 60
},
{
"code": 2322,
"line": 62
}
]
},
{
"compiler": "5.9.3",
"mode": "bundler-esm",
"declarations": [
"node_modules/artplayer/types/component.d.ts",
"node_modules/artplayer/types/config.d.ts",
"node_modules/artplayer/types/emitter.d.ts",
"node_modules/artplayer/types/cssVar.d.ts",
"node_modules/artplayer/types/i18n.d.ts",
"node_modules/artplayer/types/icons.d.ts",
"node_modules/artplayer/types/plugin.d.ts",
"node_modules/artplayer/types/quality.d.ts",
"node_modules/artplayer/types/setting.d.ts",
"node_modules/artplayer/types/subtitle.d.ts",
"node_modules/artplayer/types/option.d.ts",
"node_modules/artplayer/types/player.d.ts",
"node_modules/artplayer/types/events.d.ts",
"node_modules/artplayer/types/playback.d.ts",
"node_modules/artplayer/types/template.d.ts",
"node_modules/artplayer/types/utils.d.ts",
"node_modules/artplayer/types/artplayer.d.ts",
"node_modules/artplayer/types/artplayer.d.cts",
"node_modules/artplayer/types/artplayer.d.mts",
"node_modules/artplayer-plugin-audio-track/types/artplayer-plugin-audio-track.d.ts",
"node_modules/artplayer-plugin-audio-track/types/artplayer-plugin-audio-track.d.cts",
"node_modules/artplayer-plugin-audio-track/types/artplayer-plugin-audio-track.d.mts",
"node_modules/artplayer-plugin-audio-track/types/runtime/index.d.cts",
"node_modules/artplayer-plugin-audio-track/types/runtime/index.d.mts"
],
"negativeStatements": 12,
"negativeDiagnostics": [
{
"code": 2554,
"line": 40
},
{
"code": 2345,
"line": 42
},
{
"code": 2322,
"line": 44
},
{
"code": 2554,
"line": 46
},
{
"code": 2322,
"line": 48
},
{
"code": 2322,
"line": 50
},
{
"code": 2322,
"line": 52
},
{
"code": 2322,
"line": 54
},
{
"code": 2322,
"line": 56
},
{
"code": 2322,
"line": 58
},
{
"code": 2353,
"line": 60
},
{
"code": 2322,
"line": 62
}
]
},
{
"compiler": "4.3.5",
"mode": "node10-commonjs",
"declarations": [
"node_modules/artplayer/types/component.d.ts",
"node_modules/artplayer/types/config.d.ts",
"node_modules/artplayer/types/emitter.d.ts",
"node_modules/artplayer/types/cssVar.d.ts",
"node_modules/artplayer/types/i18n.d.ts",
"node_modules/artplayer/types/icons.d.ts",
"node_modules/artplayer/types/plugin.d.ts",
"node_modules/artplayer/types/quality.d.ts",
"node_modules/artplayer/types/setting.d.ts",
"node_modules/artplayer/types/subtitle.d.ts",
"node_modules/artplayer/types/option.d.ts",
"node_modules/artplayer/types/player.d.ts",
"node_modules/artplayer/types/events.d.ts",
"node_modules/artplayer/types/playback.d.ts",
"node_modules/artplayer/types/template.d.ts",
"node_modules/artplayer/types/utils.d.ts",
"node_modules/artplayer/types/artplayer.d.ts",
"node_modules/artplayer-plugin-audio-track/types/artplayer-plugin-audio-track.d.ts",
"node_modules/artplayer-plugin-audio-track/types/runtime/index.d.ts"
],
"negativeStatements": 12,
"negativeDiagnostics": [
{
"code": 2554,
"line": 40
},
{
"code": 2345,
"line": 42
},
{
"code": 2322,
"line": 44
},
{
"code": 2554,
"line": 46
},
{
"code": 2322,
"line": 48
},
{
"code": 2322,
"line": 50
},
{
"code": 2322,
"line": 52
},
{
"code": 2322,
"line": 54
},
{
"code": 2322,
"line": 56
},
{
"code": 2322,
"line": 58
},
{
"code": 2345,
"line": 60
},
{
"code": 2322,
"line": 62
}
]
}
]
},
{
"name": "artplayer-plugin-hls-control",
"fixture": "test/types/hls-control.ts",
"fixtureSha256": "3bbdeae926b6a5aad6e5b7c34a21babbc7784007c49d65acc44dac0962ba2b61",
"modes": [
{
"compiler": "5.9.3",
"mode": "node10-commonjs",
"declarations": [
"node_modules/artplayer/types/component.d.ts",
"node_modules/artplayer/types/config.d.ts",
"node_modules/artplayer/types/emitter.d.ts",
"node_modules/artplayer/types/cssVar.d.ts",
"node_modules/artplayer/types/i18n.d.ts",
"node_modules/artplayer/types/icons.d.ts",
"node_modules/artplayer/types/plugin.d.ts",
"node_modules/artplayer/types/quality.d.ts",
"node_modules/artplayer/types/setting.d.ts",
"node_modules/artplayer/types/subtitle.d.ts",
"node_modules/artplayer/types/option.d.ts",
"node_modules/artplayer/types/player.d.ts",
"node_modules/artplayer/types/events.d.ts",
"node_modules/artplayer/types/playback.d.ts",
"node_modules/artplayer/types/template.d.ts",
"node_modules/artplayer/types/utils.d.ts",
"node_modules/artplayer/types/artplayer.d.ts",
"node_modules/artplayer-plugin-hls-control/types/artplayer-plugin-hls-control.d.ts"
],
"negativeStatements": 8,
"negativeDiagnostics": [
{
"code": 2322,
"line": 28
},
{
"code": 2554,
"line": 30
},
{
"code": 2322,
"line": 32
},
{
"code": 2769,
"line": 34
},
{
"code": 2769,
"line": 36
},
{
"code": 2769,
"line": 38
},
{
"code": 2769,
"line": 40
},
{
"code": 2339,
"line": 42
}
]
},
{
"compiler": "5.9.3",
"mode": "nodenext-cjs",
"declarations": [
"node_modules/artplayer/types/component.d.ts",
"node_modules/artplayer/types/config.d.ts",
"node_modules/artplayer/types/emitter.d.ts",
"node_modules/artplayer/types/cssVar.d.ts",
"node_modules/artplayer/types/i18n.d.ts",
"node_modules/artplayer/types/icons.d.ts",
"node_modules/artplayer/types/plugin.d.ts",
"node_modules/artplayer/types/quality.d.ts",
"node_modules/artplayer/types/setting.d.ts",
"node_modules/artplayer/types/subtitle.d.ts",
"node_modules/artplayer/types/option.d.ts",
"node_modules/artplayer/types/player.d.ts",
"node_modules/artplayer/types/events.d.ts",
"node_modules/artplayer/types/playback.d.ts",
"node_modules/artplayer/types/template.d.ts",
"node_modules/artplayer/types/utils.d.ts",
"node_modules/artplayer/types/artplayer.d.ts",
"node_modules/artplayer/types/artplayer.d.cts",
"node_modules/artplayer-plugin-hls-control/types/artplayer-plugin-hls-control.d.ts",
"node_modules/artplayer-plugin-hls-control/types/artplayer-plugin-hls-control.d.cts"
],
"negativeStatements": 8,
"negativeDiagnostics": [
{
"code": 2322,
"line": 28
},
{
"code": 2554,
"line": 30
},
{
"code": 2322,
"line": 32
},
{
"code": 2769,
"line": 34
},
{
"code": 2769,
"line": 36
},
{
"code": 2769,
"line": 38
},
{
"code": 2769,
"line": 40
},
{
"code": 2339,
"line": 42
}
]
},
{
"compiler": "5.9.3",
"mode": "nodenext-esm",
"declarations": [
"node_modules/artplayer/types/component.d.ts",
"node_modules/artplayer/types/config.d.ts",
"node_modules/artplayer/types/emitter.d.ts",
"node_modules/artplayer/types/cssVar.d.ts",
"node_modules/artplayer/types/i18n.d.ts",
"node_modules/artplayer/types/icons.d.ts",
"node_modules/artplayer/types/plugin.d.ts",
"node_modules/artplayer/types/quality.d.ts",
"node_modules/artplayer/types/setting.d.ts",
"node_modules/artplayer/types/subtitle.d.ts",
"node_modules/artplayer/types/option.d.ts",
"node_modules/artplayer/types/player.d.ts",
"node_modules/artplayer/types/events.d.ts",
"node_modules/artplayer/types/playback.d.ts",
"node_modules/artplayer/types/template.d.ts",
"node_modules/artplayer/types/utils.d.ts",
"node_modules/artplayer/types/artplayer.d.ts",
"node_modules/artplayer/types/artplayer.d.cts",
"node_modules/artplayer-plugin-hls-control/types/artplayer-plugin-hls-control.d.ts",
"node_modules/artplayer-plugin-hls-control/types/artplayer-plugin-hls-control.d.cts",
"node_modules/artplayer-plugin-hls-control/types/artplayer-plugin-hls-control.d.mts",
"node_modules/artplayer/types/artplayer.d.mts"
],
"negativeStatements": 8,
"negativeDiagnostics": [
{
"code": 2322,
"line": 28
},
{
"code": 2554,
"line": 30
},
{
"code": 2322,
"line": 32
},
{
"code": 2769,
"line": 34
},
{
"code": 2769,
"line": 36
},
{
"code": 2769,
"line": 38
},
{
"code": 2769,
"line": 40
},
{
"code": 2339,
"line": 42
}
]
},
{
"compiler": "5.9.3",
"mode": "bundler-esm",
"declarations": [
"node_modules/artplayer/types/component.d.ts",
"node_modules/artplayer/types/config.d.ts",
"node_modules/artplayer/types/emitter.d.ts",
"node_modules/artplayer/types/cssVar.d.ts",
"node_modules/artplayer/types/i18n.d.ts",
"node_modules/artplayer/types/icons.d.ts",
"node_modules/artplayer/types/plugin.d.ts",
"node_modules/artplayer/types/quality.d.ts",
"node_modules/artplayer/types/setting.d.ts",
"node_modules/artplayer/types/subtitle.d.ts",
"node_modules/artplayer/types/option.d.ts",
"node_modules/artplayer/types/player.d.ts",
"node_modules/artplayer/types/events.d.ts",
"node_modules/artplayer/types/playback.d.ts",
"node_modules/artplayer/types/template.d.ts",
"node_modules/artplayer/types/utils.d.ts",
"node_modules/artplayer/types/artplayer.d.ts",
"node_modules/artplayer/types/artplayer.d.cts",
"node_modules/artplayer/types/artplayer.d.mts",
"node_modules/artplayer-plugin-hls-control/types/artplayer-plugin-hls-control.d.ts",
"node_modules/artplayer-plugin-hls-control/types/artplayer-plugin-hls-control.d.cts",
"node_modules/artplayer-plugin-hls-control/types/artplayer-plugin-hls-control.d.mts"
],
"negativeStatements": 8,
"negativeDiagnostics": [
{
"code": 2322,
"line": 28
},
{
"code": 2554,
"line": 30
},
{
"code": 2322,
"line": 32
},
{
"code": 2769,
"line": 34
},
{
"code": 2769,
"line": 36
},
{
"code": 2769,
"line": 38
},
{
"code": 2769,
"line": 40
},
{
"code": 2339,
"line": 42
}
]
},
{
"compiler": "4.3.5",
"mode": "node10-commonjs",
"declarations": [
"node_modules/artplayer/types/component.d.ts",
"node_modules/artplayer/types/config.d.ts",
"node_modules/artplayer/types/emitter.d.ts",
"node_modules/artplayer/types/cssVar.d.ts",
"node_modules/artplayer/types/i18n.d.ts",
"node_modules/artplayer/types/icons.d.ts",
"node_modules/artplayer/types/plugin.d.ts",
"node_modules/artplayer/types/quality.d.ts",
"node_modules/artplayer/types/setting.d.ts",
"node_modules/artplayer/types/subtitle.d.ts",
"node_modules/artplayer/types/option.d.ts",
"node_modules/artplayer/types/player.d.ts",
"node_modules/artplayer/types/events.d.ts",
"node_modules/artplayer/types/playback.d.ts",
"node_modules/artplayer/types/template.d.ts",
"node_modules/artplayer/types/utils.d.ts",
"node_modules/artplayer/types/artplayer.d.ts",
"node_modules/artplayer-plugin-hls-control/types/artplayer-plugin-hls-control.d.ts"
],
"negativeStatements": 8,
"negativeDiagnostics": [
{
"code": 2322,
"line": 28
},
{
"code": 2554,
"line": 30
},
{
"code": 2322,
"line": 32
},
{
"code": 2769,
"line": 34
},
{
"code": 2769,
"line": 36
},
{
"code": 2769,
"line": 38
},
{
"code": 2769,
"line": 40
},
{
"code": 2339,
"line": 42
}
]
}
]
}
],
"originalChecks": {
"runtime": 36,
"legacyModes": 5,
"preciseModes": 8,
"knownTypeBlockers": 0,
"knownRuntimeBlockers": 0
},
"validation": [
{
"command": "yarn test:package --browser",
"exitCode": 0,
"seconds": 128.94
},
{
"command": "node --test test/installed-types.test.js",
"exitCode": 0,
"passed": 3
},
{
"command": "node --test test/package-check.test.js",
"exitCode": 0,
"passed": 6
},
{
"command": "yarn test:ci",
"exitCode": 0,
"passed": 77
},
{
"command": "node node_modules/typescript/bin/tsc -p scripts/tsconfig.docs.json --noEmit",
"exitCode": 0
},
{
"command": "node node_modules/eslint/bin/eslint.js scripts/consumers scripts/package-check.mjs test/installed-types.test.js",
"exitCode": 0
}
],
"logs": [
{
"path": "refactor/.cache/ci-types-package.log",
"sha256": "e2976d0ff636f06c75e6618d1bed451785cb19ac793df4dd02467d85f7d243e2"
},
{
"path": "refactor/.cache/ci-types-package-final.log",
"sha256": "8f8197b4ab77c9889e6d7ee22280e089ca24fa326fd5b4e4e9b0ceb0746218c7"
},
{
"path": "refactor/.cache/installed-types-tests.log",
"sha256": "2e1fa29014c38cd9e38a6c801a14901993c655dd4cd0ec583e3da68dd8486757"
},
{
"path": "refactor/.cache/ci-types-package-tests.log",
"sha256": "7e11837cc7fe5c942a1ccb963eea06694e8f66d31941fcc587c71cda72ac7b63"
},
{
"path": "refactor/.cache/ci-types-ci-tests.log",
"sha256": "26ec64ccd8e36a40761c9a8397845b9ea3ad2ab64cd7d7e1c34b44806bd82b43"
}
],
"inputs": {
"scripts/consumers/types.ts": "7ab794eab8bd429dac2e359a2be8c71e54b1e96498af734e20d2bbc7ab620d7c",
"scripts/consumers/packages.ts": "0e3366031f76c0db36cf880ff593377a8e223cb0273a9b439d0146b564c3d178",
"scripts/package-check.mjs": "cf19bbfd6010965e40495a9943f0d6fe9e024d110e22234490f16e7e3d461ac4",
"test/installed-types.test.js": "f16737913edf403e399552ca54cb2edfd032e8bfa193cffd273a67d041e3bd9f",
"test/types/audio-track.ts": "d9c01d2d4cb9ce28da599440f71cafe7b87c8c9521eb4d0c2ce1168ba3d2fde4",
"test/types/hls-control.ts": "3bbdeae926b6a5aad6e5b7c34a21babbc7784007c49d65acc44dac0962ba2b61"
}
}
@@ -0,0 +1,47 @@
# CI-TYPES-01:Audio/HLS 安装后类型消费者
基线 `210484c443077da389e048afb76a229f2b1e56bc`。此前通用 tarball 检查
只执行核心/Chapter 类型,Audio/HLS 的完整正反例仅在仓库内编译。本任务把
这两包实际安装的类型检查接入 `test:package --browser` 和相应 `--include`。
## 实现与兼容边界
`scripts/consumers/types.ts` 负责严格编译、真实路径隔离和逐行负例验证;
`packages.ts` 只选择已安装且明确登记的包,直接复用完整的 `test/types/`
用例并记录 SHA-256。拆分避免每包重复实现编译器循环,也不把其他包的
特殊历史声明用一个空导入 smoke 替代。其余专用 package-types 检查仍保留。
五模式为 TS 5.9.3 node10 CommonJS、NodeNext CommonJS、NodeNext ESM、
bundler ESM,加 TS 4.3.5 node10 CommonJS。旧编译器的一处类型适配仅覆盖
共享 compiler API,不传入新版 resolution 模式。未增加依赖或修改锁文件。
首先保留 `@ts-expect-error` 编译完整正反例;再中和指令、保留行号,要求
每条无效调用所在行实际出现诊断,并拒绝其他位置的诊断。夹具要求指令紧邻
单行无效调用。每个解析文件的 realpath 必须在隔离安装目录内,唯一例外是
选定编译器自身目录下的标准 lib 声明;禁止借用 workspace 链接或外部声明。
Audio 保留根/legacy 的历史参数提取、函数替换和必需 URL,`/runtime`
保留准确的局部 update、HTMLAudioElement 和同步 void;共 12 条无效调用。
HLS 保留根/legacy、历史 Option 提取、自定义轨道泛型和 formatter 的可选
index;共 8 条无效调用。本任务没有改任何生产源码、公开声明或运行时行为。
新模块纳入严格 docs-tools TS 和 lint,测试纳入 test:node。维护说明位于
scripts/consumers/README.md、两包 README、test/package/README.md;影响
说明保持十九包完整安装消费缺口,不把新增类型覆盖当成运行时/浏览器准入。
## 验证与报告
执行命令和最终安装报告摘要见
[机器证据](../baselines/installed-plugin-types-validation.json)。原有报告的
typeScope/runtimeScope 仍表示核心/Chapter,新增 additionalTypeScope 和
pluginTypes 单列两包、编译器、实际声明路径、夹具指纹及负例行号/错误码。
本次没有执行远端 Actions、完整浏览器矩阵、真实设备验收或发布。CI-01、
CI-04 与两包组合验收保持未完成;本任务只关闭安装后的类型检查接入缺口。
安装报告中的 source 是修改前 HEAD,报告与本提交一起解释工作树验证证据,
不宣称提交后精确 HEAD 的浏览器准入。浏览器运行仍须遵守候选新鲜度检查。
## 回退
回退本任务独立提交恢复原通用类型检查范围和脚本入口,生产 API 与依赖不变。
既有包内类型用例继续保留;不需要修改消费者代码或降级运行时包。
+4 -2
View File
@@ -56,8 +56,10 @@ GitHub PR读取事件里的base SHA,push读取before SHA;初次push的全零
- `test:package`当前实际只有core/chapter;脚本读取其names数组核对策略,变更范围
后必须更新声明。其余19个库包完整安装消费仍缺证据,不能因识别为affected而过关。
`--browser` 已单独覆盖十八包安装产物及明确列出的浏览器子集,不扩张这个通用
Node/类型消费者列表,也不等于十八包全部类型/设备/SDK 组合通过。
`--browser` 已单独准备二十包安装产物及明确列出的浏览器子集,不扩张这个通用
Node 消费者列表,也不等于二十包全部类型/设备/SDK 组合通过。Audio/HLS 的额外
五模式安装类型验证由 CI-TYPES-01 接入,报告单列 additionalTypeScope;其余包
的专用类型检查仍保留,不能因此关闭十九包完整安装消费的缺口。
- 覆盖率范围从实际coverage-policy读取;浏览器/性能命令运行已有用例,不代表所有
包、真实设备、远程SDK已验收。
- ENG-COVERAGE-01继续把契约、支持版本、测试ID、候选/报告及任务逐项连接;
+7 -5
View File
@@ -2,9 +2,9 @@
> 由 tasks.json 生成。请修改数据后运行 `node refactor/scripts/plan.mjs --write`,不要手改本表。
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 277 项,范围 22 个包及工作区/示例。
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 278 项,范围 22 个包及工作区/示例。
状态:todo 43 / doing 21 / blocked 0 / done 213 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
状态:todo 43 / doing 21 / blocked 0 / done 214 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。
@@ -18,7 +18,7 @@
| artplayer-plugin-ads | 2.1.0 | PKG-ADS-01, PKG-ADS-02, PKG-ADS-03, PKG-ADS-04, PKG-ADS-05, PKG-ADS-06 |
| artplayer-plugin-ambilight | 1.1.0 | PKG-AMBILIGHT-01, PKG-AMBILIGHT-02, PKG-AMBILIGHT-03, PKG-AMBILIGHT-04, PKG-AMBILIGHT-PROXY-01, PKG-AMBILIGHT-05, PKG-AMBILIGHT-06, PKG-FACTORY-01 |
| artplayer-plugin-asr | 2.1.0 | PKG-ASR-01, PKG-ASR-02, PKG-ASR-03, PKG-ASR-04, PKG-ASR-05, PKG-ASR-06, PKG-ASR-07, PKG-ASR-08, PKG-ASR-09, PKG-ASR-10 |
| artplayer-plugin-audio-track | 1.1.0 | PKG-AUDIO-01, PKG-AUDIO-02, PKG-AUDIO-03, PKG-AUDIO-04, PKG-AUDIO-05, PKG-AUDIO-06, SITE-AUDIO-01 |
| artplayer-plugin-audio-track | 1.1.0 | PKG-AUDIO-01, PKG-AUDIO-02, PKG-AUDIO-03, PKG-AUDIO-04, PKG-AUDIO-05, PKG-AUDIO-06, SITE-AUDIO-01, CI-TYPES-01 |
| artplayer-plugin-auto-thumbnail | 1.1.0 | PKG-AUTO-THUMB-01, PKG-AUTO-THUMB-02, PKG-AUTO-THUMB-03, PKG-AUTO-THUMB-04, PKG-AUTO-THUMB-05, PKG-AUTO-THUMB-06, PKG-AUTO-THUMB-07, PKG-AUTO-THUMB-08, PKG-AUTO-THUMB-09, PKG-AUTO-THUMB-10, PKG-AUTO-THUMB-11, PKG-AUTO-THUMB-12, PKG-AUTO-THUMB-13 |
| artplayer-plugin-chapter | 1.1.0 | PILOT-01, PKG-CHAPTER-01, PKG-CHAPTER-02, PKG-CHAPTER-03, PKG-CHAPTER-04, PKG-CHAPTER-05, PKG-CHAPTER-06, PKG-CHAPTER-HOVER-01 |
| artplayer-plugin-chromecast | 1.1.0 | PKG-CAST-01, PKG-CAST-02, PKG-CAST-03, PKG-CAST-04, PKG-CAST-05, PKG-CAST-06 |
@@ -26,7 +26,7 @@
| artplayer-plugin-danmuku-mask | 1.1.0 | PKG-MASK-01, PKG-MASK-02, PKG-MASK-03, PKG-MASK-04, PKG-MASK-05, PKG-MASK-06, ENG-LINT-01, PKG-DANMUKU-MASK-LOAD-01 |
| artplayer-plugin-dash-control | 1.1.0 | PKG-DASH-01, PKG-DASH-02, PKG-DASH-03, PKG-DASH-04, PKG-DASH-SEEK-01, PKG-DASH-MENU-01, PKG-DASH-05, PKG-DASH-06, SITE-DASH-01, PKG-DASH-CLEANUP-01 |
| artplayer-plugin-document-pip | 1.1.0 | PKG-DPIP-01, PKG-DPIP-02, PKG-DPIP-03, PKG-DPIP-04, PKG-DPIP-05, PKG-DPIP-06 |
| artplayer-plugin-hls-control | 1.1.0 | PKG-HLS-01, PKG-HLS-02, PKG-HLS-03, PKG-HLS-04, PKG-HLS-SDK-01, PKG-HLS-05, PKG-HLS-06, SITE-HLS-01, PKG-HLS-PACK-01 |
| artplayer-plugin-hls-control | 1.1.0 | PKG-HLS-01, PKG-HLS-02, PKG-HLS-03, PKG-HLS-04, PKG-HLS-SDK-01, PKG-HLS-05, PKG-HLS-06, SITE-HLS-01, PKG-HLS-PACK-01, CI-TYPES-01 |
| artplayer-plugin-jassub | 1.1.0 | PKG-JASSUB-01, PKG-JASSUB-02, PKG-JASSUB-03, PKG-JASSUB-04, PKG-JASSUB-05, PKG-JASSUB-06, PKG-JASSUB-07, PKG-JASSUB-08, PKG-JASSUB-09, PKG-JASSUB-10 |
| artplayer-plugin-multiple-subtitles | 1.2.0 | PKG-MULTI-SUB-01, PKG-MULTI-SUB-02, PKG-MULTI-SUB-03, PKG-MULTI-SUB-04, PKG-MULTI-SUB-07, PKG-MULTI-SUB-08, PKG-MULTI-SUB-05, PKG-MULTI-SUB-06, PKG-MULTI-SUB-09, PKG-MULTI-SUB-10, PKG-MULTI-SUB-11 |
| artplayer-plugin-vast | 1.2.0 | PKG-VAST-01, PKG-VAST-02, PKG-VAST-03, PKG-VAST-04, PKG-VAST-05, PKG-VAST-06, PKG-VAST-07, ENG-LINT-02 |
@@ -96,9 +96,10 @@
| CI-01 | workspace<br>增强兼容矩阵、并发缓存与 CI 报告 | DOC-10, ENG-08, ENG-09, ENG-10 | OS/Node/TS/浏览器与影响范围矩阵、缓存、超时、汇总检查和 artifact 报告 | 固定安装、失败/取消不误报、核心影响全生态;检查只读,失败证据可追溯 | H | doing |
| CI-02 | workspace<br>分离并改进 GitHub Pages 部署 | DOC-10, ENG-02, SITE-03 | Pages artifact 部署配置、旧路径/域名核对、预检和迁移恢复指南 | 部署只取受信任已验证产物;本地实现可验收,远端 source/环境和实际部署状态单独登记 | H | done |
| CI-03 | workspace<br>建立 npm 分包候选与发布工作流 | DOC-10, CI-01, REL-08, REL-04, CI-NPM-01 | 候选准备、精确 artifact 发布配置、OIDC 评估、版本/tag/registry 预检和部分失败恢复 | 不自动发布;明确逐包信任前置和 dry run 限制,不能重建未验证内容或重发冲突版本;按版本清单校验各包下一 major 和预发布/正式 tag,保留旧核心支持范围 | H | todo |
| CI-04 | workspace<br>验收 GitHub 流水线与远端发布准入 | CI-01, CI-02, CI-03, SITE-06, CI-BROWSER-01 | 静态/干净环境检查、真实 PR 正反例、候选 dry run、required checks/Pages/npm 必需配置状态及运维指南 | 必要 Actions 证据和远端配置核对齐全;缺失保持未完成,真实 publish/deploy 仍在授权发布步骤执行 | H | todo |
| CI-04 | workspace<br>验收 GitHub 流水线与远端发布准入 | CI-01, CI-02, CI-03, SITE-06, CI-BROWSER-01, CI-TYPES-01 | 静态/干净环境检查、真实 PR 正反例、候选 dry run、required checks/Pages/npm 必需配置状态及运维指南 | 必要 Actions 证据和远端配置核对齐全;缺失保持未完成,真实 publish/deploy 仍在授权发布步骤执行 | H | todo |
| CI-BROWSER-01 | workspace<br>分离源码与已安装产物浏览器验证范围 | ENG-05, ENG-07 | 完整源码入口、明确已安装包子集、分开的报告目录与失败传播 | 混用输入旧红新绿;源码默认保留所有spec,已安装入口严格校验四包来源;两类报告都保留,源码失败不能误报全绿;不代表完整远端或全包验收 | M | done |
| CI-NPM-01 | workspace<br>从已验收候选准备不可重建的npm交付包 | DOC-10, REL-08, REL-04 | 复用严格准入台账、复制精确tarball、绑定源码/工具链/证据/摘要的本地准备命令及反向测试;供CI-03后续受信任artifact工作流使用 | 缺候选或任一准入缺口即拒绝;不构建、不安装、不联网或发布;阻止路径越界、脏源码、复制期间漂移及半成品冒充完成,声明远端信任/OIDC/registry预检仍未实现 | H | done |
| CI-TYPES-01 | workspace, artplayer-plugin-audio-track, artplayer-plugin-hls-control<br>接入 Audio/HLS 安装后严格类型消费者 | ENG-07, PKG-AUDIO-04, PKG-HLS-04 | 共享隔离编译器模块、真实 tarball 的五模式正反例和声明路径证据 | 旧/新编译器所有正例通过,每条无效调用实际报错;仓库外声明解析、缺声明/any/逃逸负例有效;保留独立运行时和浏览器验收 | M | done |
## 2.1 早期试点
@@ -730,3 +731,4 @@
- SITE-VTT-01: [记录](changes/2026-09-15-SITE-VTT-01-guides.md) [记录](baselines/vtt-docs-validation.json)
- PKG-AUTO-THUMB-13: [记录](changes/2026-09-15-PKG-AUTO-THUMB-13-registration.md) [记录](baselines/auto-thumbnail-registration-validation.json)
- SITE-ROUTES-01: [记录](changes/2026-09-15-SITE-ROUTES-01-html-inventory.md) [记录](baselines/site-routes-validation.json)
- CI-TYPES-01: [记录](changes/2026-09-15-CI-TYPES-01-installed-consumers.md) [记录](baselines/installed-plugin-types-validation.json)
+15
View File
@@ -1,5 +1,20 @@
# 进度与证据
## CI-TYPES-01 安装后的 Audio/HLS 类型验证
共享严格编译器模块已接入真实 tarball 消费:Audio 的12条和HLS的8条负例,
在五模式中逐条报错,完整正例均通过。记录实际安装声明路径和夹具SHA-256,
拒绝仓库外链接逃逸、缺声明和any放宽。新模块及两包维护文档同步。
最终20包build/pack/离线安装/冻结重装通过,128.94秒;原核心/Chapter的36项
运行时、5旧类型和8精确类型模式通过。新增3项隔离测试、6项打包回归、77项CI
测试、严格TS与定向lint通过。见[记录](changes/2026-09-15-CI-TYPES-01-installed-consumers.md)
及[证据](baselines/installed-plugin-types-validation.json)。
本次不扩大已验收运行时范围,不代表20包全类型/浏览器/设备或远端CI通过。
CI-04保留原依赖并追加本子项;214 done、21 doing、43 todo,共278。
没有改公开接口、包版本、依赖和锁文件;无推送、部署或发布。
## SITE-ROUTES-01 路径增量台账及完整本地CI
完整ci:check复现最后基线集合1项失败:九个新增指南HTML没有进入历史demo路径台账。
+25 -1
View File
@@ -843,7 +843,8 @@
"CI-02",
"CI-03",
"SITE-06",
"CI-BROWSER-01"
"CI-BROWSER-01",
"CI-TYPES-01"
],
"status": "todo",
"risk": "H",
@@ -5971,6 +5972,29 @@
"changes/2026-09-15-SITE-ROUTES-01-html-inventory.md",
"baselines/site-routes-validation.json"
]
},
{
"id": "CI-TYPES-01",
"phase": "2.2 GitHub CI/CD",
"title": "接入 Audio/HLS 安装后严格类型消费者",
"scope": [
"workspace",
"artplayer-plugin-audio-track",
"artplayer-plugin-hls-control"
],
"dependsOn": [
"ENG-07",
"PKG-AUDIO-04",
"PKG-HLS-04"
],
"status": "done",
"risk": "M",
"deliverable": "共享隔离编译器模块、真实 tarball 的五模式正反例和声明路径证据",
"acceptance": "旧/新编译器所有正例通过,每条无效调用实际报错;仓库外声明解析、缺声明/any/逃逸负例有效;保留独立运行时和浏览器验收",
"evidence": [
"changes/2026-09-15-CI-TYPES-01-installed-consumers.md",
"baselines/installed-plugin-types-validation.json"
]
}
]
}
+35
View File
@@ -0,0 +1,35 @@
# Installed TypeScript consumers
`packages.ts` selects reviewed package fixtures from `test/types/`. It runs only
for packages actually packed and installed by `package-check.mjs`. Adding a
registry entry requires checking the complete fixture against its published type
contract; do not replace historical namespace or overload checks with import-only
smoke tests. Other packages retain their specialized `refactor/scripts/*package-types.mjs`
checks until deliberately integrated.
`types.ts` owns the compiler matrix, strict compiler options, realpath isolation,
and diagnostic accounting. TS 5.9.3 covers node10 CommonJS, NodeNext CommonJS and
ESM, and bundler ESM; TS 4.3.5 covers node10 CommonJS. The single compiler adapter
uses only the shared API and never sends newer resolution modes to TS 4.3.
Both compilers are existing pinned development dependencies; no runtime dependency
is introduced.
Fixtures must use package imports and put each `@ts-expect-error` immediately
before its single-line invalid statement. First compile with directives; then
neutralize directives without moving lines and require diagnostics at every
invalid statement and nowhere else. Missing declarations and widened `any` must
fail. Every parsed file must resolve inside the isolated installation or be a
standard library file from the selected compiler's exact library directory.
The temporary input is removed in `finally`; the caller owns installation cleanup.
Run `yarn test:package --browser` for the installed roster or
`yarn test:package --include=artplayer-plugin-audio-track,artplayer-plugin-hls-control`
for these two additions. `report.json` keeps `typeScope`/`runtimeScope` for the
existing core/chapter checks and separately records `additionalTypeScope` and
`pluginTypes` (compiler modes, installed declaration paths, negative lines/codes).
This type proof does not imply installed runtime or browser acceptance.
Maintain the module with `yarn typecheck:docs-tools`, `yarn lint`, and
`node --test test/installed-types.test.js` (also included in `yarn test:node`).
The tests compile a real isolated package and reject a missing declaration,
`any` widening, and a package link outside the consumer.
+26
View File
@@ -0,0 +1,26 @@
import assert from 'node:assert/strict'
import { createHash } from 'node:crypto'
import fs from 'node:fs'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import { checkTypeFixture, typeMatrix } from './types.ts'
const fixtures: Record<string, string> = {
'artplayer-plugin-audio-track': 'audio-track.ts',
'artplayer-plugin-hls-control': 'hls-control.ts',
}
export function installedPluginTypes(directory: string, packages: string[]) {
const results = []
for (const name of packages) {
const fixture = fixtures[name]
if (!fixture)
continue
const source = fs.readFileSync(fileURLToPath(new URL(`../../test/types/${fixture}`, import.meta.url)), 'utf8')
const modes = typeMatrix.map(({ compiler, mode }) => checkTypeFixture(directory, source, compiler, mode))
for (const result of modes)
assert(result.declarations.some(file => file.startsWith(`node_modules/${name}/`)), `Missing installed declaration for ${name}`)
results.push({ name, fixture: path.posix.join('test/types', fixture), fixtureSha256: createHash('sha256').update(source).digest('hex'), modes })
}
return results
}
+71
View File
@@ -0,0 +1,71 @@
import assert from 'node:assert/strict'
import fs from 'node:fs'
import path from 'node:path'
import ts from 'typescript'
import compat from 'typescript-compat'
type Mode = 'node10-commonjs' | 'nodenext-cjs' | 'nodenext-esm' | 'bundler-esm'
// Both pinned compilers provide this stable API; newer resolution modes never
// reach TS 4.3. Keep the version boundary here, outside consumer fixtures.
export const typeMatrix: { compiler: typeof ts, mode: Mode }[] = [
...(['node10-commonjs', 'nodenext-cjs', 'nodenext-esm', 'bundler-esm'] as const).map(mode => ({ compiler: ts, mode })),
{ compiler: compat as unknown as typeof ts, mode: 'node10-commonjs' },
]
function inside(root: string, file: string) {
const relative = path.relative(root, file)
return relative === '' || (!relative.startsWith(`..${path.sep}`) && relative !== '..' && !path.isAbsolute(relative))
}
export function checkTypeFixture(directory: string, source: string, compiler: typeof ts, mode: Mode) {
const root = fs.realpathSync(directory)
const next = mode.startsWith('nodenext')
const extension = next ? mode.endsWith('-cjs') ? 'cts' : 'mts' : 'ts'
const file = path.join(root, `installed-consumer.${extension}`)
const options: ts.CompilerOptions = {
strict: true,
noEmit: true,
skipLibCheck: false,
types: [],
esModuleInterop: true,
target: compiler.ScriptTarget.ES2020,
lib: ['lib.es2020.d.ts', 'lib.dom.d.ts'],
module: next ? compiler.ModuleKind.NodeNext : mode === 'bundler-esm' ? compiler.ModuleKind.ESNext : compiler.ModuleKind.CommonJS,
moduleResolution: next ? compiler.ModuleResolutionKind.NodeNext : mode === 'bundler-esm' ? compiler.ModuleResolutionKind.Bundler : compiler.ModuleResolutionKind.NodeJs,
}
const library = fs.realpathSync(path.dirname(compiler.getDefaultLibFilePath(options)))
function compile(text: string) {
fs.writeFileSync(file, text)
const program = compiler.createProgram([file], options)
const declarations: string[] = []
for (const input of program.getSourceFiles()) {
const resolved = fs.realpathSync(input.fileName)
const standard = path.dirname(resolved) === library && /^lib\..*\.d\.ts$/.test(path.basename(resolved))
assert(inside(root, resolved) || standard, `Consumer input escaped installation: ${resolved}`)
if (input.isDeclarationFile && !standard)
declarations.push(path.relative(root, resolved).replaceAll('\\', '/'))
}
const diagnostics = compiler.getPreEmitDiagnostics(program).map(diagnostic => ({
code: diagnostic.code,
file: diagnostic.file ? fs.realpathSync(diagnostic.file.fileName) : null,
line: diagnostic.file && diagnostic.start !== undefined ? diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start).line + 1 : null,
message: compiler.flattenDiagnosticMessageText(diagnostic.messageText, '\n'),
}))
return { declarations, diagnostics }
}
try {
const valid = compile(source)
assert.deepEqual(valid.diagnostics, [], `Valid installed consumer failed (${compiler.version}/${mode})`)
const expected = source.split(/\r?\n/).flatMap((line, index) => line.includes('@ts-expect-error') ? [index + 2] : [])
assert(expected.length > 0, 'Consumer needs negative statements')
// Preserve lines so every intentionally invalid call must fail at its own location.
const invalid = compile(source.replaceAll('@ts-expect-error', 'expected type error'))
assert(invalid.diagnostics.every(diagnostic => diagnostic.file === file && expected.includes(diagnostic.line ?? 0)), 'Unexpected negative consumer diagnostics')
assert.deepEqual([...new Set(invalid.diagnostics.map(diagnostic => diagnostic.line))].sort((a, b) => a! - b!), expected, 'Every invalid consumer statement must be rejected')
return { compiler: compiler.version, mode, declarations: valid.declarations, negativeStatements: expected.length, negativeDiagnostics: invalid.diagnostics.map(({ code, line }) => ({ code, line })) }
}
finally {
fs.rmSync(file, { force: true })
}
}
+6
View File
@@ -6,6 +6,7 @@ import process from 'node:process'
import { fileURLToPath } from 'node:url'
import { ensureArchive, hash, readMember } from '../refactor/scripts/releases.mjs'
import { installedPackages } from './browser-validation/scope.ts'
import { installedPluginTypes } from './consumers/packages.ts'
import { consumerDirectory, names as defaultNames, readJson, removeConsumer, run, runtimeConsumer, typeConsumers, workspace, writeJson } from './package-consumer.mjs'
export function packageOptions(args) {
@@ -179,15 +180,20 @@ export async function checkPackages({ release = false, include = [] } = {}) {
assert.deepEqual(runtime.observations.api, oldRuntime.observations.api, 'Published API shape/defaults changed')
const types = typeConsumers(installed)
const preciseTypes = typeConsumers(installed, { precise: true })
const pluginTypes = installedPluginTypes(installed, include)
const source = execFileSync('git', ['rev-parse', 'HEAD'], { cwd: workspace, encoding: 'utf8' }).trim()
const publishedPackages = baseline.releases.map(({ name, version, files }) => ({ name, version, files }))
const report = { task: 'ENG-07', capturedAt: new Date().toISOString(), source, toolchain: { yarn: '1.22.22', yarnPath: yarn }, node: process.versions.node, packages, runtimeScope: defaultNames, typeScope: defaultNames, additionalBrowserPackages: include, runtime, publishedPackages, publishedRuntime: oldRuntime, types, preciseTypes, knownRuntimeBlockers: runtime.observations.defaultsWithoutNavigator.resolved ? 0 : 1, knownTypeBlockers: [...types, ...preciseTypes].reduce((sum, result) => sum + result.diagnostics.length, 0) }
report.additionalTypeScope = pluginTypes.map(result => result.name)
report.pluginTypes = pluginTypes
writeJson(path.join(output, 'report.json'), report)
writeJson(path.join(output, 'browser-artifacts.json'), artifacts)
writeJson(path.join(parent, 'latest.json'), { output: path.relative(workspace, output).replaceAll('\\', '/') })
console.log(`Installed tarball contracts passed: ${runtime.checks.length} runtime checks; ${types.filter(t => !t.diagnostics.length).length}/${types.length} legacy type modes; ${preciseTypes.filter(t => !t.diagnostics.length).length}/${preciseTypes.length} precise type modes. Report: ${output}`)
if (include.length)
console.log(`Runtime/type fixture scope: ${defaultNames.join(', ')}. Additional packages require their own consumer and browser acceptance: ${include.join(', ')}.`)
if (pluginTypes.length)
console.log(`Additional installed type fixtures passed: ${pluginTypes.map(result => result.name).join(', ')}; five compiler modes with checked negative statements per package. Runtime/browser acceptance remains separate.`)
if (release) {
assert.equal(report.knownTypeBlockers, 0, 'Known type blockers remain; this candidate is not release-ready')
assert.equal(report.knownRuntimeBlockers, 0, 'Known runtime blockers remain; this candidate is not release-ready')
+1
View File
@@ -13,6 +13,7 @@
"checkJs": true
},
"include": [
"consumers/**/*.ts",
"docs-smoke/**/*.ts",
"build-test.js",
"build-ts.js",
+64
View File
@@ -0,0 +1,64 @@
import assert from 'node:assert/strict'
import fs from 'node:fs'
import path from 'node:path'
import process from 'node:process'
// eslint-disable-next-line test/no-import-node-test -- Exercises the repository's isolated compiler runner.
import { test } from 'node:test'
import { checkTypeFixture, typeMatrix } from '../scripts/consumers/types.ts'
import { consumerDirectory, removeConsumer } from '../scripts/package-consumer.mjs'
const source = `import { update } from 'fixture'
update('video.mp4')
// @ts-expect-error URL must stay a string.
update(123)
`
function setup(declaration = 'export declare function update(url: string): void') {
const dir = consumerDirectory()
const pkg = path.join(dir, 'node_modules/fixture')
fs.mkdirSync(pkg, { recursive: true })
fs.writeFileSync(path.join(pkg, 'package.json'), JSON.stringify({ name: 'fixture', types: 'index.d.ts' }))
fs.writeFileSync(path.join(pkg, 'index.d.ts'), declaration)
return { dir, pkg }
}
test('Isolated consumer validates real declarations and each negative call in all five compiler modes', () => {
const { dir } = setup()
try {
for (const { compiler, mode } of typeMatrix) {
const result = checkTypeFixture(dir, source, compiler, mode)
assert.deepEqual(result.declarations, ['node_modules/fixture/index.d.ts'])
assert.deepEqual(result.negativeDiagnostics, [{ code: 2345, line: 4 }])
assert.equal(result.negativeStatements, 1)
}
}
finally { removeConsumer(dir) }
})
test('Missing declarations and accidental any widening fail installed consumer validation', () => {
const { dir, pkg } = setup()
const { compiler, mode } = typeMatrix[0]
try {
fs.rmSync(path.join(pkg, 'index.d.ts'))
assert.throws(() => checkTypeFixture(dir, source, compiler, mode), /Valid installed consumer failed/)
fs.writeFileSync(path.join(pkg, 'index.d.ts'), 'export declare function update(url: any): void')
assert.throws(() => checkTypeFixture(dir, source, compiler, mode), /Valid installed consumer failed/)
}
finally { removeConsumer(dir) }
})
test('A declaration reached through an external package link cannot silently satisfy the consumer', () => {
const { dir } = setup()
const external = consumerDirectory()
const { compiler, mode } = typeMatrix[0]
try {
fs.writeFileSync(path.join(external, 'index.d.ts'), 'export declare const value: string')
fs.symlinkSync(external, path.join(dir, 'node_modules/external'), process.platform === 'win32' ? 'junction' : 'dir')
assert.throws(() => checkTypeFixture(dir, `import { value } from 'external'\n${source}\nvoid value`, compiler, mode), /escaped installation/)
}
finally {
fs.unlinkSync(path.join(dir, 'node_modules/external'))
removeConsumer(dir)
removeConsumer(external)
}
})
+8 -1
View File
@@ -19,13 +19,20 @@ browser scope and the remaining package-specific release gates.
Run `yarn test:package` with the pinned Node and Yarn after a frozen install. The
default consumer scope is core and chapter. For the shared installed browser scope,
run `yarn test:package --browser`.
These four additional packages have reviewed published contracts and use the same
The additional packages have reviewed published contracts and use the same
source snapshot/build/pack/offline-install/frozen-reinstall pipeline. Installed
files are copied only after archive hash checks. The report explicitly separates
the core/chapter runtime/type scope from the additional browser package scope;
`--release` rejects additional packages until complete consumer coverage exists.
Other packages need a reviewed contract and their own consumers before inclusion.
Audio Track and HLS Control also run their complete `test/types/` fixtures against
the installed tarballs in five compiler modes, with every invalid call checked
again after removing error directives. `additionalTypeScope` and `pluginTypes`
record this separately from the original core/chapter checks. Other additional
packages still need their dedicated type consumers; no extra runtime scope is
implied. See [compiler module maintenance](../../scripts/consumers/README.md).
`scripts/package-check.mjs` copies source into an ignored build snapshot, rebuilds
all three formats and core languages using repository scripts, and runs Yarn pack.
It checks manifest targets, historical distribution files, archive members and