refactor(vast): [PKG-VAST-04] retain published types and add accurate runtime declarations

This commit is contained in:
Harvey Zhao committed 2026-09-14 23:07:52 +08:00
1 parent c162d2b3b3
commit e5c73fa620
34 files changed
+7819 -1495

No files matched your search

+7 -2
View File
@@ -44,13 +44,18 @@ package consumer tests still use them. Core retains its existing bundler and
private definitions namespace. Plugins preserve callable/default aliases and
exported type namespaces. Unsupported imports/re-exports and invalid syntax fail.
VAST's `Player` and `PlayerOptions` come from the installed, lockfile-pinned
Historical workspace VAST's `Player` and `PlayerOptions` come from the installed, lockfile-pinned
`@glomex/vast-ima-player` 1.21.2 and `@alugha/ima` 2.1.0 declarations. A dedicated
type-only SDK entry avoids bundling a second copy of the linked workspace core.
SDK types stay in the plugin's module-private definitions namespace, not global
runtime values. The optional Window hook and required callback remain unchanged.
Adjacent generated `artplayer-plugin-vast.LICENSE.txt` preserves upstream notices.
This does not settle VAST's runtime default-behavior compatibility decision.
PKG-VAST-04 restores the published npm1.0.0 root declaration and editor global under
the user's explicit type decision. The CommonJS generator supports its inline factory
and module-private aliases, preserving the old required callback and field types.
Current root generation does not expose the workspace SDK types or Window augmentation;
the historical fixture still verifies that generator path. Accurate module consumers use
VAST's `/runtime` declarations. Real IMA verification remains separate.
The editor loads 22 declarations: core, 20 ecosystem libraries and i18n. The
unreferenced legacy `artplayer-plugin-websr.d.ts` asset is not in the canonical
+11 -5
View File
@@ -121,6 +121,7 @@ function generateCommonJSPluginEditor(source: ts.SourceFile, name: string) {
let exported = false
let global = false
let classExport = false
let inlineFactory = false
for (const node of source.statements) {
if (ts.isImportDeclaration(node)) {
assert(ts.isStringLiteral(node.moduleSpecifier) && node.importClause?.isTypeOnly && !node.importClause.namedBindings && node.importClause.name?.text === 'Artplayer' && node.moduleSpecifier.text === 'artplayer', 'Unsupported CommonJS plugin editor import')
@@ -142,10 +143,14 @@ function generateCommonJSPluginEditor(source: ts.SourceFile, name: string) {
const definition = definitions[0]
assert(definition && ts.isIdentifier(definition.name) && definition.type)
assert.equal(definition.name.text, name)
assert(ts.isTypeReferenceNode(definition.type) && ts.isQualifiedName(definition.type.typeName)
&& ts.isIdentifier(definition.type.typeName.left) && definition.type.typeName.left.text === name && definition.type.typeName.right.text === 'Factory', 'Editor export must use its public Factory interface')
inlineFactory = ts.isFunctionTypeNode(definition.type)
assert(inlineFactory || (ts.isTypeReferenceNode(definition.type) && ts.isQualifiedName(definition.type.typeName)
&& ts.isIdentifier(definition.type.typeName.left) && definition.type.typeName.left.text === name && definition.type.typeName.right.text === 'Factory'), 'Editor export must use its public Factory interface or an inline function type')
callable = true
}
else if (ts.isTypeAliasDeclaration(node) || ts.isInterfaceDeclaration(node)) {
assert(!node.modifiers?.some(modifier => modifier.kind === ts.SyntaxKind.ExportKeyword), 'CommonJS local types must remain private')
}
else if (ts.isExportAssignment(node)) {
assert(node.isExportEquals && ts.isIdentifier(node.expression) && node.expression.text === name, 'Unexpected CommonJS plugin export')
exported = true
@@ -159,10 +164,11 @@ function generateCommonJSPluginEditor(source: ts.SourceFile, name: string) {
}
statements.push(node)
}
assert(namespace && callable && exported && global, 'Incomplete CommonJS plugin editor declaration')
assert((namespace || inlineFactory) && callable && exported && global, 'Incomplete CommonJS plugin editor declaration')
const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed })
const bridge = classExport ? '' : '/* eslint-disable ts/no-redeclare -- Callable and public type namespace intentionally merge. */\n'
return `// Generated from the package public declaration by yarn build:ts. Do not edit.\n${bridge}${statements.map(node => printer.printNode(ts.EmitHint.Unspecified, node, source)).join('\n')}\n`
const bridge = classExport || !namespace ? '' : '/* eslint-disable ts/no-redeclare -- Callable and public type namespace intentionally merge. */\n'
const historical = inlineFactory ? '/* eslint-disable ts/no-use-before-define, ts/consistent-type-definitions -- Preserve historical export ordering and private aliases. */\n' : ''
return `// Generated from the package public declaration by yarn build:ts. Do not edit.\n${bridge}${historical}${statements.map(node => printer.printNode(ts.EmitHint.Unspecified, node, source)).join('\n')}\n`
}
export function checkPluginEditorDeclaration(code: string, core: string, consumer = '', compiler: typeof ts = ts) {
+2
View File
@@ -74,6 +74,8 @@ export function runTypechecks() {
console.log(`Strict project passed: ${relative(config)} (${result.files.length} root files)`)
}
for (const [compiler, mode] of [[ts, 'node10-commonjs'], [ts, 'nodenext-cjs'], [ts, 'bundler-esm'], [ts, 'nodenext-esm'], [compat, 'node10-commonjs']]) {
for (const fixture of ['test/types/vast-runtime.ts', 'refactor/fixtures/consumers/vast-published.ts'])
assert.deepEqual(checkConsumer(compiler, mode, fs.readFileSync(path.join(root, fixture), 'utf8')), [], `VAST consumer failed: TS ${compiler.version} ${mode}`)
for (const source of [autoThumbnailPublic(mode), autoThumbnailRuntime(mode)])
assert.deepEqual(checkConsumer(compiler, mode, source), [], `Auto Thumbnail consumer failed: TS ${compiler.version} ${mode}`)
for (const fixture of ['test/types/asr-public.ts', mode === 'nodenext-esm' ? 'refactor/fixtures/consumers/asr-esm-namespace.ts' : 'refactor/fixtures/consumers/asr-published.ts']) {