diff --git a/.eslintrc.js b/.eslintrc.js index de99730a..3dd5fc2d 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -50,6 +50,13 @@ module.exports = { 'no-console': 'off', }, }, + { + files: ['packages/jest/lib/**/*.ts'], + rules: { + 'import/no-default-export': 'off', + 'import/no-named-as-default': 'off', + }, + }, { files: ['example/**/*'], rules: { diff --git a/.yarn/cache/@jest-create-cache-key-function-npm-27.5.1-d4c8561229-a6c3a8c769.zip b/.yarn/cache/@jest-create-cache-key-function-npm-27.5.1-d4c8561229-a6c3a8c769.zip new file mode 100644 index 00000000..e1652a98 Binary files /dev/null and b/.yarn/cache/@jest-create-cache-key-function-npm-27.5.1-d4c8561229-a6c3a8c769.zip differ diff --git a/.yarn/cache/@jest-create-cache-key-function-npm-29.7.0-786396764f-681bc761fa.zip b/.yarn/cache/@jest-create-cache-key-function-npm-29.7.0-786396764f-681bc761fa.zip new file mode 100644 index 00000000..a9b0f9f6 Binary files /dev/null and b/.yarn/cache/@jest-create-cache-key-function-npm-29.7.0-786396764f-681bc761fa.zip differ diff --git a/.yarn/cache/@swc-jest-npm-0.2.29-83a2d9fed7-9eaad32231.zip b/.yarn/cache/@swc-jest-npm-0.2.29-83a2d9fed7-9eaad32231.zip new file mode 100644 index 00000000..27242f39 Binary files /dev/null and b/.yarn/cache/@swc-jest-npm-0.2.29-83a2d9fed7-9eaad32231.zip differ diff --git a/.yarn/cache/swc-plugin-coverage-instrument-npm-0.0.20-e82119d110-4d182c67b9.zip b/.yarn/cache/swc-plugin-coverage-instrument-npm-0.0.20-e82119d110-4d182c67b9.zip new file mode 100644 index 00000000..27765c27 Binary files /dev/null and b/.yarn/cache/swc-plugin-coverage-instrument-npm-0.0.20-e82119d110-4d182c67b9.zip differ diff --git a/example/.eslintrc.js b/example/.eslintrc.js new file mode 100644 index 00000000..ec29fcfd --- /dev/null +++ b/example/.eslintrc.js @@ -0,0 +1,46 @@ +const { resolve } = require('node:path'); + +const project = resolve(__dirname, 'tsconfig.json'); + +/** @type { import('eslint').ESLint.ConfigData } */ +module.exports = { + root: true, + env: { + node: true, + }, + plugins: ['prettier'], + extends: [ + require.resolve('@vercel/style-guide/eslint/node'), + require.resolve('@vercel/style-guide/eslint/typescript'), + ], + parserOptions: { + project, + }, + settings: { + 'import/resolver': { + typescript: { + project, + }, + }, + }, + overrides: [ + { + files: ['*.ts?(x)', '*.js?(x)'], + rules: { + semi: ['error', 'always'], + quotes: ['error', 'single'], + 'object-curly-spacing': ['error', 'always'], + 'array-bracket-spacing': 'off', + 'no-console': 'off', + 'unicorn/filename-case': 'off', + 'prettier/prettier': 'error', + }, + }, + { + files: ['*.test.ts?(x)', '*.spec.js?(x)'], + rules: { + 'import/no-named-as-default-member': 'off', + }, + }, + ], +}; diff --git a/example/.gitignore b/example/.gitignore index 82a4ae22..f4c3ff65 100644 --- a/example/.gitignore +++ b/example/.gitignore @@ -75,6 +75,7 @@ yarn-error.log # @react-native-esbuild .rne +.swc # @react-native-esbuild for web public/ diff --git a/example/__tests__/App.test.tsx b/example/__tests__/App.test.tsx index 43456926..7f855360 100644 --- a/example/__tests__/App.test.tsx +++ b/example/__tests__/App.test.tsx @@ -1,17 +1,11 @@ -/** - * @format - */ - -import 'react-native'; -import React from 'react'; -import App from '../src/App'; - -// Note: import explicitly to use the types shiped with jest. -import {it} from '@jest/globals'; - -// Note: test renderer must be required after react-native. -import renderer from 'react-test-renderer'; - -it('renders correctly', () => { - renderer.create(); +import { describe, it } from '@jest/globals'; +import renderer, { act } from 'react-test-renderer'; +import { App } from '../src/App'; + +describe('App', () => { + it('renders correctly', async () => { + await act(() => { + renderer.create(); + }); + }); }); diff --git a/example/babel.config.js b/example/babel.config.js index 983e075d..b18dd931 100644 --- a/example/babel.config.js +++ b/example/babel.config.js @@ -1,4 +1,7 @@ module.exports = { presets: ['module:metro-react-native-babel-preset'], - plugins: ['react-native-reanimated/plugin'], + plugins: [ + ['@babel/plugin-transform-private-methods', { loose: true }], + 'react-native-reanimated/plugin', + ], }; diff --git a/example/jest.config.js b/example/jest.config.js index 8eb675e9..7aec26d4 100644 --- a/example/jest.config.js +++ b/example/jest.config.js @@ -1,3 +1,28 @@ +const TRANSFORM_PACKAGE = [ + 'react-native', + 'jest-react-native', + '@react-native', + '@react-native-community', + '@react-navigation', + '@expo/html-elements', + 'dripsy', +]; + +/** + * @type {import('jest').Config} + */ module.exports = { preset: 'react-native', + transform: { + '^.+\\.(t|j)sx?$': '@react-native-esbuild/jest', + }, + transformIgnorePatterns: [`node_modules/(?!${TRANSFORM_PACKAGE.join('|')})/`], + testPathIgnorePatterns: ['dist'], + coveragePathIgnorePatterns: ['node_modules'], + collectCoverageFrom: [ + 'src/**/*.{js,jsx,ts,tsx}', + '!**/*.d.ts', + '!**/index.ts', + ], + setupFilesAfterEnv: ['./tests/setup.ts'], }; diff --git a/example/package.json b/example/package.json index ce7adeaa..891bc8f1 100644 --- a/example/package.json +++ b/example/package.json @@ -37,16 +37,20 @@ "devDependencies": { "@babel/core": "^7.20.0", "@babel/plugin-transform-export-namespace-from": "^7.22.11", + "@babel/plugin-transform-private-methods": "^7.22.5", "@babel/preset-env": "^7.20.0", "@babel/runtime": "^7.20.0", + "@jest/globals": "^29.7.0", "@react-native-community/cli": "^11.3.6", "@react-native-community/cli-platform-android": "^11.3.6", "@react-native-esbuild/cli": "workspace:^", + "@react-native-esbuild/jest": "workspace:^", "@react-native/assets-registry": "^0.73.0", "@react-native/codegen": "^0.72.6", "@react-native/gradle-plugin": "^0.72.11", "@react-native/metro-config": "^0.72.11", "@react-navigation/devtools": "^6.0.19", + "@swc/jest": "^0.2.29", "@tsconfig/react-native": "^3.0.0", "@types/react": "^18.0.24", "@types/react-test-renderer": "^18.0.0", diff --git a/example/tests/setup.ts b/example/tests/setup.ts new file mode 100644 index 00000000..a6a4fe0f --- /dev/null +++ b/example/tests/setup.ts @@ -0,0 +1,8 @@ +import 'react-native-gesture-handler/jestSetup'; +import { setUpTests } from 'react-native-reanimated'; + +setUpTests(); + +jest.mock('@react-navigation/devtools', () => ({ + useFlipper: jest.fn(), +})); diff --git a/example/tsconfig.json b/example/tsconfig.json index ce945215..852e746b 100644 --- a/example/tsconfig.json +++ b/example/tsconfig.json @@ -4,5 +4,5 @@ "rootDir": ".", "jsx": "react-native" }, - "include": ["src/**/*"] + "include": ["src/**/*", "tests/*", "__tests__/**/*"] } diff --git a/packages/core/lib/bundler/bundler.ts b/packages/core/lib/bundler/bundler.ts index 99f9ec2a..710fb345 100644 --- a/packages/core/lib/bundler/bundler.ts +++ b/packages/core/lib/bundler/bundler.ts @@ -78,6 +78,10 @@ export class ReactNativeEsbuildBundler extends BundlerEventEmitter { } } + public static getConfig(): Config { + return getConfigFromGlobal(); + } + public static setGlobalLogLevel(logLevel: LogLevel): void { Logger.setGlobalLogLevel(logLevel); } @@ -443,10 +447,6 @@ export class ReactNativeEsbuildBundler extends BundlerEventEmitter { return buildTask.handler.task; } - public getConfig(): Config { - return this.config; - } - public getRoot(): string { return this.root; } diff --git a/packages/jest/.gitignore b/packages/jest/.gitignore new file mode 100644 index 00000000..57eadd03 --- /dev/null +++ b/packages/jest/.gitignore @@ -0,0 +1,2 @@ +# preset +jest-preset.js diff --git a/packages/jest/README.md b/packages/jest/README.md new file mode 100644 index 00000000..d3d60add --- /dev/null +++ b/packages/jest/README.md @@ -0,0 +1,42 @@ +# `@react-native-esbuild/jest` + +> react-native preset for jest powered by @react-native-esbuild + +## Usage + +```js +exports.default = { + preset: 'react-native', + transform: { + '^.+\\.(t|j)sx?$': '@react-native-esbuild/jest', + }, +}; + +// With transformer options(for enable custom instrument). +exports.default = { + preset: 'react-native', + transform: { + '^.+\\.(t|j)sx?$': ['@react-native-esbuild/jest', /* TransformerConfig */], + }, +}; +``` + +```ts +/** + * @see {@link https://github.com/kwonoj/swc-plugin-coverage-instrument} + */ +interface TransformerConfig { + experimental?: { + customCoverageInstrumentation?: { + coverageVariable?: string; + compact: boolean; + reportLogic: boolean; + ignoreClassMethods: string[]; + instrumentLog?: { + level: string; + enableTrace: boolean; + }; + }; + }; +} +``` diff --git a/packages/jest/build/index.js b/packages/jest/build/index.js new file mode 100644 index 00000000..11d3d095 --- /dev/null +++ b/packages/jest/build/index.js @@ -0,0 +1,9 @@ +const esbuild = require('esbuild'); +const { getEsbuildBaseOptions } = require('../../../shared'); + +const buildOptions = getEsbuildBaseOptions(__dirname); + +esbuild.build(buildOptions).catch((error) => { + console.error(error); + process.exit(1); +}); diff --git a/packages/jest/lib/index.ts b/packages/jest/lib/index.ts new file mode 100644 index 00000000..2bb2a429 --- /dev/null +++ b/packages/jest/lib/index.ts @@ -0,0 +1,8 @@ +import type { TransformerFactory } from '@jest/transform'; +import { createTransformer } from './transformer'; + +const factory: TransformerFactory> = { + createTransformer, +}; + +export default factory; diff --git a/packages/jest/lib/transformer/createTransformer.ts b/packages/jest/lib/transformer/createTransformer.ts new file mode 100644 index 00000000..36f33c9b --- /dev/null +++ b/packages/jest/lib/transformer/createTransformer.ts @@ -0,0 +1,114 @@ +import type { + Transformer, + TransformOptions, + TransformedSource, +} from '@jest/transform'; +import getCacheKeyFunction from '@jest/create-cache-key-function'; +import md5 from 'md5'; +import { ReactNativeEsbuildBundler } from '@react-native-esbuild/core'; +import { + SyncTransformPipeline, + AsyncTransformPipeline, + swcPresets, +} from '@react-native-esbuild/transformer'; +import { getReactNativeInitializeCore } from '@react-native-esbuild/internal'; +import type { TransformerConfig } from '../types'; +import pkg from '../../package.json'; + +const DUMMY_ENTRY = ''; +const DUMMY_ESBUILD_VALUE = ''; +const ROOT = process.cwd(); + +ReactNativeEsbuildBundler.bootstrap(); + +export const createTransformer = (config: TransformerConfig): Transformer => { + const cacheKeyFunction = getCacheKeyFunction([], [pkg.version]); + const { transformer } = ReactNativeEsbuildBundler.getConfig(); + const instrumentEnabled = Boolean( + config.experimental?.customCoverageInstrumentation, + ); + const swcExperimentalOptions = instrumentEnabled + ? config.experimental + : undefined; + + const syncTransformPipeline = new SyncTransformPipeline.builder( + ROOT, + DUMMY_ENTRY, + { + swc: swcPresets.getJestOptions({ + module: 'cjs', + experimental: swcExperimentalOptions, + }), + }, + ) + .setInjectScripts([getReactNativeInitializeCore(ROOT)]) + .setFullyTransformPackages(transformer?.fullyTransformPackageNames ?? []) + .setStripFlowPackages(transformer?.stripFlowPackageNames ?? []) + .setAdditionalBabelTransformRules( + transformer?.additionalTransformRules?.babel ?? [], + ) + .setAdditionalSwcTransformRules( + transformer?.additionalTransformRules?.swc ?? [], + ) + .build(); + + const asyncTransformPipeline = new AsyncTransformPipeline.builder( + ROOT, + DUMMY_ENTRY, + { + // Async transform is always ESM. + swc: swcPresets.getJestOptions({ + module: 'esm', + experimental: swcExperimentalOptions, + }), + }, + ) + .setInjectScripts([getReactNativeInitializeCore(ROOT)]) + .setFullyTransformPackages(transformer?.fullyTransformPackageNames ?? []) + .setStripFlowPackages(transformer?.stripFlowPackageNames ?? []) + .setAdditionalBabelTransformRules( + transformer?.additionalTransformRules?.babel ?? [], + ) + .setAdditionalSwcTransformRules( + transformer?.additionalTransformRules?.swc ?? [], + ) + .build(); + + return { + canInstrument: instrumentEnabled, + process: ( + code: string, + path: string, + _options: TransformOptions, + ): TransformedSource => { + const transformResult = syncTransformPipeline.transform(code, { + path, + pluginData: DUMMY_ESBUILD_VALUE, + namespace: DUMMY_ESBUILD_VALUE, + suffix: DUMMY_ESBUILD_VALUE, + }); + return { code: transformResult.code }; + }, + processAsync: async ( + code: string, + path: string, + _options: TransformOptions, + ): Promise => { + const transformResult = await asyncTransformPipeline.transform(code, { + path, + pluginData: DUMMY_ESBUILD_VALUE, + namespace: DUMMY_ESBUILD_VALUE, + suffix: DUMMY_ESBUILD_VALUE, + }); + return { code: transformResult.code }; + }, + getCacheKey: ( + code: string, + path: string, + options: TransformOptions, + ): string => { + // @ts-expect-error -- `NewGetCacheKeyFunction` + return md5(cacheKeyFunction(code, path, options)); + }, + }; +}; diff --git a/packages/jest/lib/transformer/index.ts b/packages/jest/lib/transformer/index.ts new file mode 100644 index 00000000..77c8d3b4 --- /dev/null +++ b/packages/jest/lib/transformer/index.ts @@ -0,0 +1 @@ +export * from './createTransformer'; diff --git a/packages/jest/lib/types.ts b/packages/jest/lib/types.ts new file mode 100644 index 00000000..e0cd68fe --- /dev/null +++ b/packages/jest/lib/types.ts @@ -0,0 +1,3 @@ +import type { SwcJestPresetOptions } from '@react-native-esbuild/transformer'; + +export type TransformerConfig = Omit; diff --git a/packages/jest/package.json b/packages/jest/package.json new file mode 100644 index 00000000..e949ae14 --- /dev/null +++ b/packages/jest/package.json @@ -0,0 +1,56 @@ +{ + "name": "@react-native-esbuild/jest", + "version": "0.1.0-beta.9", + "description": "react-native preset for jest powered by @react-native-esbuild", + "keywords": [ + "react-native", + "esbuild", + "jest" + ], + "author": "leegeunhyeok ", + "homepage": "https://github.com/leegeunhyeok/react-native-esbuild#readme", + "license": "MIT", + "type": "commonjs", + "module": "lib/index.ts", + "main": "dist/index.js", + "types": "dist/lib/index.d.ts", + "directories": { + "lib": "lib", + "test": "__tests__" + }, + "files": [ + "lib", + "dist", + "jest-preset.js" + ], + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/leegeunhyeok/react-native-esbuild.git" + }, + "scripts": { + "prepack": "yarn cleanup && yarn build", + "cleanup": "rimraf ./dist", + "build": "node build/index.js && tsc" + }, + "bugs": { + "url": "https://github.com/leegeunhyeok/react-native-esbuild/issues" + }, + "peerDependencies": { + "react-native": "*" + }, + "dependencies": { + "@jest/create-cache-key-function": "^29.7.0", + "@react-native-esbuild/core": "workspace:*", + "@react-native-esbuild/internal": "workspace:^", + "@react-native-esbuild/transformer": "workspace:*", + "md5": "^2.3.0" + }, + "devDependencies": { + "@jest/transform": "^29.7.0", + "@types/md5": "^2.3.2", + "esbuild": "^0.19.5" + } +} diff --git a/packages/jest/tsconfig.json b/packages/jest/tsconfig.json new file mode 100644 index 00000000..bd42e358 --- /dev/null +++ b/packages/jest/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "rootDir": ".", + "outDir": "./dist", + "declaration": true, + "emitDeclarationOnly": true + }, + "include": ["./lib"], + "exclude": ["./dist"] +} diff --git a/packages/transformer/lib/pipelines/builder.ts b/packages/transformer/lib/pipelines/builder.ts index b292bfb6..f62859b8 100644 --- a/packages/transformer/lib/pipelines/builder.ts +++ b/packages/transformer/lib/pipelines/builder.ts @@ -20,7 +20,7 @@ export abstract class TransformPipelineBuilder< protected transformerOptions: { swc?: SwcTransformOptions; babel?: BabelTransformOptions; - }; + } = {}; protected injectScriptPaths: string[] = []; protected fullyTransformPackageNames: string[] = []; protected stripFlowPackageNames: string[] = []; diff --git a/packages/transformer/lib/transformer/swc/presets.ts b/packages/transformer/lib/transformer/swc/presets.ts index 8caa7872..2b79f320 100644 --- a/packages/transformer/lib/transformer/swc/presets.ts +++ b/packages/transformer/lib/transformer/swc/presets.ts @@ -1,4 +1,5 @@ import type { Options } from '@swc/core'; +import type { SwcJestPresetOptions } from '../../types'; /** * swc transform options preset for react-native runtime. @@ -20,7 +21,7 @@ const getReactNativeRuntimeOptions = (): Options => ({ /** * swc transform options preset for jest. */ -const getJestOptions = (): Options => ({ +const getJestOptions = (options: SwcJestPresetOptions): Options => ({ sourceMaps: 'inline', jsc: { target: 'es2022', @@ -36,8 +37,22 @@ const getJestOptions = (): Options => ({ runtime: 'automatic', }, }, + experimental: { + ...(options.experimental?.customCoverageInstrumentation + ? { + plugins: [ + [ + 'swc-plugin-coverage-instrument', + options.experimental.customCoverageInstrumentation, + ], + ], + } + : null), + }, + }, + module: { + type: options.module === 'esm' ? 'es6' : 'commonjs', }, - module: { type: 'commonjs' }, }); export { getReactNativeRuntimeOptions, getJestOptions }; diff --git a/packages/transformer/lib/types.ts b/packages/transformer/lib/types.ts index 3e3f32e8..034a50db 100644 --- a/packages/transformer/lib/types.ts +++ b/packages/transformer/lib/types.ts @@ -19,6 +19,23 @@ export interface TransformerContext { root: string; } +// swc presets +export interface SwcJestPresetOptions { + module?: 'cjs' | 'esm'; + experimental?: { + /** + * @see {@link https://github.com/kwonoj/swc-plugin-coverage-instrument} + */ + customCoverageInstrumentation?: { + coverageVariable?: string; + compact?: boolean; + reportLogic?: boolean; + ignoreClassMethods?: string[]; + instrumentLog?: { level: string; enableTrace: boolean }; + }; + }; +} + export interface TransformRuleBase { /** * Predicator for transform diff --git a/packages/transformer/package.json b/packages/transformer/package.json index 35b92e36..b1f030b8 100644 --- a/packages/transformer/package.json +++ b/packages/transformer/package.json @@ -45,6 +45,7 @@ "@react-native-esbuild/config": "workspace:*", "@swc/core": "^1.3.94", "@swc/helpers": "^0.5.3", - "sucrase": "^3.34.0" + "sucrase": "^3.34.0", + "swc-plugin-coverage-instrument": "^0.0.20" } } diff --git a/packages/transformer/tsconfig.json b/packages/transformer/tsconfig.json index bd42e358..5457e96f 100644 --- a/packages/transformer/tsconfig.json +++ b/packages/transformer/tsconfig.json @@ -6,6 +6,6 @@ "declaration": true, "emitDeclarationOnly": true }, - "include": ["./lib"], + "include": ["./lib", "./tests"], "exclude": ["./dist"] } diff --git a/yarn.lock b/yarn.lock index 8f2722df..950217e6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3565,6 +3565,15 @@ __metadata: languageName: node linkType: hard +"@jest/create-cache-key-function@npm:^27.4.2": + version: 27.5.1 + resolution: "@jest/create-cache-key-function@npm:27.5.1" + dependencies: + "@jest/types": ^27.5.1 + checksum: a6c3a8c769aca6f66f5dc80f1c77e66980b4f213a6b2a15a92ba3595f032848a1261c06c9c798dcf2b672b1ffbefad5085af89d130548741c85ddbe0cf4284e7 + languageName: node + linkType: hard + "@jest/create-cache-key-function@npm:^29.2.1": version: 29.6.2 resolution: "@jest/create-cache-key-function@npm:29.6.2" @@ -3574,6 +3583,15 @@ __metadata: languageName: node linkType: hard +"@jest/create-cache-key-function@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/create-cache-key-function@npm:29.7.0" + dependencies: + "@jest/types": ^29.6.3 + checksum: 681bc761fa1d6fa3dd77578d444f97f28296ea80755e90e46d1c8fa68661b9e67f54dd38b988742db636d26cf160450dc6011892cec98b3a7ceb58cad8ff3aae + languageName: node + linkType: hard + "@jest/environment@npm:^29.6.2": version: 29.6.2 resolution: "@jest/environment@npm:29.6.2" @@ -4938,7 +4956,7 @@ __metadata: languageName: unknown linkType: soft -"@react-native-esbuild/internal@workspace:*, @react-native-esbuild/internal@workspace:packages/internal": +"@react-native-esbuild/internal@workspace:*, @react-native-esbuild/internal@workspace:^, @react-native-esbuild/internal@workspace:packages/internal": version: 0.0.0-use.local resolution: "@react-native-esbuild/internal@workspace:packages/internal" dependencies: @@ -4948,6 +4966,23 @@ __metadata: languageName: unknown linkType: soft +"@react-native-esbuild/jest@workspace:^, @react-native-esbuild/jest@workspace:packages/jest": + version: 0.0.0-use.local + resolution: "@react-native-esbuild/jest@workspace:packages/jest" + dependencies: + "@jest/create-cache-key-function": ^29.7.0 + "@jest/transform": ^29.7.0 + "@react-native-esbuild/core": "workspace:*" + "@react-native-esbuild/internal": "workspace:^" + "@react-native-esbuild/transformer": "workspace:*" + "@types/md5": ^2.3.2 + esbuild: ^0.19.5 + md5: ^2.3.0 + peerDependencies: + react-native: "*" + languageName: unknown + linkType: soft + "@react-native-esbuild/plugins@workspace:*, @react-native-esbuild/plugins@workspace:packages/plugins": version: 0.0.0-use.local resolution: "@react-native-esbuild/plugins@workspace:packages/plugins" @@ -4990,6 +5025,7 @@ __metadata: "@swc/helpers": ^0.5.3 esbuild: ^0.19.5 sucrase: ^3.34.0 + swc-plugin-coverage-instrument: ^0.0.20 languageName: unknown linkType: soft @@ -5696,6 +5732,18 @@ __metadata: languageName: node linkType: hard +"@swc/jest@npm:^0.2.29": + version: 0.2.29 + resolution: "@swc/jest@npm:0.2.29" + dependencies: + "@jest/create-cache-key-function": ^27.4.2 + jsonc-parser: ^3.2.0 + peerDependencies: + "@swc/core": "*" + checksum: 9eaad322310f34e81f67d41411a7d60663341af1bd9fb65456faa914c936d849d6f643fa3b942a187d52e71e62c33097098c639d25c2047fa874f49bf51cec76 + languageName: node + linkType: hard + "@swc/types@npm:^0.1.5": version: 0.1.5 resolution: "@swc/types@npm:0.1.5" @@ -11317,11 +11365,14 @@ __metadata: dependencies: "@babel/core": ^7.20.0 "@babel/plugin-transform-export-namespace-from": ^7.22.11 + "@babel/plugin-transform-private-methods": ^7.22.5 "@babel/preset-env": ^7.20.0 "@babel/runtime": ^7.20.0 + "@jest/globals": ^29.7.0 "@react-native-community/cli": ^11.3.6 "@react-native-community/cli-platform-android": ^11.3.6 "@react-native-esbuild/cli": "workspace:^" + "@react-native-esbuild/jest": "workspace:^" "@react-native/assets-registry": ^0.73.0 "@react-native/codegen": ^0.72.6 "@react-native/gradle-plugin": ^0.72.11 @@ -11329,6 +11380,7 @@ __metadata: "@react-navigation/devtools": ^6.0.19 "@react-navigation/native": ^6.1.7 "@react-navigation/stack": ^6.3.17 + "@swc/jest": ^0.2.29 "@tsconfig/react-native": ^3.0.0 "@types/react": ^18.0.24 "@types/react-test-renderer": ^18.0.0 @@ -14973,7 +15025,7 @@ __metadata: languageName: node linkType: hard -"jsonc-parser@npm:3.2.0": +"jsonc-parser@npm:3.2.0, jsonc-parser@npm:^3.2.0": version: 3.2.0 resolution: "jsonc-parser@npm:3.2.0" checksum: 946dd9a5f326b745aa326d48a7257e3f4a4b62c5e98ec8e49fa2bdd8d96cef7e6febf1399f5c7016114fd1f68a1c62c6138826d5d90bc650448e3cf0951c53c7 @@ -21385,6 +21437,13 @@ __metadata: languageName: node linkType: hard +"swc-plugin-coverage-instrument@npm:^0.0.20": + version: 0.0.20 + resolution: "swc-plugin-coverage-instrument@npm:0.0.20" + checksum: 4d182c67b9db10280c5f2cc3e234afd6bb939c8aa0c92ba215fe1dc8d283f3114d39531bfc28f1046d9f5d26737599ca6a8dbcdf874a5275ac62f73c5ffe01d3 + languageName: node + linkType: hard + "synckit@npm:0.8.5, synckit@npm:^0.8.5": version: 0.8.5 resolution: "synckit@npm:0.8.5"