Skip to content

Commit

Permalink
fix: resolve "~/core" import for .d.mts modules (#2095)
Browse files Browse the repository at this point in the history
  • Loading branch information
kettanaito authored Mar 17, 2024
1 parent a16c999 commit 7cdbd1a
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 20 deletions.
18 changes: 13 additions & 5 deletions config/replaceCoreImports.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
function replaceCoreImports(fileContents, isEsm) {
const importPattern = isEsm
? /from ["'](~\/core(.*))["'](;)?$/gm
: /require\(["'](~\/core(.*))["']\)(;)?/gm
const CORE_ESM_IMPORT_PATTERN = /from ["'](~\/core(.*))["'](;)?/gm
const CORE_CJS_IMPORT_PATTERN = /require\(["'](~\/core(.*))["']\)(;)?/gm

function getCoreImportPattern(isEsm) {
return isEsm ? CORE_ESM_IMPORT_PATTERN : CORE_CJS_IMPORT_PATTERN
}

function hasCoreImports(fileContents, isEsm) {
return getCoreImportPattern(isEsm).test(fileContents)
}

function replaceCoreImports(fileContents, isEsm) {
return fileContents.replace(
importPattern,
getCoreImportPattern(isEsm),
(_, __, maybeSubmodulePath, maybeSemicolon) => {
const submodulePath = maybeSubmodulePath || '/index'
const semicolon = maybeSemicolon || ''
Expand All @@ -17,5 +24,6 @@ function replaceCoreImports(fileContents, isEsm) {
}

module.exports = {
hasCoreImports,
replaceCoreImports,
}
107 changes: 92 additions & 15 deletions config/scripts/patch-ts.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,106 @@
const fs = require('fs')
const path = require('path')
const { replaceCoreImports } = require('../replaceCoreImports')
const fs = require('node:fs')
const { exec } = require('node:child_process')
const path = require('node:path')
const { promisify } = require('node:util')
const { invariant } = require('outvariant')
const glob = require('glob')
const { hasCoreImports, replaceCoreImports } = require('../replaceCoreImports')

const execAsync = promisify(exec)

const BUILD_DIR = path.resolve(__dirname, '../../lib')

async function patchTypeDefs() {
const typeDefsPaths = [
path.resolve(__dirname, '../..', 'lib/browser/index.d.ts'),
path.resolve(__dirname, '../..', 'lib/node/index.d.ts'),
path.resolve(__dirname, '../..', 'lib/native/index.d.ts'),
]
const typeDefsPaths = glob.sync('**/*.d.{ts,mts}', {
cwd: BUILD_DIR,
absolute: true,
})
const typeDefsWithCoreImports = typeDefsPaths
.map((modulePath) => {
const fileContents = fs.readFileSync(modulePath, 'utf8')
if (hasCoreImports(fileContents, true)) {
return [modulePath, fileContents]
}
})
.filter(Boolean)

for (const typeDefsPath of typeDefsPaths) {
if (!fs.existsSync(typeDefsPath)) {
continue
}
if (typeDefsWithCoreImports.length === 0) {
console.log(
'Found no .d.ts modules containing the "~/core" import, skipping...',
)
return process.exit(0)
}

const fileContents = fs.readFileSync(typeDefsPath, 'utf8')
console.log(
'Found %d module(s) with the "~/core" import, resolving...',
typeDefsWithCoreImports.length,
)

for (const [typeDefsPath, fileContents] of typeDefsWithCoreImports) {
// Treat ".d.ts" files as ESM to replace "import" statements.
// Force no extension on the ".d.ts" imports.
const nextFileContents = replaceCoreImports(fileContents, true)

fs.writeFileSync(typeDefsPath, nextFileContents, 'utf8')
console.log('Successfully patched "%s"!', typeDefsPath)
}

console.log(
'Imports resolved in %d file(s), verifying...',
typeDefsWithCoreImports.length,
)

// Next, validate that we left no "~/core" imports unresolved.
const result = await execAsync(
`grep "~/core" ./**/*.{ts,mts} -R -l || exit 0`,
{
cwd: BUILD_DIR,
shell: '/bin/bash',
},
)

invariant(
result.stderr === '',
'Failed to validate the .d.ts modules for the presence of the "~/core" import. See the original error below.',
result.stderr,
)

console.log('Successfully patched at "%s"!', typeDefsPath)
if (result.stdout !== '') {
const modulesWithUnresolvedImports = result.stdout
.split('\n')
.filter(Boolean)

console.error(
`Found .d.ts modules containing unresolved "~/core" import after the patching:
${modulesWithUnresolvedImports.map((path) => ` - ${path}`).join('\n')}
`,
)

return process.exit(1)
}

// Ensure that the .d.ts files compile without errors after resolving the "~/core" imports.
console.log('Compiling the .d.ts modules with tsc...')
const tscCompilation = await execAsync(
`tsc --noEmit --skipLibCheck ${typeDefsPaths.join(' ')}`,
{
cwd: BUILD_DIR,
},
)

if (tscCompilation.stderr !== '') {
console.error(
'Failed to compile the .d.ts modules with tsc. See the original error below.',
tscCompilation.stderr,
)

return process.exit(1)
}

console.log(
'The "~/core" imports resolved successfully in %d .d.ts modules! 🎉',
typeDefsWithCoreImports.length,
)
}

patchTypeDefs()

0 comments on commit 7cdbd1a

Please sign in to comment.