diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 40a1b0e2f..1078d25a7 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -14,7 +14,7 @@ jobs: - uses: actions/checkout@v1 - uses: actions/setup-node@v1 with: - node-version: '18.x' + node-version: '20.17.x' - name: Generate docs run: | yarn install --frozen-lockfile @@ -32,7 +32,7 @@ jobs: - uses: actions/checkout@v1 - uses: actions/setup-node@v1 with: - node-version: '18.x' + node-version: '20.17.x' - uses: webfactory/ssh-agent@v0.5.0 with: ssh-private-key: ${{ secrets.GH_PAGES_DEPLOY }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e0d0fd7fa..408bd8e7b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,10 +16,10 @@ jobs: # This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commits fetch-depth: 0 - - name: Setup Node.js 18.x + - name: Setup Node.js 20.17.x uses: actions/setup-node@master with: - node-version: 18.x + node-version: 20.17.x - name: Install Dependencies run: yarn diff --git a/.github/workflows/test-integration.yml b/.github/workflows/test-integration.yml index 1d837ea44..e8d7fe76d 100644 --- a/.github/workflows/test-integration.yml +++ b/.github/workflows/test-integration.yml @@ -11,7 +11,7 @@ jobs: strategy: matrix: - node-version: [18.x] + node-version: [20.17.x] steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 10ac8775c..92006ba04 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,7 +12,7 @@ jobs: strategy: matrix: - node-version: [18.x] + node-version: [20.17.x] steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 7490c1944..2d04e937e 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -12,7 +12,7 @@ jobs: strategy: matrix: - node-version: [18.x] + node-version: [20.17.x] steps: - uses: actions/checkout@v2 diff --git a/.nvmrc b/.nvmrc index 3f430af82..016e34baf 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v18 +v20.17.0 diff --git a/jest.config.js b/jest.config.js index 239ff437c..3328b83a6 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,4 +1,5 @@ module.exports = { + testEnvironment: 'node', transform: { '^.+\\.ts$': [ 'ts-jest', diff --git a/packages/cli-alias/package.json b/packages/cli-alias/package.json index 3f2cb49c0..7f3be955c 100644 --- a/packages/cli-alias/package.json +++ b/packages/cli-alias/package.json @@ -19,6 +19,6 @@ "ts-node": "^10.9.1" }, "engines": { - "node": ">=14" + "node": ">=20" } } diff --git a/packages/cli/package.json b/packages/cli/package.json index 0d4b9a08a..05691d122 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -29,13 +29,13 @@ "fs-extra": "^9.1.0", "inquirer": "^8.2.4", "jscodeshift": "^0.13.1", - "live-plugin-manager": "^0.18.1", "lodash": "^4.17.21", "ora": "^5.4.1", "semver": "^7.3.5", - "ts-node": "^10.9.1" + "ts-node": "^10.9.1", + "tsx": "^4.19.1" }, "engines": { - "node": ">=14" + "node": ">=20" } } diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index 869a3ad87..bf70b4057 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -66,10 +66,6 @@ program '--registryToken ', 'Define an authentication token to use as credentials for the registry', ) - .option( - '--experimental-loader', - 'Enables the experimental package downloader', - ) .addOption( new Option( '--verbose ', diff --git a/packages/cli/src/list.ts b/packages/cli/src/list.ts index 2b677dd8c..1a3ebd7c6 100644 --- a/packages/cli/src/list.ts +++ b/packages/cli/src/list.ts @@ -1,19 +1,14 @@ import chalk from 'chalk'; -import { PluginManager } from 'live-plugin-manager'; import { fetchPackages } from './utils/fetch-package'; import { getHypermodPackageName } from './utils/package-names'; export default async function list(packages: string[]) { - const packageManager = new PluginManager(); const configs = []; for (const packageName of packages) { try { - const { community, remote } = await fetchPackages( - packageName, - packageManager, - ); + const { community, remote } = await fetchPackages(packageName); community && configs.push({ packageName: getHypermodPackageName(packageName), diff --git a/packages/cli/src/main.ts b/packages/cli/src/main.ts index 1f7efc04d..c5a188970 100644 --- a/packages/cli/src/main.ts +++ b/packages/cli/src/main.ts @@ -1,11 +1,7 @@ -import path from 'path'; import semver from 'semver'; import chalk from 'chalk'; import findUp from 'find-up'; import inquirer from 'inquirer'; -import fs from 'fs-extra'; -import { PluginManager, PluginManagerOptions } from 'live-plugin-manager'; -import { installPackage } from '@antfu/install-pkg'; import * as core from '@hypermod/core'; import { fetchConfigAtPath } from '@hypermod/fetcher'; @@ -16,54 +12,7 @@ import { mergeConfigs } from './utils/merge-configs'; import { fetchConfigsForWorkspaces, getPackageJson } from './utils/file-system'; import { getConfigPrompt, getMultiConfigPrompt } from './prompt'; -const ExperimentalModuleLoader = () => { - const getInfo = (packageName: string) => { - const entryPath = require.resolve(packageName); - const location = entryPath.split(packageName)[0] + packageName; - const pkgJsonRaw = fs.readFileSync( - path.join(location, 'package.json'), - 'utf8', - ); - const pkgJson = JSON.parse(pkgJsonRaw); - - return { - location, - entryPath, - pkgJson, - }; - }; - - const install = async (packageName: string) => { - await installPackage(packageName, { - cwd: __dirname, - packageManager: 'npm', - additionalArgs: ['--force'], - }); - - const { pkgJson } = getInfo(packageName); - - // Install whitelisted devDependencies - if (pkgJson?.hypermod?.dependencies) { - await Promise.all( - pkgJson.hypermod.dependencies.map((dep: string) => { - const version = pkgJson.devDependencies[dep]; - if (!version) return; - return installPackage(`${dep}@${version}`, { - cwd: __dirname, - packageManager: 'npm', - additionalArgs: ['--force'], - }); - }), - ); - } - }; - - return { - install, - getInfo, - require: (packageName: string) => require(packageName), - }; -}; +import ModuleLoader from './utils/module-loader'; export default async function main( paths: string[], @@ -75,25 +24,10 @@ export default async function main( ); } - const pluginManagerConfig: Partial = { - pluginsPath: path.join(__dirname, '..', 'node_modules'), - }; - - // If a registry is provided in the CLI flags, use it for the pluginManagers configuration. - if (flags.registry !== undefined) { - pluginManagerConfig.npmRegistryUrl = flags.registry; - } - - // If a registryToken is provided in the CLI flags, use it as an authentication token for the pluginManager - if (flags.registryToken !== undefined) { - pluginManagerConfig.npmRegistryConfig = { - auth: { token: flags.registryToken }, - }; - } - - const packageManager = flags.experimentalLoader - ? ExperimentalModuleLoader() - : new PluginManager(pluginManagerConfig); + const moduleLoader = ModuleLoader({ + npmRegistryUrl: flags.registry, + authToken: flags.registryToken, + }); let transforms: string[] = []; @@ -233,11 +167,7 @@ export default async function main( .filter(id => id.startsWith('#')) .map(id => id.substring(1)); - const { community, remote } = await fetchPackages( - pkgName, - // @ts-expect-error Experimental loader - packageManager, - ); + const { community, remote } = await fetchPackages(pkgName, moduleLoader); const config = mergeConfigs(community, remote); diff --git a/packages/cli/src/utils/fetch-package.ts b/packages/cli/src/utils/fetch-package.ts index 83ffd2ef4..a22b1d44a 100644 --- a/packages/cli/src/utils/fetch-package.ts +++ b/packages/cli/src/utils/fetch-package.ts @@ -1,6 +1,5 @@ import ora from 'ora'; import chalk from 'chalk'; -import { PluginManager } from 'live-plugin-manager'; import { fetchPackage, @@ -10,10 +9,11 @@ import { import { isValidConfig } from '@hypermod/validator'; import { getHypermodPackageName } from './package-names'; +import ModuleLoader from './module-loader'; export async function fetchPackages( packageName: string, - packageManager: PluginManager, + moduleLoader: ReturnType, ) { const hypermodPackageName = getHypermodPackageName(packageName); let hypermodPackage: ConfigMeta | undefined; @@ -24,7 +24,7 @@ export async function fetchPackages( ).start(); try { - hypermodPackage = await fetchPackage(hypermodPackageName, packageManager); + hypermodPackage = await fetchPackage(hypermodPackageName, moduleLoader); spinner.succeed( `${chalk.green('Found Hypermod package:')} ${hypermodPackageName}`, ); @@ -46,7 +46,7 @@ export async function fetchPackages( spinner.info( `${chalk.green(`Attempting to download npm package:`)} ${packageName}`, ); - remotePackage = await fetchRemotePackage(packageName, packageManager); + remotePackage = await fetchRemotePackage(packageName, moduleLoader); spinner.succeed( `${chalk.green('Found remote Hypermod package:')} ${packageName}`, ); diff --git a/packages/cli/src/utils/module-loader.ts b/packages/cli/src/utils/module-loader.ts new file mode 100644 index 000000000..39e2b7519 --- /dev/null +++ b/packages/cli/src/utils/module-loader.ts @@ -0,0 +1,74 @@ +import path from 'path'; +import fs from 'fs-extra'; +import { installPackage } from '@antfu/install-pkg'; + +/** + * Register the TSX plugin to allow require TS(X) files. + */ +import { register } from 'tsx/esm/api'; +register(); + +const ModuleLoader = (config: { + npmRegistryUrl?: string; + authToken?: string; +}) => { + const getInfo = async (packageName: string) => { + // @ts-expect-error Experimental loader + const entryPath = await import.meta.resolve(packageName); + const location = (entryPath.split(packageName)[0] + packageName).replace( + 'file://', + '', + ); + const pkgJsonRaw = fs.readFileSync( + path.join(location.replace('file://', ''), 'package.json'), + 'utf8', + ); + const pkgJson = JSON.parse(pkgJsonRaw); + + return { location, entryPath, pkgJson }; + }; + + const install = async (packageName: string) => { + // @ts-expect-error + const __dirname = path.dirname(new URL(import.meta.url).pathname); + await installPackage(packageName, { + cwd: __dirname, + packageManager: 'npm', + additionalArgs: [ + '--force', + // --registry=https://your-custom-registry-url/ --//your-custom-registry-url/:_authToken=YOUR_AUTH_TOKEN + ...(config.npmRegistryUrl + ? [`--registry=${config.npmRegistryUrl}`] + : []), + ...(config.authToken + ? [`${config.npmRegistryUrl}/:_authToken=${config.authToken}`] + : []), + ], + }); + + const { pkgJson } = await getInfo(packageName); + + // Install whitelisted devDependencies + if (pkgJson?.hypermod?.dependencies) { + await Promise.all( + pkgJson.hypermod.dependencies.map((dep: string) => { + const version = pkgJson.devDependencies[dep]; + if (!version) return; + return installPackage(`${dep}@${version}`, { + cwd: __dirname, + packageManager: 'npm', + additionalArgs: ['--force'], + }); + }), + ); + } + }; + + return { + install, + getInfo, + require: async (packageName: string) => import(packageName), + }; +}; + +export default ModuleLoader; diff --git a/packages/core/lib/Worker.js b/packages/core/lib/Worker.js index c25a0ce91..8bbf9d9d3 100644 --- a/packages/core/lib/Worker.js +++ b/packages/core/lib/Worker.js @@ -1,55 +1,41 @@ -/* eslint-disable @typescript-eslint/no-var-requires */ -'use strict'; - -const path = require('path'); -const { EventEmitter } = require('events'); -const async = require('neo-async'); -const fs = require('graceful-fs'); -const writeFileAtomic = require('write-file-atomic'); -const { DEFAULT_EXTENSIONS } = require('@babel/core'); - -const getParser = require('jscodeshift/src/getParser'); -const jscodeshift = require('jscodeshift/src/core'); - -let presetEnv; -try { - presetEnv = require('@babel/preset-env'); -} catch (_) {} - -let emitter; -let finish; -let notify; +import path from 'path'; +import async from 'neo-async'; +import fs from 'graceful-fs'; +import writeFileAtomic from 'write-file-atomic'; +import { fileURLToPath } from 'url'; +import { register } from 'tsx/esm/api'; + +import getParser from 'jscodeshift/src/getParser.js'; +import jscodeshift from 'jscodeshift/src/core.js'; +import { workerData, isMainThread, parentPort } from 'worker_threads'; + +/** + * Register the TSX plugin to allow import TS(X) files. + */ +register(); + let transform; let parserFromTransform; -if (module.parent) { - emitter = new EventEmitter(); - // @ts-expect-error - emitter.send = data => run(data); - finish = () => emitter.emit('disconnect'); - notify = data => emitter.emit('message', data); - - module.exports = args => { - setup(args[0], args[1]); - return emitter; - }; -} else { - finish = () => setImmediate(() => process.disconnect()); - notify = data => process.send(data); - process.on('message', data => run(data)); - setup(process.argv[2], process.argv[3]); +// Get the __filename and __dirname equivalents for ESM +const __filename = fileURLToPath(import.meta.url); + +if (!isMainThread) { + await setup(workerData.entrypointPath); + parentPort.on('message', data => run(data)); } function prepareJscodeshift(options) { - const parser = - parserFromTransform || getParser(options.parser, options.parserConfig); - return jscodeshift.withParser(parser); + return jscodeshift.withParser( + parserFromTransform || getParser(options.parser, options.parserConfig), + ); } function retrieveTransformId(str) { if (str.includes('#')) return false; return (str.match(/[^@]*(?:[@](?!.*[@]))(.*)$/) || [, ''])[1]; } + function retrievePresetId(str) { return (str.match(/[^#]*(?:[#](?!.*[#]))(.*)$/) || [, ''])[1]; } @@ -59,41 +45,16 @@ function retrievePath(str) { } function getModule(mod) { - return mod.hasOwnProperty('default') ? mod.default : mod; + return Boolean(mod.default) ? mod.default : mod; } -function setup(entryPath, babel) { - if (babel === 'babel') { - const presets = []; - if (presetEnv) { - presets.push([presetEnv.default, { targets: { node: true } }]); - } - - presets.push(require('@babel/preset-typescript').default); - - require('@babel/register')({ - configFile: false, - babelrc: false, - presets, - plugins: [ - require('@babel/plugin-proposal-class-properties').default, - require('@babel/plugin-proposal-nullish-coalescing-operator').default, - require('@babel/plugin-proposal-optional-chaining').default, - require('@babel/plugin-transform-modules-commonjs').default, - ], - extensions: [...DEFAULT_EXTENSIONS, '.ts', '.tsx'], - // By default, babel register only compiles things inside the current working directory. - // https://github.com/babel/babel/blob/2a4f16236656178e84b05b8915aab9261c55782c/packages/babel-register/src/node.js#L140-L157 - ignore: [ - // Ignore parser related files - /@babel\/parser/, - /\/flow-parser\//, - /\/recast\//, - /\/ast-types\//, - ], - }); - } +async function getModuleName(path) { + const moduleName = retrievePath(path).split('node_modules/')[1]; + const pkg = await import(moduleName); + return getModule(pkg); +} +async function setup(entryPath) { const transformId = retrieveTransformId(entryPath); const presetId = retrievePresetId(entryPath); @@ -101,17 +62,17 @@ function setup(entryPath, babel) { let transformModule; if (transformId) { - transformPkg = getModule(require(path.resolve(retrievePath(entryPath)))); + transformPkg = await getModuleName(entryPath); transformModule = transformPkg.transforms[transformId]; } if (presetId) { - transformPkg = getModule(require(path.resolve(retrievePath(entryPath)))); + transformPkg = await getModuleName(entryPath); transformModule = transformPkg.presets[presetId]; } if (!transformId && !presetId) { - transformModule = require(path.resolve(entryPath)); + transformModule = await import(path.resolve(entryPath)); } transform = getModule(transformModule); @@ -126,12 +87,12 @@ function setup(entryPath, babel) { function updateStatus(status, file, msg) { msg = msg ? file + ' ' + msg : file; - notify({ action: 'status', status, msg }); + parentPort.postMessage({ action: 'status', status, msg }); } function stats(name, quantity) { quantity = typeof quantity !== 'number' ? 1 : quantity; - notify({ action: 'update', name: name, quantity: quantity }); + parentPort.postMessage({ action: 'update', name: name, quantity: quantity }); } function trimStackTrace(trace) { @@ -154,9 +115,10 @@ function run(data) { const options = data.options || {}; if (!files.length) { - finish(); + parentPort.close(); return; } + async.each( files, function (file, callback) { @@ -171,19 +133,18 @@ function run(data) { try { const jscodeshift = prepareJscodeshift(options); const out = await transform( - { - path: file, - source: source, - }, + { path: file, source: source }, { j: jscodeshift, jscodeshift: jscodeshift, // eslint-disable-next-line @typescript-eslint/no-empty-function stats: options.dry ? stats : () => {}, - report: msg => notify({ action: 'report', file, msg }), + report: msg => + parentPort.postMessage({ action: 'report', file, msg }), }, options, ); + if (!out || out === source) { updateStatus(out ? 'nochange' : 'skip', file); callback(); @@ -222,7 +183,7 @@ function run(data) { if (err) { updateStatus('error', '', 'This should never be shown!'); } - notify({ action: 'free' }); + parentPort.postMessage({ action: 'free' }); }, ); } diff --git a/packages/core/lib/Worker.spec.js b/packages/core/lib/Worker.spec.ts similarity index 71% rename from packages/core/lib/Worker.spec.js rename to packages/core/lib/Worker.spec.ts index e721846ea..10f64398a 100644 --- a/packages/core/lib/Worker.spec.js +++ b/packages/core/lib/Worker.spec.ts @@ -1,12 +1,14 @@ /* eslint-disable @typescript-eslint/no-var-requires */ 'use strict'; -const fs = require('fs'); -const mkdirp = require('mkdirp'); -const path = require('path'); -const temp = require('temp'); - -function renameFileTo(oldPath, newFilename) { +import path from 'path'; +import fs from 'fs'; +// @ts-expect-error +import mkdirp from 'mkdirp'; +// @ts-expect-error +import temp from 'temp'; + +function renameFileTo(oldPath: string, newFilename: string) { const projectPath = path.dirname(oldPath); const newPath = path.join(projectPath, newFilename); mkdirp.sync(path.dirname(newPath)); @@ -14,7 +16,11 @@ function renameFileTo(oldPath, newFilename) { return newPath; } -function createTempFileWith(content, filename, extension) { +function createTempFileWith( + content: string, + filename?: string, + extension?: string, +) { const info = temp.openSync({ suffix: extension }); let filePath = info.path; fs.writeSync(info.fd, content); @@ -27,7 +33,7 @@ function createTempFileWith(content, filename, extension) { // Test transform files need a js extension to work with @babel/register // .ts or .tsx work as well -function createTransformWith(content, ext = '.js') { +function createTransformWith(content: string, ext = '.js') { return createTempFileWith( 'module.exports = function(fileInfo, api, options) { ' + content + ' }', undefined, @@ -35,13 +41,14 @@ function createTransformWith(content, ext = '.js') { ); } -function getFileContent(filePath) { +function getFileContent(filePath: string) { return fs.readFileSync(filePath).toString(); } describe('Worker API', () => { - it('transforms files', done => { - const worker = require('./Worker'); + it('transforms files', async () => { + // @ts-expect-error + const worker = await import('./Worker.js'); const transformPath = createTransformWith( 'return fileInfo.source + " changed";', ); @@ -49,16 +56,16 @@ describe('Worker API', () => { const emitter = worker([transformPath]); emitter.send({ files: [sourcePath] }); - emitter.once('message', data => { + emitter.once('message', (data: any) => { expect(data.status).toBe('ok'); expect(data.msg).toBe(sourcePath); expect(getFileContent(sourcePath)).toBe('foo changed'); - done(); }); }); - it('transforms files with tranformId as extension', done => { - const worker = require('./Worker'); + it('transforms files with tranformId as extension', async () => { + // @ts-expect-error + const worker = await import('./Worker.js'); const configPath = createTempFileWith( ` const transfomer = (fileInfo) => fileInfo.source + " changed"; @@ -71,16 +78,16 @@ describe('Worker API', () => { const emitter = worker([configPath + '@1.0.0']); emitter.send({ files: [sourcePath] }); - emitter.once('message', data => { + emitter.once('message', (data: any) => { expect(data.status).toBe('ok'); expect(data.msg).toBe(sourcePath); expect(getFileContent(sourcePath)).toBe('foo changed'); - done(); }); }); - it('transforms files with presetId as extension', done => { - const worker = require('./Worker'); + it('transforms files with presetId as extension', async () => { + // @ts-expect-error + const worker = await import('./Worker.js'); const configPath = createTempFileWith( ` const transfomer = (fileInfo) => fileInfo.source + " changed"; @@ -93,16 +100,16 @@ describe('Worker API', () => { const emitter = worker([configPath + '#my-preset']); emitter.send({ files: [sourcePath] }); - emitter.once('message', data => { + emitter.once('message', (data: any) => { expect(data.status).toBe('ok'); expect(data.msg).toBe(sourcePath); expect(getFileContent(sourcePath)).toBe('foo changed'); - done(); }); }); - it('passes j as argument', done => { - const worker = require('./Worker'); + it('passes j as argument', async () => { + // @ts-expect-error + const worker = await import('./Worker.js'); const transformPath = createTempFileWith( `module.exports = function (file, api) { return api.j(file.source).toSource() + ' changed'; @@ -112,15 +119,14 @@ describe('Worker API', () => { const emitter = worker([transformPath]); emitter.send({ files: [sourcePath] }); - emitter.once('message', data => { + emitter.once('message', (data: any) => { expect(data.status).toBe('ok'); expect(getFileContent(sourcePath)).toBe('const x = 10;' + ' changed'); - done(); }); }); describe('custom parser', () => { - function getTransformForParser(parser) { + function getTransformForParser(parser: string) { return createTempFileWith( `function transform(fileInfo, api) { api.jscodeshift(fileInfo.source); @@ -136,8 +142,9 @@ describe('Worker API', () => { return createTempFileWith('const x = (a: Object, b: string): void => {}'); } - it('errors if new flow type code is parsed with babel v5', done => { - const worker = require('./Worker'); + it('errors if new flow type code is parsed with babel v5', async () => { + // @ts-expect-error + const worker = await import('./Worker.js'); const transformPath = createTransformWith( 'api.jscodeshift(fileInfo.source); return "changed";', ); @@ -145,32 +152,32 @@ describe('Worker API', () => { const emitter = worker([transformPath]); emitter.send({ files: [sourcePath] }); - emitter.once('message', data => { + emitter.once('message', (data: any) => { expect(data.status).toBe('error'); expect(data.msg).toMatch('SyntaxError'); - done(); }); }); ['flow', 'babylon'].forEach(parser => { - it(`uses ${parser} if configured as such`, done => { - const worker = require('./Worker'); + it(`uses ${parser} if configured as such`, async () => { + // @ts-expect-error + const worker = await import('./Worker.js'); const transformPath = getTransformForParser(parser); const sourcePath = getSourceFile(); const emitter = worker([transformPath]); emitter.send({ files: [sourcePath] }); - emitter.once('message', data => { + emitter.once('message', (data: any) => { expect(data.status).toBe('ok'); expect(getFileContent(sourcePath)).toBe('changed'); - done(); }); }); }); ['babylon', 'flow', 'tsx'].forEach(parser => { - it(`can parse JSX with ${parser}`, done => { - const worker = require('./Worker'); + it(`can parse JSX with ${parser}`, async () => { + // @ts-expect-error + const worker = await import('./Worker.js'); const transformPath = getTransformForParser(parser); const sourcePath = createTempFileWith( 'var component =
{foobar}
;', @@ -178,25 +185,24 @@ describe('Worker API', () => { const emitter = worker([transformPath]); emitter.send({ files: [sourcePath] }); - emitter.once('message', data => { + emitter.once('message', (data: any) => { expect(data.status).toBe('ok'); expect(getFileContent(sourcePath)).toBe('changed'); - done(); }); }); }); - it('can parse enums with flow', done => { - const worker = require('./Worker'); + it('can parse enums with flow', async () => { + // @ts-expect-error + const worker = await import('./Worker.js'); const transformPath = getTransformForParser('flow'); const sourcePath = createTempFileWith('enum E {A, B}'); const emitter = worker([transformPath]); emitter.send({ files: [sourcePath] }); - emitter.once('message', data => { + emitter.once('message', (data: any) => { expect(data.status).toBe('ok'); expect(getFileContent(sourcePath)).toBe('changed'); - done(); }); }); }); diff --git a/packages/core/package.json b/packages/core/package.json index 9d821a822..753d05b12 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,7 @@ { "name": "@hypermod/core", "version": "0.3.0", + "type": "module", "source": "src/index.ts", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -21,6 +22,7 @@ "graceful-fs": "^4.2.4", "jscodeshift": "^0.13.1", "neo-async": "^2.5.0", + "tsx": "^4.19.1", "write-file-atomic": "^2.3.0" }, "devDependencies": { @@ -28,6 +30,6 @@ "temp": "^0.8.4" }, "engines": { - "node": ">=14" + "node": ">=20" } } diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 2a4a918bf..af1b7c9b6 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,2 +1,2 @@ -export type { Flags } from './types'; -export { run } from './runner'; +export type { Flags } from './types.js'; +export { run } from './runner.js'; diff --git a/packages/core/src/runner.ts b/packages/core/src/runner.ts index 85ccf9005..29add2cdb 100644 --- a/packages/core/src/runner.ts +++ b/packages/core/src/runner.ts @@ -1,12 +1,15 @@ -import child_process from 'child_process'; +import { Worker } from 'worker_threads'; import chalk from 'chalk'; import fs from 'graceful-fs'; import path from 'path'; import os from 'os'; -// @ts-expect-error -import ignores from 'jscodeshift/src/ignoreFiles'; -import { Message, Flags, Statuses } from './types'; +import { Message, Flags, Statuses } from './types.js'; + +// @ts-expect-error +const ignores = await import('jscodeshift/src/ignoreFiles.js'); +// @ts-expect-error +const __dirname = import.meta.dirname; type FileCounters = Record; type Stats = Record; @@ -230,25 +233,23 @@ export function run( } } - const args = [entrypointPath, options.babel ? 'babel' : 'no-babel']; - - const workers = []; + const workers: Worker[] = []; for (let i = 0; i < processes; i++) { workers.push( - options.runInBand - ? // eslint-disable-next-line @typescript-eslint/no-var-requires - require('../lib/Worker')(args) - : child_process.fork( - path.join(__dirname, '..', 'lib', 'Worker.js'), - args, - ), + new Worker(path.join(__dirname, '..', 'lib', 'Worker.js'), { + workerData: { + entrypointPath, + babel: options.babel ? 'babel' : 'no-babel', + }, + }), ); } - return workers.map(child => { - child.send({ files: next(), options }); - child.on('message', (message: Message) => { + return workers.map(worker => { + worker.postMessage({ files: next(), options }); + worker.on('error', (message: Message) => console.error(message)); + worker.on('message', (message: Message) => { switch (message.action) { case 'status': fileCounters[message.status] += 1; @@ -261,7 +262,7 @@ export function run( statsCounter[message.name] += message.quantity; break; case 'free': - child.send({ files: next(), options }); + worker.postMessage({ files: next(), options }); break; case 'report': bufferedWrite( @@ -274,7 +275,7 @@ export function run( break; } }); - return new Promise(resolve => child.on('disconnect', resolve)); + return new Promise(resolve => worker.on('close', resolve)); }); }) .then(pendingWorkers => diff --git a/packages/fetcher/package.json b/packages/fetcher/package.json index 0900b60dd..b7a262866 100644 --- a/packages/fetcher/package.json +++ b/packages/fetcher/package.json @@ -1,6 +1,7 @@ { "name": "@hypermod/fetcher", "version": "0.9.0", + "type": "module", "source": "src/index.ts", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -17,11 +18,9 @@ "@babel/register": "^7.23.0", "@hypermod/types": "*", "chalk": "^4.1.0", - "fs-extra": "^9.1.0", - "globby": "^11.1.0", - "live-plugin-manager": "^0.18.1" + "globby": "^11.1.0" }, "engines": { - "node": ">=14" + "node": ">=20" } } diff --git a/packages/fetcher/src/index.ts b/packages/fetcher/src/index.ts index 11774d82a..b02179e54 100644 --- a/packages/fetcher/src/index.ts +++ b/packages/fetcher/src/index.ts @@ -2,43 +2,9 @@ import fs from 'fs'; import path from 'path'; import globby from 'globby'; -import { PluginManager } from 'live-plugin-manager'; import { Config } from '@hypermod/types'; -// This configuration allows us to require TypeScript config files directly -const { DEFAULT_EXTENSIONS } = require('@babel/core'); -const presets = []; - -let presetEnv; -try { - presetEnv = require('@babel/preset-env'); - presets.push([presetEnv.default, { targets: { node: true } }]); -} catch (_) {} - -require('@babel/register')({ - configFile: false, - babelrc: false, - presets: [...presets, require('@babel/preset-typescript').default], - plugins: [ - require('@babel/plugin-transform-class-properties').default, - require('@babel/plugin-transform-nullish-coalescing-operator').default, - require('@babel/plugin-transform-optional-chaining').default, - require('@babel/plugin-transform-modules-commonjs').default, - require('@babel/plugin-transform-private-methods').default, - ], - extensions: [...DEFAULT_EXTENSIONS, '.ts', '.tsx'], - // By default, babel register only compiles things inside the current working directory. - // https://github.com/babel/babel/blob/2a4f16236656178e84b05b8915aab9261c55782c/packages/babel-register/src/node.js#L140-L157 - ignore: [ - // Ignore parser related files - /@babel\/parser/, - /\/flow-parser\//, - /\/recast\//, - /\/ast-types\//, - ], -}); - export interface ConfigMeta { filePath: string; config: Config; @@ -48,10 +14,10 @@ function resolveConfigExport(pkg: any): Config { return pkg.default ? pkg.default : pkg; } -function requireConfig(filePath: string, resolvedPath: string) { +async function requireConfig(filePath: string, resolvedPath: string) { try { // eslint-disable-next-line @typescript-eslint/no-var-requires - const pkg = require(resolvedPath); + const pkg = await import(resolvedPath); return resolveConfigExport(pkg); } catch (e) { console.log(resolvedPath, e); @@ -89,7 +55,7 @@ export async function fetchConfigs(filePath: string): Promise { configs.push({ filePath: matchedPath, - config: requireConfig(matchedPath, resolvedMatchedPath), + config: await requireConfig(matchedPath, resolvedMatchedPath), }); } @@ -109,11 +75,11 @@ export async function fetchConfigAtPath(filePath: string): Promise { export async function fetchPackage( packageName: string, - packageManager: PluginManager, + moduleLoader: any, ): Promise { - await packageManager.install(packageName); - const pkg = packageManager.require(packageName); - const info = packageManager.getInfo(packageName); + await moduleLoader.install(packageName); + const pkg = await moduleLoader.require(packageName); + const info = await moduleLoader.getInfo(packageName); if (!info) { throw new Error(`Unable to find package info for: ${packageName}`); @@ -127,14 +93,14 @@ export async function fetchPackage( export async function fetchRemotePackage( packageName: string, - packageManager: PluginManager, + moduleLoader: any, ): Promise { if (['javascript', 'typescript'].includes(packageName)) { throw new Error(`'${packageName}' is ignored as a remote package.`); } - await packageManager.install(packageName); - const info = packageManager.getInfo(packageName); + await moduleLoader.install(packageName); + const info = await moduleLoader.getInfo(packageName); if (!info) { throw new Error( @@ -144,7 +110,7 @@ export async function fetchRemotePackage( // Search main entrypoint for transform/presets from the default import try { - const pkg = packageManager.require(packageName); + const pkg = await moduleLoader.require(packageName); const configExport = resolveConfigExport(pkg); if (configExport.transforms || configExport.presets) { diff --git a/packages/initializer/package.json b/packages/initializer/package.json index f1b5d4cbc..27a9194f4 100644 --- a/packages/initializer/package.json +++ b/packages/initializer/package.json @@ -14,6 +14,6 @@ "semver": "^7.3.5" }, "engines": { - "node": ">=14" + "node": ">=20" } } diff --git a/packages/utils/package.json b/packages/utils/package.json index 67f45592a..072c9a97a 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -7,7 +7,7 @@ "license": "MIT", "repository": "https://github.com/hypermod-io/hypermod-community/tree/main/packages/utils", "engines": { - "node": ">=14" + "node": ">=20" }, "dependencies": { "jscodeshift": "^0.13.1" diff --git a/packages/validator/package.json b/packages/validator/package.json index 4ca612d23..9c6420908 100644 --- a/packages/validator/package.json +++ b/packages/validator/package.json @@ -1,6 +1,7 @@ { "name": "@hypermod/validator", "version": "0.6.9", + "type": "module", "source": "src/index.ts", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -15,6 +16,6 @@ "@types/lodash": "^4.14.176" }, "engines": { - "node": ">=14" + "node": ">=20" } } diff --git a/packages/validator/src/index.ts b/packages/validator/src/index.ts index 1e279f7fd..2e1b69edb 100644 --- a/packages/validator/src/index.ts +++ b/packages/validator/src/index.ts @@ -13,7 +13,7 @@ function hasValidPresets(config: Config): boolean { if (!config.presets) return true; return Object.entries(config.presets).every(([key]) => - key.match(/^[0-9a-zA-Z\-]+$/), + key.match(/^[0-9a-zA-Z\-\.]+$/), ); } diff --git a/scripts/validate.ts b/scripts/validate.ts index 8618b52af..67df105ee 100644 --- a/scripts/validate.ts +++ b/scripts/validate.ts @@ -2,7 +2,6 @@ import fs, { lstatSync, existsSync } from 'fs-extra'; import junk from 'junk'; import path from 'path'; import chalk from 'chalk'; -import { isValidPackageName, isValidConfigAtPath } from '@hypermod/validator'; const validPackageNameFormat = /^@hypermod\/mod(-[a-zA-Z0-9]+)*(-(?!__)[a-zA-Z0-9]+)*(__([a-zA-Z0-9]+(-[a-zA-Z0-9]+)*)?)?$/; @@ -29,6 +28,9 @@ For example: @hypermod/mod-foo__bar`); } async function main(targetPath: string) { + const { isValidPackageName, isValidConfigAtPath } = await import( + '@hypermod/validator' + ); const directories = await fs.readdir(targetPath); directories diff --git a/yarn.lock b/yarn.lock index 8ae2faee7..6bf5c810a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1276,6 +1276,126 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" +"@esbuild/aix-ppc64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz#51299374de171dbd80bb7d838e1cfce9af36f353" + integrity sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ== + +"@esbuild/android-arm64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz#58565291a1fe548638adb9c584237449e5e14018" + integrity sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw== + +"@esbuild/android-arm@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.23.1.tgz#5eb8c652d4c82a2421e3395b808e6d9c42c862ee" + integrity sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ== + +"@esbuild/android-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.23.1.tgz#ae19d665d2f06f0f48a6ac9a224b3f672e65d517" + integrity sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg== + +"@esbuild/darwin-arm64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz#05b17f91a87e557b468a9c75e9d85ab10c121b16" + integrity sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q== + +"@esbuild/darwin-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz#c58353b982f4e04f0d022284b8ba2733f5ff0931" + integrity sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw== + +"@esbuild/freebsd-arm64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz#f9220dc65f80f03635e1ef96cfad5da1f446f3bc" + integrity sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA== + +"@esbuild/freebsd-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz#69bd8511fa013b59f0226d1609ac43f7ce489730" + integrity sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g== + +"@esbuild/linux-arm64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz#8050af6d51ddb388c75653ef9871f5ccd8f12383" + integrity sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g== + +"@esbuild/linux-arm@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz#ecaabd1c23b701070484990db9a82f382f99e771" + integrity sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ== + +"@esbuild/linux-ia32@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz#3ed2273214178109741c09bd0687098a0243b333" + integrity sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ== + +"@esbuild/linux-loong64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz#a0fdf440b5485c81b0fbb316b08933d217f5d3ac" + integrity sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw== + +"@esbuild/linux-mips64el@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz#e11a2806346db8375b18f5e104c5a9d4e81807f6" + integrity sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q== + +"@esbuild/linux-ppc64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz#06a2744c5eaf562b1a90937855b4d6cf7c75ec96" + integrity sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw== + +"@esbuild/linux-riscv64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz#65b46a2892fc0d1af4ba342af3fe0fa4a8fe08e7" + integrity sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA== + +"@esbuild/linux-s390x@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz#e71ea18c70c3f604e241d16e4e5ab193a9785d6f" + integrity sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw== + +"@esbuild/linux-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz#d47f97391e80690d4dfe811a2e7d6927ad9eed24" + integrity sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ== + +"@esbuild/netbsd-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz#44e743c9778d57a8ace4b72f3c6b839a3b74a653" + integrity sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA== + +"@esbuild/openbsd-arm64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz#05c5a1faf67b9881834758c69f3e51b7dee015d7" + integrity sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q== + +"@esbuild/openbsd-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz#2e58ae511bacf67d19f9f2dcd9e8c5a93f00c273" + integrity sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA== + +"@esbuild/sunos-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz#adb022b959d18d3389ac70769cef5a03d3abd403" + integrity sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA== + +"@esbuild/win32-arm64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz#84906f50c212b72ec360f48461d43202f4c8b9a2" + integrity sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A== + +"@esbuild/win32-ia32@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz#5e3eacc515820ff729e90d0cb463183128e82fac" + integrity sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ== + +"@esbuild/win32-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz#81fd50d11e2c32b2d6241470e3185b70c7b30699" + integrity sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg== + "@eslint-community/eslint-utils@^4.2.0": version "4.4.0" resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz" @@ -2636,20 +2756,6 @@ dependencies: "@babel/types" "^7.20.7" -"@types/debug@^4.1.7": - version "4.1.12" - resolved "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz" - integrity sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ== - dependencies: - "@types/ms" "*" - -"@types/fs-extra@^9.0.13": - version "9.0.13" - resolved "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz" - integrity sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA== - dependencies: - "@types/node" "*" - "@types/graceful-fs@^4.1.3": version "4.1.9" resolved "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz" @@ -2713,11 +2819,6 @@ resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== -"@types/lockfile@^1.0.2": - version "1.0.4" - resolved "https://registry.npmjs.org/@types/lockfile/-/lockfile-1.0.4.tgz" - integrity sha512-Q8oFIHJHr+htLrTXN2FuZfg+WXVHQRwU/hC2GpUu+Q8e3FUM9EDkS2pE3R2AO1ZGu56f479ybdMCNF1DAu8cAQ== - "@types/lodash@^4.14.176": version "4.14.202" resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.202.tgz" @@ -2735,24 +2836,11 @@ dependencies: minipass "*" -"@types/ms@*": - version "0.7.34" - resolved "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz" - integrity sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g== - "@types/neo-async@^2.6.0": version "2.6.6" resolved "https://registry.npmjs.org/@types/neo-async/-/neo-async-2.6.6.tgz" integrity sha512-D22UBilfSj6IMhC5Fs6+sbZveSTgG0qPVw4mFbQaadLaU7COikojl/TJpKxX0woidAbbWJ42MJ9ANOr9ODi6Yw== -"@types/node-fetch@^2.5.12": - version "2.6.9" - resolved "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.9.tgz" - integrity sha512-bQVlnMLFJ2d35DkPNjEPmd9ueO/rh5EiaZt2bhqiSarPjZIuIV6bPQVqcrEyvNo+AfTrRGVazle1tl597w3gfA== - dependencies: - "@types/node" "*" - form-data "^4.0.0" - "@types/node@*", "@types/node@^16.11.0": version "16.18.68" resolved "https://registry.npmjs.org/@types/node/-/node-16.18.68.tgz" @@ -2778,7 +2866,7 @@ resolved "https://registry.npmjs.org/@types/semver/-/semver-6.2.7.tgz" integrity sha512-blctEWbzUFzQx799RZjzzIdBJOXmE37YYEyDtKkx5Dg+V7o/zyyAxLPiI98A2jdTtDgxZleMdfV+7p8WbRJ1OQ== -"@types/semver@^7.3.12", "@types/semver@^7.3.9", "@types/semver@^7.5.0": +"@types/semver@^7.3.12", "@types/semver@^7.5.0": version "7.5.6" resolved "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz" integrity sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A== @@ -2801,14 +2889,6 @@ "@types/minipass" "*" "@types/node" "*" -"@types/tar@^6.1.1": - version "6.1.10" - resolved "https://registry.npmjs.org/@types/tar/-/tar-6.1.10.tgz" - integrity sha512-60ZO+W0tRKJ3ggdzJKp75xKVlNogKYMqGvr2bMH/+k3T0BagfYTnbmVDFMJB1BFttz6yRgP5MDGP27eh7brrqw== - dependencies: - "@types/node" "*" - minipass "^4.0.0" - "@types/through@*": version "0.0.33" resolved "https://registry.npmjs.org/@types/through/-/through-0.0.33.tgz" @@ -2816,11 +2896,6 @@ dependencies: "@types/node" "*" -"@types/url-join@4.0.1": - version "4.0.1" - resolved "https://registry.npmjs.org/@types/url-join/-/url-join-4.0.1.tgz" - integrity sha512-wDXw9LEEUHyV+7UWy7U315nrJGJ7p1BzaCxDpEoLr789Dk1WDVMMlf3iBfbG2F8NdWnYyFbtTxUn2ZNbm1Q4LQ== - "@types/write-file-atomic@^4.0.0": version "4.0.3" resolved "https://registry.npmjs.org/@types/write-file-atomic/-/write-file-atomic-4.0.3.tgz" @@ -3824,7 +3899,7 @@ debug@^2.2.0, debug@^2.3.3: dependencies: ms "2.0.0" -debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.3, debug@^4.3.4: +debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.4: version "4.3.4" resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -4167,6 +4242,36 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" +esbuild@~0.23.0: + version "0.23.1" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.23.1.tgz#40fdc3f9265ec0beae6f59824ade1bd3d3d2dab8" + integrity sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg== + optionalDependencies: + "@esbuild/aix-ppc64" "0.23.1" + "@esbuild/android-arm" "0.23.1" + "@esbuild/android-arm64" "0.23.1" + "@esbuild/android-x64" "0.23.1" + "@esbuild/darwin-arm64" "0.23.1" + "@esbuild/darwin-x64" "0.23.1" + "@esbuild/freebsd-arm64" "0.23.1" + "@esbuild/freebsd-x64" "0.23.1" + "@esbuild/linux-arm" "0.23.1" + "@esbuild/linux-arm64" "0.23.1" + "@esbuild/linux-ia32" "0.23.1" + "@esbuild/linux-loong64" "0.23.1" + "@esbuild/linux-mips64el" "0.23.1" + "@esbuild/linux-ppc64" "0.23.1" + "@esbuild/linux-riscv64" "0.23.1" + "@esbuild/linux-s390x" "0.23.1" + "@esbuild/linux-x64" "0.23.1" + "@esbuild/netbsd-x64" "0.23.1" + "@esbuild/openbsd-arm64" "0.23.1" + "@esbuild/openbsd-x64" "0.23.1" + "@esbuild/sunos-x64" "0.23.1" + "@esbuild/win32-arm64" "0.23.1" + "@esbuild/win32-ia32" "0.23.1" + "@esbuild/win32-x64" "0.23.1" + escalade@^3.1.1: version "3.1.1" resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" @@ -4589,15 +4694,6 @@ fragment-cache@^0.2.1: dependencies: map-cache "^0.2.2" -fs-extra@^10.0.0: - version "10.1.0" - resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz" - integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - fs-extra@^7.0.1: version "7.0.1" resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz" @@ -4638,7 +4734,7 @@ fs.realpath@^1.0.0: resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== -fsevents@^2.3.2: +fsevents@^2.3.2, fsevents@~2.3.3: version "2.3.3" resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== @@ -4725,6 +4821,13 @@ get-symbol-description@^1.0.0: call-bind "^1.0.2" get-intrinsic "^1.1.1" +get-tsconfig@^4.7.5: + version "4.8.1" + resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.8.1.tgz#8995eb391ae6e1638d251118c7b56de7eb425471" + integrity sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg== + dependencies: + resolve-pkg-maps "^1.0.0" + get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz" @@ -6067,26 +6170,6 @@ lines-and-columns@^1.1.6: resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== -live-plugin-manager@^0.18.1: - version "0.18.1" - resolved "https://registry.npmjs.org/live-plugin-manager/-/live-plugin-manager-0.18.1.tgz" - integrity sha512-GvLMSaZ1Cc18o91NiHLRuPXm1z7xDiUXUGgQ6jAwGM/x0FY8vXXHa/+LMNb2zrkAV2bWULCs0FEwX9yRsmFZmw== - dependencies: - "@types/debug" "^4.1.7" - "@types/fs-extra" "^9.0.13" - "@types/lockfile" "^1.0.2" - "@types/node-fetch" "^2.5.12" - "@types/semver" "^7.3.9" - "@types/tar" "^6.1.1" - "@types/url-join" "4.0.1" - debug "^4.3.3" - fs-extra "^10.0.0" - lockfile "^1.0.4" - node-fetch "^2.6.6" - semver "^7.3.5" - tar "^6.1.11" - url-join "^4.0.1" - lmdb@2.8.5: version "2.8.5" resolved "https://registry.npmjs.org/lmdb/-/lmdb-2.8.5.tgz" @@ -6155,13 +6238,6 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" -lockfile@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/lockfile/-/lockfile-1.0.4.tgz" - integrity sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA== - dependencies: - signal-exit "^3.0.2" - lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz" @@ -6422,11 +6498,6 @@ minipass@^3.0.0: dependencies: yallist "^4.0.0" -minipass@^4.0.0: - version "4.2.8" - resolved "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz" - integrity sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ== - minipass@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz" @@ -6550,13 +6621,6 @@ node-dir@^0.1.17: dependencies: minimatch "^3.0.2" -node-fetch@^2.6.6: - version "2.7.0" - resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz" - integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== - dependencies: - whatwg-url "^5.0.0" - node-gyp-build-optional-packages@5.0.7: version "5.0.7" resolved "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.0.7.tgz" @@ -7251,6 +7315,11 @@ resolve-from@^5.0.0: resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== +resolve-pkg-maps@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz#616b3dc2c57056b5588c31cdf4b3d64db133720f" + integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== + resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz" @@ -7869,7 +7938,7 @@ tapable@^1.0.0: resolved "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz" integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== -tar@^6.1.0, tar@^6.1.11: +tar@^6.1.0: version "6.2.0" resolved "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz" integrity sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ== @@ -7971,11 +8040,6 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" - integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== - trim-newlines@^3.0.0: version "3.0.1" resolved "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz" @@ -8043,6 +8107,16 @@ tsutils@^3.21.0: dependencies: tslib "^1.8.1" +tsx@^4.19.1: + version "4.19.1" + resolved "https://registry.yarnpkg.com/tsx/-/tsx-4.19.1.tgz#b7bffdf4b565813e4dea14b90872af279cd0090b" + integrity sha512-0flMz1lh74BR4wOvBjuh9olbnwqCPc35OOlfyzHba0Dc+QNUeWX/Gq2YTbnwcWPO3BMd8fkzRVrHcsR+a7z7rA== + dependencies: + esbuild "~0.23.0" + get-tsconfig "^4.7.5" + optionalDependencies: + fsevents "~2.3.3" + tty-table@^4.1.5: version "4.2.3" resolved "https://registry.npmjs.org/tty-table/-/tty-table-4.2.3.tgz" @@ -8223,11 +8297,6 @@ urix@^0.1.0: resolved "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz" integrity sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg== -url-join@^4.0.1: - version "4.0.1" - resolved "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz" - integrity sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA== - url-parse-lax@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz" @@ -8303,19 +8372,6 @@ weak-lru-cache@^1.2.2: resolved "https://registry.npmjs.org/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz" integrity sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw== -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== - -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz" - integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - which-boxed-primitive@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz"