import type * as d from '../../declarations' ; import { getAbsoluteBuildDir } from './html-utils' ; import { generateHashedCopy } from '../output-targets/copy/hashed-copy' ; import { injectModulePreloads } from './inject-module-preloads' ; import { isString } from '@utils' ; import { join } from 'path' ; import ts from 'typescript' ; export const optimizeEsmImport = async ( config , compilerCtx , doc , outputTarget ) => { const resourcesUrl = getAbsoluteBuildDir ( outputTarget ) ; const entryFilename = `${ config . fsNamespace }.esm.js` ; const expectedSrc = join ( resourcesUrl , entryFilename ) ; const script = Array . from ( doc . querySelectorAll ( 'script' ) ) . find ( ( s ) => s . getAttribute ( 'type' ) === 'module' && ! s . hasAttribute ( 'crossorigin' ) && s . getAttribute ( 'src' ) === expectedSrc ) ; if ( ! script ) { return false ; } script . setAttribute ( 'data-resources-url' , resourcesUrl ) ; script . setAttribute ( 'data-stencil-namespace' , config . fsNamespace ) ; const entryPath = join ( outputTarget . buildDir , entryFilename ) ; const content = await compilerCtx . fs . readFile ( entryPath ) ; if ( isString ( content ) ) { if ( config . allowInlineScripts && content . length < MAX_JS_INLINE_SIZE ) { const results = updateImportPaths ( content , resourcesUrl ) ; if ( results . orgImportPaths . length > 0 ) { script . removeAttribute ( 'src' ) ; script . innerHTML = results . code ; } } else { const hashedFile = await generateHashedCopy ( config , compilerCtx , entryPath ) ; if ( hashedFile ) { const hashedPath = join ( resourcesUrl , hashedFile ) ; script . setAttribute ( 'src' , hashedPath ) ; injectModulePreloads ( doc , [ hashedPath ] ) ; } } return true ; } return false ; } ; export const updateImportPaths = ( code , newDir ) => { const orgImportPaths = [ ] ; const tsSourceFile = ts . createSourceFile ( 'module.ts' , code , ts . ScriptTarget . Latest ) ; ts . transform ( tsSourceFile , [ readImportPaths ( orgImportPaths ) ] ) ; orgImportPaths . forEach ( ( orgImportPath ) => { const newPath = replacePathDir ( orgImportPath , newDir ) ; if ( newPath ) { code = code . replace ( `"${ orgImportPath }"` , `"${ newPath }"` ) ; code = code . replace ( `'${ orgImportPath }'` , `'${ newPath }'` ) ; } } ) ; return { code , orgImportPaths , } ; } ; const replacePathDir = ( orgImportPath , newDir ) => { if ( orgImportPath . startsWith ( './' ) && ( orgImportPath . endsWith ( '.js' ) || orgImportPath . endsWith ( '.mjs' ) ) ) { return newDir + orgImportPath . substring ( 2 ) ; } return null ; } ; const readImportPaths = ( orgImportPaths ) : ts . TransformerFactory < ts . SourceFile > => { return ( ) => { return ( tsSourceFile ) => { const importStatements = tsSourceFile . statements . filter ( ts . isImportDeclaration ) . filter ( ( s ) => s . moduleSpecifier != null ) . filter ( ( s ) => ts . isStringLiteral ( s . moduleSpecifier ) && s . moduleSpecifier . text ) ; importStatements . forEach ( ( s ) => { if ( ts . isStringLiteral ( s . moduleSpecifier ) ) { orgImportPaths . push ( s . moduleSpecifier . text ) ; } } ) ; return tsSourceFile ; } ; } ; } ; const MAX_JS_INLINE_SIZE = 1 * 1024 ;