diff --git a/.prettierignore b/.prettierignore index c2c0d9b1..2d09ad4d 100644 --- a/.prettierignore +++ b/.prettierignore @@ -10,3 +10,4 @@ temp LICENSE CHANGELOG.* SECURITY.md +*.api.md \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index c1e3e198..b94572f5 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -37,6 +37,17 @@ "sourceMaps": true, "outputCapture": "std", "console": "integratedTerminal" + }, + { + "name": "Debug example-lib build", + "request": "launch", + "type": "node", + "runtimeExecutable": "yarn", + "runtimeArgs": ["run", "build"], + "cwd": "${workspaceFolder}/packages/example-lib", + "console": "integratedTerminal", + "outputCapture": "std", + "sourceMaps": true } ] } diff --git a/change/change-0c7dafd4-b632-47f2-bacf-b22077ce3c51.json b/change/change-0c7dafd4-b632-47f2-bacf-b22077ce3c51.json new file mode 100644 index 00000000..928c2f17 --- /dev/null +++ b/change/change-0c7dafd4-b632-47f2-bacf-b22077ce3c51.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "type": "minor", + "comment": "`nodeExecTask`: add `enableTypeScript: esm` setting to run the task in `ts-node` with ESM support", + "packageName": "just-scripts", + "email": "elcraig@microsoft.com", + "dependentChangeType": "patch" + } + ] +} \ No newline at end of file diff --git a/change/change-3e7ef03c-6140-4b48-b824-f7303ca53d62.json b/change/change-3e7ef03c-6140-4b48-b824-f7303ca53d62.json new file mode 100644 index 00000000..18f56b40 --- /dev/null +++ b/change/change-3e7ef03c-6140-4b48-b824-f7303ca53d62.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "type": "patch", + "comment": "Detect if already running in ts-node or tsx and skip call to ts-node register", + "packageName": "just-task", + "email": "elcraig@microsoft.com", + "dependentChangeType": "patch" + } + ] +} \ No newline at end of file diff --git a/change/change-48ef8505-5b31-4b60-bfe2-53e1433985cd.json b/change/change-48ef8505-5b31-4b60-bfe2-53e1433985cd.json new file mode 100644 index 00000000..cb0f9059 --- /dev/null +++ b/change/change-48ef8505-5b31-4b60-bfe2-53e1433985cd.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "type": "minor", + "comment": "Compile just with TS 4.7 and `module`/`moduleResolution` `\"Node16\"`", + "packageName": "just-scripts", + "email": "elcraig@microsoft.com", + "dependentChangeType": "patch" + } + ] +} \ No newline at end of file diff --git a/change/change-9ea30187-bf7e-4cd9-ba0a-e1af7e7b3bdc.json b/change/change-9ea30187-bf7e-4cd9-ba0a-e1af7e7b3bdc.json new file mode 100644 index 00000000..b52245f3 --- /dev/null +++ b/change/change-9ea30187-bf7e-4cd9-ba0a-e1af7e7b3bdc.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "type": "minor", + "comment": "For ts-node, use `module`/`moduleResolution` `\"Node16\"` if the local TS version supports it", + "packageName": "just-task", + "email": "elcraig@microsoft.com", + "dependentChangeType": "patch" + } + ] +} \ No newline at end of file diff --git a/change/change-9eb2d5fb-3a3f-4714-8fd7-5bac2166d20d.json b/change/change-9eb2d5fb-3a3f-4714-8fd7-5bac2166d20d.json new file mode 100644 index 00000000..9c67c9d8 --- /dev/null +++ b/change/change-9eb2d5fb-3a3f-4714-8fd7-5bac2166d20d.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "type": "minor", + "comment": "Partial support for ESM packages: load `just.config.js` as ESM if package has `type: \"module\"`, and support explicit `.cjs`, `.mjs`, and `.cts` extensions. (`.ts` configs in packages with `type: \"module\"` are not supported due to limitations with `ts-node` `register()`.)", + "packageName": "just-task", + "email": "elcraig@microsoft.com", + "dependentChangeType": "patch" + } + ] +} diff --git a/change/change-e400c7a0-47ba-4cf5-b712-508ad7481673.json b/change/change-e400c7a0-47ba-4cf5-b712-508ad7481673.json new file mode 100644 index 00000000..4a6da678 --- /dev/null +++ b/change/change-e400c7a0-47ba-4cf5-b712-508ad7481673.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "type": "minor", + "comment": "Compile just with TS 4.7 and `module`/`moduleResolution` `\"Node16\"`", + "packageName": "just-task", + "email": "elcraig@microsoft.com", + "dependentChangeType": "patch" + } + ] +} \ No newline at end of file diff --git a/package.json b/package.json index 9c498854..87a3a9c8 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "prettier": "^2.8.4", "syncpack": "^9.0.0", "ts-jest": "^29.0.5", - "typescript": "~4.3.5", + "typescript": "~4.7.0", "vuepress": "^1.9.9", "vuepress-plugin-mermaidjs": "^1.9.1", "workspace-tools": "^0.35.2" @@ -74,6 +74,18 @@ "dependencyTypes": [ "dev", "prod" + ], + "versionGroups": [ + { + "label": "ts-node (testing with multiple versions)", + "dependencies": [ + "ts-node" + ], + "packages": [ + "**" + ], + "isIgnored": true + } ] }, "workspaces": { diff --git a/packages/example-lib-esm-ts/README.md b/packages/example-lib-esm-ts/README.md new file mode 100644 index 00000000..4942bcb3 --- /dev/null +++ b/packages/example-lib-esm-ts/README.md @@ -0,0 +1,3 @@ +This package has `"type": "module"` in its `package.json`. If the just config was `just.config.ts`, this would be implicitly considered as ESM, and loading TS files as ESM isn't supported with `ts-node` `register()` (it must be configured with a `--loader` option when the Node process is created). So the package has to use `just.config.cts` instead. + +The just config also defines a `nodeExecTask` which must be handled as ESM. The custom task file can be a normal `.ts` which is treated as ESM because `enableTypeScript: 'esm'` is set, and the task is run in a separate Node process where the `--loader` can be used. diff --git a/packages/example-lib-esm-ts/just.config.cts b/packages/example-lib-esm-ts/just.config.cts new file mode 100644 index 00000000..10bbd7dc --- /dev/null +++ b/packages/example-lib-esm-ts/just.config.cts @@ -0,0 +1,14 @@ +import { nodeExecTask, tscTask, task, parallel } from 'just-scripts'; + +task('typescript', tscTask({})); + +task( + 'customNodeTask', + nodeExecTask({ + enableTypeScript: 'esm', + transpileOnly: true, + args: ['./tasks/customTask.ts'], + }), +); + +task('build', parallel('customNodeTask', 'typescript')); diff --git a/packages/example-lib-esm-ts/package.json b/packages/example-lib-esm-ts/package.json new file mode 100644 index 00000000..7d763baa --- /dev/null +++ b/packages/example-lib-esm-ts/package.json @@ -0,0 +1,14 @@ +{ + "name": "example-lib-esm-ts", + "private": true, + "version": "1.0.0", + "type": "module", + "scripts": { + "build": "just-scripts build" + }, + "license": "MIT", + "devDependencies": { + "just-scripts": ">=2.2.3 <3.0.0", + "ts-node": "^10.0.0" + } +} diff --git a/packages/example-lib-esm-ts/src/index.ts b/packages/example-lib-esm-ts/src/index.ts new file mode 100644 index 00000000..ef74d34b --- /dev/null +++ b/packages/example-lib-esm-ts/src/index.ts @@ -0,0 +1 @@ +const a = 5; diff --git a/packages/example-lib-esm-ts/tasks/customTask.ts b/packages/example-lib-esm-ts/tasks/customTask.ts new file mode 100644 index 00000000..39731f3b --- /dev/null +++ b/packages/example-lib-esm-ts/tasks/customTask.ts @@ -0,0 +1,7 @@ +import * as path from 'path'; +import * as fs from 'fs'; +import { fileURLToPath } from 'url'; + +const dirname = path.dirname(fileURLToPath(import.meta.url)); + +export const packageJson = fs.readFileSync(path.resolve(dirname, '../package.json'), 'utf-8'); diff --git a/packages/example-lib-esm-ts/tsconfig.json b/packages/example-lib-esm-ts/tsconfig.json new file mode 100644 index 00000000..6ce85e60 --- /dev/null +++ b/packages/example-lib-esm-ts/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "target": "ESNext", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "declaration": true, + "declarationMap": true, + "outDir": "lib", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "types": [] + }, + "include": ["src"] +} diff --git a/packages/example-lib-esm-tsnode/README.md b/packages/example-lib-esm-tsnode/README.md new file mode 100644 index 00000000..1c57c67b --- /dev/null +++ b/packages/example-lib-esm-tsnode/README.md @@ -0,0 +1 @@ +This package has `"type": "module"` in its `package.json`. The config is a `.ts` which will be treated as ESM, and Just can't handle that directly (see [`example-lib-esm-ts` readme](../example-lib-esm-ts/README.md)). So the package's `"build"` script wraps the `just-scripts` binary with the transpiler: `ts-node-esm node_modules/.bin/just-scripts build`. diff --git a/packages/example-lib-esm-tsnode/just.config.ts b/packages/example-lib-esm-tsnode/just.config.ts new file mode 100644 index 00000000..10bbd7dc --- /dev/null +++ b/packages/example-lib-esm-tsnode/just.config.ts @@ -0,0 +1,14 @@ +import { nodeExecTask, tscTask, task, parallel } from 'just-scripts'; + +task('typescript', tscTask({})); + +task( + 'customNodeTask', + nodeExecTask({ + enableTypeScript: 'esm', + transpileOnly: true, + args: ['./tasks/customTask.ts'], + }), +); + +task('build', parallel('customNodeTask', 'typescript')); diff --git a/packages/example-lib-esm-tsnode/package.json b/packages/example-lib-esm-tsnode/package.json new file mode 100644 index 00000000..3966ddd0 --- /dev/null +++ b/packages/example-lib-esm-tsnode/package.json @@ -0,0 +1,14 @@ +{ + "name": "example-lib-esm-tsnode", + "private": true, + "version": "1.0.0", + "type": "module", + "scripts": { + "build": "ts-node-esm node_modules/.bin/just-scripts build" + }, + "license": "MIT", + "devDependencies": { + "just-scripts": ">=2.2.3 <3.0.0", + "ts-node": "^10.0.0" + } +} diff --git a/packages/example-lib-esm-tsnode/src/index.ts b/packages/example-lib-esm-tsnode/src/index.ts new file mode 100644 index 00000000..ef74d34b --- /dev/null +++ b/packages/example-lib-esm-tsnode/src/index.ts @@ -0,0 +1 @@ +const a = 5; diff --git a/packages/example-lib-esm-tsnode/tasks/customTask.ts b/packages/example-lib-esm-tsnode/tasks/customTask.ts new file mode 100644 index 00000000..39731f3b --- /dev/null +++ b/packages/example-lib-esm-tsnode/tasks/customTask.ts @@ -0,0 +1,7 @@ +import * as path from 'path'; +import * as fs from 'fs'; +import { fileURLToPath } from 'url'; + +const dirname = path.dirname(fileURLToPath(import.meta.url)); + +export const packageJson = fs.readFileSync(path.resolve(dirname, '../package.json'), 'utf-8'); diff --git a/packages/example-lib-esm-tsnode/tsconfig.json b/packages/example-lib-esm-tsnode/tsconfig.json new file mode 100644 index 00000000..6ce85e60 --- /dev/null +++ b/packages/example-lib-esm-tsnode/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "target": "ESNext", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "declaration": true, + "declarationMap": true, + "outDir": "lib", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "types": [] + }, + "include": ["src"] +} diff --git a/packages/example-lib-esm/README.md b/packages/example-lib-esm/README.md new file mode 100644 index 00000000..5c7889bb --- /dev/null +++ b/packages/example-lib-esm/README.md @@ -0,0 +1,3 @@ +This package has `"type": "module"` in its `package.json`, so its `just.config.js` must be loaded as ESM. + +The just config also defines a `nodeExecTask` which must be handled as ESM. diff --git a/packages/example-lib-esm/just.config.js b/packages/example-lib-esm/just.config.js new file mode 100644 index 00000000..d174515a --- /dev/null +++ b/packages/example-lib-esm/just.config.js @@ -0,0 +1,7 @@ +import { nodeExecTask, tscTask, task, parallel } from 'just-scripts'; + +task('typescript', tscTask({})); + +task('customNodeTask', nodeExecTask({ args: ['./tasks/customTask.js'] })); + +task('build', parallel('customNodeTask', 'typescript')); diff --git a/packages/example-lib-esm/package.json b/packages/example-lib-esm/package.json new file mode 100644 index 00000000..13f72fe4 --- /dev/null +++ b/packages/example-lib-esm/package.json @@ -0,0 +1,14 @@ +{ + "name": "example-lib-esm", + "private": true, + "version": "1.0.0", + "type": "module", + "scripts": { + "build": "just-scripts build" + }, + "license": "MIT", + "devDependencies": { + "just-scripts": ">=2.2.3 <3.0.0", + "ts-node": "^9.1.1" + } +} diff --git a/packages/example-lib-esm/src/index.ts b/packages/example-lib-esm/src/index.ts new file mode 100644 index 00000000..ef74d34b --- /dev/null +++ b/packages/example-lib-esm/src/index.ts @@ -0,0 +1 @@ +const a = 5; diff --git a/packages/example-lib-esm/tasks/customTask.js b/packages/example-lib-esm/tasks/customTask.js new file mode 100644 index 00000000..39731f3b --- /dev/null +++ b/packages/example-lib-esm/tasks/customTask.js @@ -0,0 +1,7 @@ +import * as path from 'path'; +import * as fs from 'fs'; +import { fileURLToPath } from 'url'; + +const dirname = path.dirname(fileURLToPath(import.meta.url)); + +export const packageJson = fs.readFileSync(path.resolve(dirname, '../package.json'), 'utf-8'); diff --git a/packages/example-lib-esm/tsconfig.json b/packages/example-lib-esm/tsconfig.json new file mode 100644 index 00000000..6ce85e60 --- /dev/null +++ b/packages/example-lib-esm/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "target": "ESNext", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "declaration": true, + "declarationMap": true, + "outDir": "lib", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "types": [] + }, + "include": ["src"] +} diff --git a/packages/example-lib/just.config.ts b/packages/example-lib/just.config.ts index 02b8363f..54fda037 100644 --- a/packages/example-lib/just.config.ts +++ b/packages/example-lib/just.config.ts @@ -3,7 +3,14 @@ import { nodeExecTask, tscTask, task, parallel, watch } from 'just-scripts'; task('typescript', tscTask({})); task('typescript:watch', tscTask({ watch: true })); -task('customNodeTask', nodeExecTask({ enableTypeScript: true, args: ['./tasks/customTask.ts'] })); +task( + 'customNodeTask', + nodeExecTask({ + enableTypeScript: true, + transpileOnly: true, + args: ['./tasks/customTask.ts'], + }), +); task('build', parallel('customNodeTask', 'typescript')); task('watch', parallel('typescript:watch')); diff --git a/packages/example-lib/package.json b/packages/example-lib/package.json index 4cd11e88..a8865d7c 100644 --- a/packages/example-lib/package.json +++ b/packages/example-lib/package.json @@ -2,17 +2,10 @@ "name": "example-lib", "private": true, "version": "1.0.0", - "description": "", - "main": "index.js", "scripts": { "build": "just-scripts build" }, - "keywords": [], - "author": "", "license": "MIT", - "engines": { - "node": ">=14" - }, "devDependencies": { "just-scripts": ">=2.2.3 <3.0.0", "ts-node": "^9.1.1" diff --git a/packages/just-scripts/etc/just-scripts.api.md b/packages/just-scripts/etc/just-scripts.api.md index 01f0d4c0..5e228d9a 100644 --- a/packages/just-scripts/etc/just-scripts.api.md +++ b/packages/just-scripts/etc/just-scripts.api.md @@ -293,7 +293,7 @@ export function nodeExecTask(options: NodeExecTaskOptions): TaskFunction; // @public (undocumented) export interface NodeExecTaskOptions { args?: string[]; - enableTypeScript?: boolean; + enableTypeScript?: boolean | 'esm'; env?: NodeJS.ProcessEnv; spawnOptions?: SpawnOptions; transpileOnly?: boolean; @@ -445,7 +445,7 @@ export interface TsLoaderOptions { } // @public (undocumented) -export const tsOverlay: (overlayOptions?: TsOverlayOptions | undefined) => Partial; +export const tsOverlay: (overlayOptions?: TsOverlayOptions) => Partial; // @public (undocumented) export interface TsOverlayOptions { diff --git a/packages/just-scripts/src/tasks/nodeExecTask.ts b/packages/just-scripts/src/tasks/nodeExecTask.ts index 21fbe3ac..0f3a44d2 100644 --- a/packages/just-scripts/src/tasks/nodeExecTask.ts +++ b/packages/just-scripts/src/tasks/nodeExecTask.ts @@ -17,9 +17,10 @@ export interface NodeExecTaskOptions { env?: NodeJS.ProcessEnv; /** - * Should this nodeExec task be using something like ts-node to execute the binary + * Whether this nodeExec task should use ts-node to execute the binary. + * If set to `esm`, it will use `ts-node/esm` instead of `ts-node/register`. */ - enableTypeScript?: boolean; + enableTypeScript?: boolean | 'esm'; /** * The tsconfig file to pass to ts-node for Typescript config @@ -40,21 +41,22 @@ export interface NodeExecTaskOptions { export function nodeExecTask(options: NodeExecTaskOptions): TaskFunction { return function () { const { spawnOptions, enableTypeScript, tsconfig, transpileOnly } = options; + const args = [...(options.args || [])]; + const env = { ...options.env }; - const tsNodeRegister = resolveCwd('ts-node/register'); + const esm = enableTypeScript === 'esm'; + const tsNodeHelper = resolveCwd(esm ? 'ts-node/esm.mjs' : 'ts-node/register'); const nodeExecPath = process.execPath; - if (enableTypeScript && tsNodeRegister) { - options.args = options.args || []; - options.args.unshift(tsNodeRegister); - options.args.unshift('-r'); + if (enableTypeScript && tsNodeHelper) { + args.unshift(esm ? '--loader' : '-r', tsNodeHelper); + Object.assign(env, getTsNodeEnv(tsconfig, transpileOnly, esm)); - options.env = { ...options.env, ...getTsNodeEnv(tsconfig, transpileOnly) }; - logger.info('Executing [TS]: ' + [nodeExecPath, ...(options.args || [])].join(' ')); + logger.info('Executing [TS]: ' + [nodeExecPath, ...args].join(' ')); } else { - logger.info('Executing: ' + [nodeExecPath, ...(options.args || [])].join(' ')); + logger.info('Executing: ' + [nodeExecPath, ...args].join(' ')); } - return spawn(nodeExecPath, options.args, { stdio: 'inherit', env: options.env, ...spawnOptions }); + return spawn(nodeExecPath, args, { stdio: 'inherit', env, ...spawnOptions }); }; } diff --git a/packages/just-scripts/src/tasks/webpackCliInitTask.ts b/packages/just-scripts/src/tasks/webpackCliInitTask.ts index 7c818606..54bed257 100644 --- a/packages/just-scripts/src/tasks/webpackCliInitTask.ts +++ b/packages/just-scripts/src/tasks/webpackCliInitTask.ts @@ -20,13 +20,13 @@ export function webpackCliInitTask(customScaffold?: string, auto = false): TaskF try { init(null, null, null, '--auto'); } catch (error) { - throw `Webpack-cli init failed with ${error.length} error(s).`; + throw `Webpack-cli init failed with ${(error as any).length} error(s).`; } } else { try { init(); } catch (error) { - throw `Webpack-cli init failed with ${error.length} error(s).`; + throw `Webpack-cli init failed with ${(error as any).length} error(s).`; } } } else { @@ -34,7 +34,7 @@ export function webpackCliInitTask(customScaffold?: string, auto = false): TaskF try { init(null, null, customScaffold); } catch (error) { - throw `Webpack-cli init failed with ${error.length} error(s).`; + throw `Webpack-cli init failed with ${(error as any).length} error(s).`; } } }; diff --git a/packages/just-scripts/src/tasks/webpackTask.ts b/packages/just-scripts/src/tasks/webpackTask.ts index 8cd7ddea..2bb70cba 100644 --- a/packages/just-scripts/src/tasks/webpackTask.ts +++ b/packages/just-scripts/src/tasks/webpackTask.ts @@ -82,11 +82,7 @@ export function webpackTask(options?: WebpackTaskOptions): TaskFunction { return new Promise((resolve, reject) => { wp(webpackConfigs, async (err: Error, stats: any) => { if (options && options.onCompile) { - const results = options.onCompile(err, stats); - - if (typeof results === 'object' && results.then) { - await results; - } + await options.onCompile(err, stats); } if (options && options.outputStats) { diff --git a/packages/just-scripts/src/typescript/getTsNodeEnv.ts b/packages/just-scripts/src/typescript/getTsNodeEnv.ts index 4861dfa0..1e567300 100644 --- a/packages/just-scripts/src/typescript/getTsNodeEnv.ts +++ b/packages/just-scripts/src/typescript/getTsNodeEnv.ts @@ -1,13 +1,22 @@ import { logger } from 'just-task'; -export function getTsNodeEnv(tsconfig?: string, transpileOnly?: boolean): { [key: string]: string | undefined } { +export function getTsNodeEnv( + tsconfig?: string, + transpileOnly?: boolean, + esm?: boolean, +): { [key: string]: string | undefined } { const env: { [key: string]: string | undefined } = {}; if (tsconfig) { logger.info(`[TS] Using ${tsconfig}`); env.TS_NODE_PROJECT = tsconfig; } else { - const compilerOptions = JSON.stringify({ module: 'commonjs', target: 'es2017', moduleResolution: 'node' }); + const compilerOptions = JSON.stringify({ + target: 'es2017', + moduleResolution: esm ? 'NodeNext' : 'node', + module: esm ? 'NodeNext' : 'commonjs', + skipLibCheck: true, + }); logger.info(`[TS] Using these compilerOptions: ${compilerOptions}`); env.TS_NODE_COMPILER_OPTIONS = compilerOptions; } diff --git a/packages/just-task/etc/just-task.api.md b/packages/just-task/etc/just-task.api.md index ea25a174..02f4f463 100644 --- a/packages/just-task/etc/just-task.api.md +++ b/packages/just-task/etc/just-task.api.md @@ -10,6 +10,8 @@ import { Arguments } from 'yargs-parser'; import { Duplex } from 'stream'; import type { FSWatcher } from 'chokidar'; import { Logger } from 'just-task-logger'; +import { logger } from 'just-task-logger'; +import { mark } from 'just-task-logger'; import type { Stats } from 'fs'; import { TaskFunction as TaskFunction_2 } from 'undertaker'; import { TaskFunctionParams } from 'undertaker'; @@ -34,6 +36,12 @@ export function clearCache(): void; // @public (undocumented) export function condition(taskName: string, conditional: () => boolean): TaskFunction_2; +export { Logger } + +export { logger } + +export { mark } + // Warning: (ae-forgotten-export) The symbol "OptionConfig" needs to be exported by the entry point index.d.ts // // @public (undocumented) @@ -118,9 +126,6 @@ export function watch(globs: string | string[], optionsOrListener?: WatchListene // @public (undocumented) type WatchListener = (path: string, stats?: Stats) => void; - -export * from "just-task-logger"; - // (No @packageDocumentation comment for this package) ``` diff --git a/packages/just-task/package.json b/packages/just-task/package.json index 96066e03..43bf99bc 100644 --- a/packages/just-task/package.json +++ b/packages/just-task/package.json @@ -34,6 +34,7 @@ "chalk": "^4.0.0", "chokidar": "^3.5.2", "fs-extra": "^11.0.0", + "just-scripts-utils": "^2.0.1", "just-task-logger": ">=1.2.1 <2.0.0", "resolve": "^1.19.0", "undertaker": "^1.3.0", diff --git a/packages/just-task/src/__tests__/resolve.spec.ts b/packages/just-task/src/__tests__/resolve.spec.ts index cc8e94c3..7ca2db34 100644 --- a/packages/just-task/src/__tests__/resolve.spec.ts +++ b/packages/just-task/src/__tests__/resolve.spec.ts @@ -202,7 +202,7 @@ describe('resolveConfigFile', () => { resetResolvePaths(); }); - it('default chooses local config', () => { + it('default chooses local config', async () => { mockfs({ config: { 'configArgument.ts': 'formConfig', @@ -210,11 +210,11 @@ describe('resolveConfigFile', () => { }, 'just.config.ts': 'localConfig', }); - const resolvedConfig = config.resolveConfigFile({ config: undefined, defaultConfig: undefined } as any); + const resolvedConfig = await config.resolveConfigFile({}); expect(resolvedConfig).toContain('just.config.ts'); }); - it('config argument wins over local config and defaultConfig', () => { + it('config argument wins over local config and defaultConfig', async () => { mockfs({ config: { 'configArgument.ts': 'formConfig', @@ -222,14 +222,14 @@ describe('resolveConfigFile', () => { }, 'just.config.ts': 'localConfig', }); - const resolvedConfig = config.resolveConfigFile({ + const resolvedConfig = await config.resolveConfigFile({ config: './config/configArgument.ts', defaultConfig: './config/defaultConfigArgument.ts', - } as any); + }); expect(resolvedConfig).toContain('configArgument.ts'); }); - it('local config file wins over defaultConfig', () => { + it('local config file wins over defaultConfig', async () => { mockfs({ config: { 'configArgument.ts': 'formConfig', @@ -237,24 +237,40 @@ describe('resolveConfigFile', () => { }, 'just.config.ts': 'localConfig', }); - const resolvedConfig = config.resolveConfigFile({ + const resolvedConfig = await config.resolveConfigFile({ config: undefined, defaultConfig: './config/defaultConfigArgument.ts', - } as any); + }); expect(resolvedConfig).toContain('just.config.ts'); }); - it('default config is used as last fallback', () => { + it('default config is used as last fallback', async () => { mockfs({ config: { 'configArgument.ts': 'formConfig', 'defaultConfigArgument.ts': 'formDefaultConfig', }, }); - const resolvedConfig = config.resolveConfigFile({ + const resolvedConfig = await config.resolveConfigFile({ config: undefined, defaultConfig: './config/defaultConfigArgument.ts', - } as any); + }); expect(resolvedConfig).toContain('defaultConfigArgument.ts'); }); + + it('resolves .mjs config', async () => { + mockfs({ + 'just.config.mjs': 'localConfig', + }); + const resolvedConfig = await config.resolveConfigFile({}); + expect(resolvedConfig).toContain('just.config.mjs'); + }); + + it('resolves .cjs config', async () => { + mockfs({ + 'just.config.cjs': 'localConfig', + }); + const resolvedConfig = await config.resolveConfigFile({}); + expect(resolvedConfig).toContain('just.config.cjs'); + }); }); diff --git a/packages/just-task/src/cli.ts b/packages/just-task/src/cli.ts index f57bb56b..516d4062 100644 --- a/packages/just-task/src/cli.ts +++ b/packages/just-task/src/cli.ts @@ -39,41 +39,48 @@ function showHelp() { } } -// Define a built-in option of "config" so users can specify which path to choose for configurations -option('config', { - describe: 'path to a just configuration file (includes the file name, e.g. /path/to/just.config.ts)', -}); -option('defaultConfig', { - describe: - 'path to a default just configuration file that will be used when the current project does not have a just configuration file. (includes the file name, e.g. /path/to/just.config.ts)', -}); -option('esm', { - describe: - 'Configure ts-node to support imports of ESM package (changes TS module/moduleResolution settings to Node16)', -}); +async function run() { + // Define a built-in option of "config" so users can specify which path to choose for configurations + option('config', { + describe: 'path to a just configuration file, e.g. ./path/to/just.config.ts', + }); + option('defaultConfig', { + describe: + 'path to a default just configuration file that will be used when the current project does not have a just configuration file. ' + + '(includes the file name, e.g. /path/to/just.config.ts)', + }); + option('esm', { + describe: 'No longer needed', + }); -const registry = undertaker.registry(); + const registry = undertaker.registry(); -const configModule = readConfig(); + const configModule = await readConfig(); -// Support named task function as exports of a config module -if (configModule && typeof configModule === 'object') { - for (const taskName of Object.keys(configModule)) { - if (typeof configModule[taskName] == 'function') { - task(taskName, configModule[taskName]); + // Support named task function as exports of a config module + if (configModule && typeof configModule === 'object') { + for (const taskName of Object.keys(configModule)) { + if (typeof configModule[taskName] == 'function') { + task(taskName, configModule[taskName]); + } } } -} -const command = parseCommand(); + const command = parseCommand(); -if (command) { - if (registry.get(command)) { - undertaker.series(registry.get(command))(() => undefined); + if (command) { + if (registry.get(command)) { + undertaker.series(registry.get(command))(() => undefined); + } else { + logger.error(`Command not defined: ${command}`); + process.exitCode = 1; + } } else { - logger.error(`Command not defined: ${command}`); - process.exitCode = 1; + showHelp(); } -} else { - showHelp(); } + +run().catch(e => { + logger.error(e.stack || e.message || e); + process.exit(1); +}); diff --git a/packages/just-task/src/config.ts b/packages/just-task/src/config.ts index ebc02dd9..eedabcbe 100644 --- a/packages/just-task/src/config.ts +++ b/packages/just-task/src/config.ts @@ -1,57 +1,93 @@ -import * as fs from 'fs'; import * as path from 'path'; - import { argv } from './option'; import { resolve } from './resolve'; import { mark, logger } from 'just-task-logger'; import { enableTypeScript } from './enableTypeScript'; -import yargsParser = require('yargs-parser'); import { TaskFunction } from './interfaces'; +import { readPackageJson } from 'just-scripts-utils'; + +export async function resolveConfigFile(args: { config?: string; defaultConfig?: string }): Promise { + // Check for the old config paths/extensions first + const paths = [ + args.config, + './just.config.js', + './just-task.js', + ...['.ts', '.cts', '.mts', '.cjs', '.mjs'].map(ext => `./just.config${ext}`), + args.defaultConfig, + ]; -export function resolveConfigFile(args: yargsParser.Arguments): string | null { - for (const entry of [args.config, './just.config.js', './just-task.js', './just.config.ts', args.defaultConfig]) { - const configFile = resolve(entry); - if (configFile) { - return configFile; + for (const entry of paths) { + const resolved = entry && resolve(entry); + if (resolved) { + return resolved; } } return null; } -export function readConfig(): { [key: string]: TaskFunction } | void { - // uses a separate instance of yargs to first parse the config (without the --help in the way) so we can parse the configFile first regardless - const args = argv(); - const configFile = resolveConfigFile(args); +export async function readConfig(): Promise<{ [key: string]: TaskFunction } | void> { + // uses a separate instance of yargs to first parse the config (without the --help in the way) + // so we can parse the configFile first regardless + const args = argv() as { config?: string; defaultConfig?: string }; + const configFile = await resolveConfigFile(args); + + if (!configFile) { + logger.error('Config file not found. Please create a file "just.config.js" at the package root.'); + process.exit(1); + } - if (configFile && fs.existsSync(configFile)) { - const ext = path.extname(configFile); - if (ext === '.ts' || ext === '.tsx') { - // TODO: add option to do typechecking as well - enableTypeScript({ transpileOnly: true, esm: args.esm }); + const packageJson = readPackageJson(process.cwd()); + const packageIsESM = packageJson?.type === 'module'; + + const ext = path.extname(configFile).toLowerCase(); + + if (/^\.[cm]?ts$/.test(ext)) { + const tsSuccess = enableTypeScript({ transpileOnly: true, configFile }); + if (!tsSuccess) { + process.exit(1); // enableTypeScript will log the error } + } - try { - const configModule = require(configFile); + let configModule = undefined; + try { + if (ext.startsWith('.m') || (packageIsESM && !ext.startsWith('.c'))) { + configModule = await import(configFile); + } else { + configModule = require(configFile); + } + } catch (e) { + logger.error(`Error loading configuration file: ${configFile}`); + logger.error((e as Error).stack || (e as Error).message || e); - mark('registry:configModule'); + if (ext === '.mts' || (packageIsESM && ext === '.ts')) { + // We can't directly support these with ts-node because we're calling register() rather than + // creating a child process with the custom --loader. + // (Related: https://typestrong.org/ts-node/docs/imports/) + const binPath = path.relative(process.cwd(), process.argv[1]); + logger.error(''); + logger.error( + 'Just does not directly support ESM TypeScript configuration files. You must either ' + + `use a .cts file, or call the just binary (${binPath}) via ts-node or tsx.`, + ); + } - if (typeof configModule === 'function') { - configModule(); - } + process.exit(1); + } - logger.perf('registry:configModule'); + mark('registry:configModule'); - return configModule; + if (typeof configModule === 'function') { + try { + await configModule(); } catch (e) { logger.error(`Invalid configuration file: ${configFile}`); - logger.error(`Error: ${e.stack || e.message || e}`); + logger.error(`Error running config function: ${(e as Error).stack || (e as Error).message || e}`); process.exit(1); } - } else { - logger.error( - `Cannot find config file "${configFile}".`, - `Please create a file called "just.config.js" in the root of the project next to "package.json".`, - ); } + + logger.perf('registry:configModule'); + + return configModule; } diff --git a/packages/just-task/src/enableTypeScript.ts b/packages/just-task/src/enableTypeScript.ts index 92b6cd21..da3b9697 100644 --- a/packages/just-task/src/enableTypeScript.ts +++ b/packages/just-task/src/enableTypeScript.ts @@ -1,35 +1,67 @@ +import * as fse from 'fs-extra'; +import * as path from 'path'; import { resolve } from './resolve'; import { logger } from 'just-task-logger'; -// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types -export function enableTypeScript({ transpileOnly = true, esm = false }): void { - const tsNodeModule = resolve('ts-node'); - if (tsNodeModule) { - const tsNode = require(tsNodeModule); - tsNode.register({ - transpileOnly, - skipProject: true, - compilerOptions: { - target: 'es2017', - module: esm ? 'node16' : 'commonjs', - strict: false, - skipLibCheck: true, - skipDefaultLibCheck: true, - moduleResolution: esm ? 'node16' : 'node', - allowJs: true, - esModuleInterop: true, - }, - files: ['just.config.ts'], - }); - } else { - logger.error(`In order to use TypeScript with just.config.ts, you need to install "ts-node" module: +/** + * Enable typescript support with ts-node. + * Returns true if successful. + */ +export function enableTypeScript(params: { transpileOnly?: boolean; configFile?: string }): boolean { + const { transpileOnly = true, configFile = '' } = params; - npm install -D ts-node + // Try to determine if the user is already running with a known transpiler. + // ts-node makes this easy by setting process.env.TS_NODE. + // tsx doesn't set a variable, so check a few places it might show up. + const contextVals = [ + ...process.argv, + ...process.execArgv, + process.env._, + process.env.npm_lifecycle_event, + process.env.npm_config_argv, + ]; + if (process.env.TS_NODE || contextVals.some(val => /[^.]tsx\b/.test(val || ''))) { + // It appears the user ran the just CLI with tsx or ts-node, so allow this. + return true; + } -or + const tsNodeModule = resolve('ts-node'); - yarn add -D ts-node + if (!tsNodeModule) { + logger.error(`In order to use TypeScript with just.config.ts, you need to install the "ts-node" package.`); + return false; + } -`); + // Use module/moduleResolution "node16" if supported for broadest compatibility + let supportsNode16Setting = false; + const typescriptPackageJson = resolve('typescript/package.json'); + if (typescriptPackageJson) { + const typescriptVersion = fse.readJsonSync(typescriptPackageJson).version as string; + const [major, minor] = typescriptVersion.split('.').map(Number); + supportsNode16Setting = major > 4 || (major === 4 && minor >= 7); } + + const tsNode = require(tsNodeModule) as typeof import('ts-node'); + const tsNodeMajor = Number(String(tsNode.VERSION || '0').split('.')[0]); + const ext = path.extname(configFile); + if (tsNodeMajor < 10 && ext !== '.ts') { + logger.error(`ts-node >= 10 is required for ${ext} extension support.`); + return false; + } + + tsNode.register({ + transpileOnly, + skipProject: true, + compilerOptions: { + target: 'es2017', + module: supportsNode16Setting ? 'node16' : 'commonjs', + strict: false, + skipLibCheck: true, + skipDefaultLibCheck: true, + moduleResolution: supportsNode16Setting ? 'node16' : 'node', + allowJs: true, + esModuleInterop: true, + }, + }); + return true; } diff --git a/packages/just-task/src/index.ts b/packages/just-task/src/index.ts index 9319f38d..cd6da75a 100644 --- a/packages/just-task/src/index.ts +++ b/packages/just-task/src/index.ts @@ -1,10 +1,10 @@ -export * from './undertaker'; -export * from './task'; -export * from './interfaces'; +export { parallel, series, undertaker } from './undertaker'; +export { task } from './task'; +export { Task, TaskContext, TaskFunction } from './interfaces'; export { condition } from './condition'; export { addResolvePath, resetResolvePaths, resolve, resolveCwd } from './resolve'; export { option, argv } from './option'; export { clearCache } from './cache'; -export * from './logger'; -export * from './chain'; -export * from './watch'; +export { Logger, logger, mark } from './logger'; +export { chain } from './chain'; +export { watch } from './watch'; diff --git a/scripts/jest.config.js b/scripts/jest.config.js index c6eb0229..17ba0cb3 100644 --- a/scripts/jest.config.js +++ b/scripts/jest.config.js @@ -5,7 +5,7 @@ const path = require('path'); * Jest config for packages within the just monorepo * @type {import('@jest/types').Config.InitialOptions} */ -module.exports = { +const config = { roots: ['/src'], testEnvironment: 'node', testMatch: ['**/?(*.)+(spec|test).[jt]s'], @@ -16,7 +16,10 @@ module.exports = { { tsconfig: path.join(process.cwd(), 'tsconfig.json'), packageJson: path.join(process.cwd(), 'package.json'), + // badly-named option means skip type checking (it's done as part of the build) + isolatedModules: true, }, ], }, }; +module.exports = config; diff --git a/tsconfig.json b/tsconfig.json index d311d550..9f8553d3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,8 +1,8 @@ { "compilerOptions": { "target": "es2019", - "module": "commonjs", - "moduleResolution": "node", + "module": "Node16", + "moduleResolution": "Node16", "pretty": true, "declaration": true, "declarationMap": true, diff --git a/yarn.lock b/yarn.lock index f9b5dbd2..96d6fdd9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1008,6 +1008,13 @@ resolved "https://registry.yarnpkg.com/@braintree/sanitize-url/-/sanitize-url-3.1.0.tgz#8ff71d51053cd5ee4981e5a501d80a536244f7fd" integrity sha512-GcIY79elgB+azP74j8vqkiXz8xLFfIzbQJdlwOPisgbKT00tviJQuEghOXSMVxJ00HoYJbGswr4kcllUc4xCcg== +"@cspotcode/source-map-support@^0.8.0": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" + integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== + dependencies: + "@jridgewell/trace-mapping" "0.3.9" + "@eslint-community/eslint-utils@^4.2.0": version "4.4.0" resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" @@ -1276,6 +1283,11 @@ "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" +"@jridgewell/resolve-uri@^3.0.3": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" + integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== + "@jridgewell/resolve-uri@^3.1.0": version "3.1.1" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" @@ -1291,6 +1303,14 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== +"@jridgewell/trace-mapping@0.3.9": + version "0.3.9" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.9": version "0.3.19" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz#f8a3249862f91be48d3127c3cfe992f79b4b8811" @@ -1444,6 +1464,26 @@ dependencies: defer-to-connect "^1.0.1" +"@tsconfig/node10@^1.0.7": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" + integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== + +"@tsconfig/node12@^1.0.7": + version "1.0.11" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" + integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== + +"@tsconfig/node14@^1.0.0": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" + integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== + +"@tsconfig/node16@^1.0.2": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" + integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== + "@types/argparse@1.0.38": version "1.0.38" resolved "https://registry.yarnpkg.com/@types/argparse/-/argparse-1.0.38.tgz#a81fd8606d481f873a3800c6ebae4f1d768a56a9" @@ -2365,11 +2405,21 @@ acorn-jsx@^5.3.2: resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== +acorn-walk@^8.1.1: + version "8.3.2" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.2.tgz#7703af9415f1b6db9315d6895503862e231d34aa" + integrity sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A== + acorn@^6.4.1: version "6.4.2" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== +acorn@^8.4.1: + version "8.11.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" + integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== + acorn@^8.9.0: version "8.10.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" @@ -10984,6 +11034,25 @@ ts-jest@^29.0.5: semver "^7.5.3" yargs-parser "^21.0.1" +ts-node@^10.0.0: + version "10.9.2" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.2.tgz#70f021c9e185bccdca820e26dc413805c101c71f" + integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ== + dependencies: + "@cspotcode/source-map-support" "^0.8.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + v8-compile-cache-lib "^3.0.1" + yn "3.1.1" + ts-node@^9.1.1: version "9.1.1" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-9.1.1.tgz#51a9a450a3e959401bda5f004a72d54b936d376d" @@ -11121,10 +11190,10 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== -typescript@~4.3.5: - version "4.3.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4" - integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA== +typescript@~4.7.0: + version "4.7.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235" + integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ== typescript@~5.0.4: version "5.0.4" @@ -11410,6 +11479,11 @@ uuid@^9.0.0: resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5" integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg== +v8-compile-cache-lib@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" + integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== + v8-to-istanbul@^9.0.1: version "9.1.0" resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz#1b83ed4e397f58c85c266a570fc2558b5feb9265"