diff --git a/docs/common/utilities.ts b/docs/common/utilities.ts index 72172e81a8111b..015a21234c5f4b 100644 --- a/docs/common/utilities.ts +++ b/docs/common/utilities.ts @@ -183,7 +183,7 @@ export function versionToText(version: string): string { return 'Next (unversioned)'; } else if (version === 'latest') { return `${formatSdkVersion(LATEST_VERSION)} (latest)`; - } else if (BETA_VERSION && version === BETA_VERSION.toString()) { + } else if (version === BETA_VERSION?.toString()) { return `${formatSdkVersion(BETA_VERSION.toString())} (beta)`; } diff --git a/docs/components/plugins/APISection.tsx b/docs/components/plugins/APISection.tsx index 9d2be22f8f992c..f15c409e4c14cc 100644 --- a/docs/components/plugins/APISection.tsx +++ b/docs/components/plugins/APISection.tsx @@ -130,8 +130,8 @@ const isComponent = (entry: GeneratedData) => { } else if (signatures?.length) { const mainSignature = signatures[0]; if ( - (mainSignature.parameters && mainSignature.parameters[0].name === 'props') || - (mainSignature.parameters && mainSignature.parameters[0].name === '__namedParameters') + mainSignature.parameters?.[0].name === 'props' || + mainSignature.parameters?.[0].name === '__namedParameters' ) { return true; } diff --git a/docs/components/plugins/api/APISectionCompoundNames.ts b/docs/components/plugins/api/APISectionCompoundNames.ts index 9cc0f0795445ef..da55af959542cf 100644 --- a/docs/components/plugins/api/APISectionCompoundNames.ts +++ b/docs/components/plugins/api/APISectionCompoundNames.ts @@ -34,7 +34,7 @@ export const getComponentPropertyChildren = (entry: GeneratedData): PropData[] = const seen = new Set(); return candidates.filter(child => { - if (!child || child.kind !== TypeDocKind.Property) { + if (child?.kind !== TypeDocKind.Property) { return false; } const id = `${child.name ?? ''}-${child.kind ?? ''}`; diff --git a/docs/components/plugins/api/APISectionEnums.tsx b/docs/components/plugins/api/APISectionEnums.tsx index f8bb86efa3d788..67caf20e284959 100644 --- a/docs/components/plugins/api/APISectionEnums.tsx +++ b/docs/components/plugins/api/APISectionEnums.tsx @@ -14,7 +14,7 @@ export type APISectionEnumsProps = { }; const sortByValue = (a: EnumValueData, b: EnumValueData) => { - if (a.type && a.type.value !== undefined && b.type && b.type.value !== undefined) { + if (a.type?.value !== undefined && b.type?.value !== undefined) { if (typeof a.type.value === 'string' && typeof b.type.value === 'string') { return a.type.value.localeCompare(b.type.value); } else if (typeof a.type.value === 'number' && typeof b.type.value === 'number') { diff --git a/docs/components/plugins/api/APISectionUtils.tsx b/docs/components/plugins/api/APISectionUtils.tsx index 21bdd4a0f94df1..23af41f4c12131 100644 --- a/docs/components/plugins/api/APISectionUtils.tsx +++ b/docs/components/plugins/api/APISectionUtils.tsx @@ -270,7 +270,7 @@ export const resolveTypeName = ( return 'See description for available values.'; } return renderUnion(types, { sdkVersion }); - } else if (elementType && elementType.type === 'union' && elementType?.types?.length) { + } else if (elementType?.type === 'union' && elementType?.types?.length) { const unionTypes = elementType?.types ?? []; return ( <> diff --git a/docs/components/plugins/api/components/APIDataType.tsx b/docs/components/plugins/api/components/APIDataType.tsx index 030fb8451f5643..f1844187fc3f7f 100644 --- a/docs/components/plugins/api/components/APIDataType.tsx +++ b/docs/components/plugins/api/components/APIDataType.tsx @@ -20,7 +20,7 @@ export const APIDataType = ({ typeDefinition, sdkVersion, inline = true }: APIDa const isIntersectionWithObject = type === 'intersection' && types?.filter(typeDefinitionContainsObject).length; const isUnionWithObject = - (type === 'union' || (elementType && elementType.type === 'union')) && + (type === 'union' || elementType?.type === 'union') && (types?.filter(typeDefinitionContainsObject)?.length ?? 0) > 0; const isObjectWrapped = type === 'reference' && diff --git a/docs/jest.config.js b/docs/jest.config.js index 40e6da9bedd977..ee6e8d68c5dc42 100644 --- a/docs/jest.config.js +++ b/docs/jest.config.js @@ -20,6 +20,9 @@ const jestConfig = { '^nanoid/index.browser.js$': '/node_modules/nanoid/index.browser.cjs', '^nanoid$': '/node_modules/nanoid/index.cjs', '^nanoid/non-secure$': '/node_modules/nanoid/non-secure/index.cjs', + // c15t (used by our cookie consent) bundles CSS modules that jsdom cannot parse + '^@expo/styleguide-cookie-consent$': + '/node_modules/@expo/styleguide-cookie-consent/mock.js', }, transform: {}, extensionsToTreatAsEsm: ['.ts', '.tsx'], diff --git a/docs/package.json b/docs/package.json index 81b5afc2e06ddd..db6311a07b014a 100644 --- a/docs/package.json +++ b/docs/package.json @@ -35,6 +35,7 @@ "dependencies": { "@expo/styleguide": "^9.3.1", "@expo/styleguide-base": "^2.0.5", + "@expo/styleguide-cookie-consent": "^0.1.11", "@expo/styleguide-icons": "^2.3.4", "@expo/styleguide-search-ui": "^3.3.3", "@kapaai/react-sdk": "^0.9.0", diff --git a/docs/pages/_app.tsx b/docs/pages/_app.tsx index 0ab1292908ea1c..05e1274139dceb 100644 --- a/docs/pages/_app.tsx +++ b/docs/pages/_app.tsx @@ -1,4 +1,5 @@ import { ThemeProvider } from '@expo/styleguide'; +import { CookieConsentProvider } from '@expo/styleguide-cookie-consent'; import { KapaProvider } from '@kapaai/react-sdk'; import { MDXProvider } from '@mdx-js/react'; import * as Sentry from '@sentry/react'; @@ -9,7 +10,7 @@ import { Inter, JetBrains_Mono } from 'next/font/google'; import { preprocessSentryError } from '~/common/sentry-utilities'; import { useNProgress } from '~/common/useNProgress'; import { DocumentationPageWrapper } from '~/components/DocumentationPageWrapper'; -import { AnalyticsProvider } from '~/providers/Analytics'; +import { useAnalyticsPageTracking } from '~/providers/Analytics'; import { CodeBlockSettingsProvider } from '~/providers/CodeBlockSettingsProvider'; import { TutorialChapterCompletionProvider } from '~/providers/TutorialChapterCompletionProvider'; import { markdownComponents } from '~/ui/components/Markdown'; @@ -60,6 +61,7 @@ export { reportWebVitals } from '~/providers/Analytics'; export default function App({ Component, pageProps }: AppProps) { useNProgress(); + useAnalyticsPageTracking(); return ( <> {/* eslint-disable-next-line react/no-unknown-property */} @@ -81,8 +83,8 @@ export default function App({ Component, pageProps }: AppProps) { } `} - - + + @@ -94,8 +96,8 @@ export default function App({ Component, pageProps }: AppProps) { - - + + ); diff --git a/docs/providers/Analytics.tsx b/docs/providers/Analytics.tsx index 67d0c842c0cd3c..b1df36e0ec4651 100644 --- a/docs/providers/Analytics.tsx +++ b/docs/providers/Analytics.tsx @@ -1,18 +1,22 @@ +import { + isAnalyticsConsented, + enqueueAnalyticsEvent, + setAnalyticsReplayFn, + getAnalyticsConsentStatus, +} from '@expo/styleguide-cookie-consent'; +import type { QueuedEvent } from '@expo/styleguide-cookie-consent'; import { NextWebVitalsMetric } from 'next/app'; import { useRouter } from 'next/compat/router'; -import Script from 'next/script'; -import React, { PropsWithChildren, useEffect } from 'react'; +import { useEffect } from 'react'; /** The global analytics measurement ID */ const MEASUREMENT_ID = 'G-YKNPYCMLWY'; -type AnalyticsProps = PropsWithChildren; - /** - * @see https://nextjs.org/docs/messages/next-script-for-ga - * @see https://nextjs.org/docs/basic-features/script#lazyonload + * Hook that subscribes to Next.js router events and reports page views. + * Call this from the App component in _app.tsx. */ -export function AnalyticsProvider(props: AnalyticsProps) { +export function useAnalyticsPageTracking() { const router = useRouter(); useEffect(function didMount() { @@ -21,67 +25,129 @@ export function AnalyticsProvider(props: AnalyticsProps) { router?.events.off('routeChangeComplete', reportPageView); }; }, []); - - return ( - <> - - {props.children} - - ); } export function reportPageView(url: string) { - window?.gtag?.('config', MEASUREMENT_ID, { - page_path: url, - transport_type: 'beacon', - anonymize_ip: true, - }); + if (isAnalyticsConsented()) { + window?.gtag?.('config', MEASUREMENT_ID, { + page_path: url, + transport_type: 'beacon', + anonymize_ip: true, + }); + return; + } + + if (getAnalyticsConsentStatus() === 'pending') { + enqueueAnalyticsEvent({ + type: 'track', + args: ['pageview', url], + timestamp: Date.now(), + }); + } } export function reportWebVitals({ id, name, label, value }: NextWebVitalsMetric) { - window?.gtag?.('event', name, { + const payload = { event_category: label === 'web-vital' ? 'Web Vitals' : 'Next.js custom metric', - // Google Analytics metrics must be integers, so the value is rounded. - // For CLS the value is first multiplied by 1000 for greater precision - // (note: increase the multiplier for greater precision if needed). value: Math.round(name === 'CLS' ? value * 1000 : value), - // The `id` value will be unique to the current page load. When sending - // multiple values from the same page (e.g. for CLS), Google Analytics can - // compute a total by grouping on this ID (note: requires `eventLabel` to - // be a dimension in your report). event_label: id, - // Use a non-interaction event to avoid affecting bounce rate. non_interaction: true, anonymize_ip: true, - }); + }; + + if (isAnalyticsConsented()) { + window?.gtag?.('event', name, payload); + return; + } + + if (getAnalyticsConsentStatus() === 'pending') { + enqueueAnalyticsEvent({ + type: 'track', + args: ['webvitals', { name, ...payload }], + timestamp: Date.now(), + }); + } } export function reportPageVote({ status }: { status: boolean }) { - window?.gtag?.('event', status ? 'page_vote_up' : 'page_vote_down', { + const eventName = status ? 'page_vote_up' : 'page_vote_down'; + const payload = { event_category: 'Page vote', - value: window?.location.pathname, - // Use a non-interaction event to avoid affecting bounce rate. + value: typeof window !== 'undefined' ? window.location.pathname : '', non_interaction: true, anonymize_ip: true, - }); + }; + + if (isAnalyticsConsented()) { + window?.gtag?.('event', eventName, payload); + return; + } + + if (getAnalyticsConsentStatus() === 'pending') { + enqueueAnalyticsEvent({ + type: 'track', + args: ['pagevote', { status, eventName, ...payload }], + timestamp: Date.now(), + }); + } } export function reportEasTutorialCompleted() { - window?.gtag?.('event', 'eas_tutorial', { + const payload = { event_category: 'EAS Tutorial Completed', event_label: 'All chapters in EAS Tutorial completed', - // Use a non-interaction event to avoid affecting bounce rate. non_interaction: true, anonymize_ip: true, - }); + }; + + if (isAnalyticsConsented()) { + window?.gtag?.('event', 'eas_tutorial', payload); + return; + } + + if (getAnalyticsConsentStatus() === 'pending') { + enqueueAnalyticsEvent({ + type: 'track', + args: ['eas_tutorial', payload], + timestamp: Date.now(), + }); + } } + +// Register the replay function so queued events are dispatched when consent is granted. +setAnalyticsReplayFn((events: QueuedEvent[]) => { + for (const event of events) { + if (event.type !== 'track') { + continue; + } + + const [eventType, data] = event.args as [string, unknown]; + + switch (eventType) { + case 'pageview': { + const url = data as string; + window?.gtag?.('config', MEASUREMENT_ID, { + page_path: url, + transport_type: 'beacon', + anonymize_ip: true, + }); + break; + } + case 'webvitals': { + const { name, ...payload } = data as Record; + window?.gtag?.('event', name as string, payload); + break; + } + case 'pagevote': { + const { eventName, ...payload } = data as Record; + window?.gtag?.('event', eventName as string, payload); + break; + } + case 'eas_tutorial': { + const payload = data as Record; + window?.gtag?.('event', 'eas_tutorial', payload); + break; + } + } + } +}); diff --git a/docs/tailwind.config.cjs b/docs/tailwind.config.cjs index 82ede4f6408cac..d00f4086e70078 100644 --- a/docs/tailwind.config.cjs +++ b/docs/tailwind.config.cjs @@ -18,6 +18,7 @@ module.exports = { './scenes/**/*.{js,ts,jsx,tsx}', './node_modules/@expo/styleguide/dist/**/*.{js,ts,jsx,tsx}', './node_modules/@expo/styleguide-search-ui/dist/**/*.{js,ts,jsx,tsx}', + './node_modules/@expo/styleguide-cookie-consent/dist/**/*.{js,ts,jsx,tsx}', ], ...getExpoTheme({ backgroundColor: { diff --git a/docs/ui/components/Footer/Footer.tsx b/docs/ui/components/Footer/Footer.tsx index e71ec7132df432..b221fc4bdb59c2 100644 --- a/docs/ui/components/Footer/Footer.tsx +++ b/docs/ui/components/Footer/Footer.tsx @@ -1,4 +1,5 @@ import { LinkBase, mergeClasses } from '@expo/styleguide'; +import { PrivacyChoicesButton } from '@expo/styleguide-cookie-consent'; import { ArrowLeftIcon } from '@expo/styleguide-icons/outline/ArrowLeftIcon'; import { ArrowRightIcon } from '@expo/styleguide-icons/outline/ArrowRightIcon'; import { useRouter } from 'next/compat/router'; @@ -131,6 +132,7 @@ export const Footer = ({ + ); }; diff --git a/docs/ui/components/Footer/NewsletterSignUp.tsx b/docs/ui/components/Footer/NewsletterSignUp.tsx index 080b2fc4903106..6eb4880d2d839a 100644 --- a/docs/ui/components/Footer/NewsletterSignUp.tsx +++ b/docs/ui/components/Footer/NewsletterSignUp.tsx @@ -1,4 +1,5 @@ import { Button, mergeClasses } from '@expo/styleguide'; +import { isMarketingConsented } from '@expo/styleguide-cookie-consent'; import { Mail01Icon } from '@expo/styleguide-icons/outline/Mail01Icon'; import { useState } from 'react'; @@ -9,6 +10,9 @@ const PORTAL_ID = '22007177'; const FORM_GUID = '6a213eb9-5e86-4a8e-8607-33f9ac1e07d6'; function getHutk() { + if (!isMarketingConsented()) { + return ''; + } return ( document.cookie .split('; ') diff --git a/docs/ui/components/Tabs/Tabs.tsx b/docs/ui/components/Tabs/Tabs.tsx index adb02127abfb78..f3151017917da0 100644 --- a/docs/ui/components/Tabs/Tabs.tsx +++ b/docs/ui/components/Tabs/Tabs.tsx @@ -64,7 +64,7 @@ const InnerTabs = ({ setIndex, }: Props & { index: number; setIndex: (index: number) => void }) => { const tabPanels = useMemo(() => collectTabPanels(children), [children]); - const tabTitles = tabs && tabs.length === tabPanels.length ? tabs : generateTabLabels(tabPanels); + const tabTitles = tabs?.length === tabPanels.length ? tabs : generateTabLabels(tabPanels); const layoutId = useMemo( () => tabTitles.reduce((acc, tab) => acc + tab, `${Math.random().toString(36).slice(5)}-`), diff --git a/docs/yarn.lock b/docs/yarn.lock index 5ba5aaa77e82c0..67afef5025fc1a 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -19,16 +19,6 @@ __metadata: languageName: node linkType: hard -"@ampproject/remapping@npm:^2.2.0": - version: 2.3.0 - resolution: "@ampproject/remapping@npm:2.3.0" - dependencies: - "@jridgewell/gen-mapping": "npm:^0.3.5" - "@jridgewell/trace-mapping": "npm:^0.3.24" - checksum: 10c0/81d63cca5443e0f0c72ae18b544cc28c7c0ec2cea46e7cb888bb0e0f411a1191d0d6b7af798d54e30777d8d1488b2ec0732aac2be342d3d7d3ffd271c6f489ed - languageName: node - linkType: hard - "@apidevtools/json-schema-ref-parser@npm:^11.9.3": version: 11.9.3 resolution: "@apidevtools/json-schema-ref-parser@npm:11.9.3" @@ -58,18 +48,7 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.21.4, @babel/code-frame@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/code-frame@npm:7.27.1" - dependencies: - "@babel/helper-validator-identifier": "npm:^7.27.1" - js-tokens: "npm:^4.0.0" - picocolors: "npm:^1.1.1" - checksum: 10c0/5dd9a18baa5fce4741ba729acc3a3272c49c25cb8736c4b18e113099520e7ef7b545a4096a26d600e4416157e63e87d66db46aa3fbf0a5f2286da2705c12da00 - languageName: node - linkType: hard - -"@babel/code-frame@npm:^7.28.6": +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.21.4, @babel/code-frame@npm:^7.28.6": version: 7.28.6 resolution: "@babel/code-frame@npm:7.28.6" dependencies: @@ -80,13 +59,6 @@ __metadata: languageName: node linkType: hard -"@babel/compat-data@npm:^7.27.2": - version: 7.28.0 - resolution: "@babel/compat-data@npm:7.28.0" - checksum: 10c0/c4e527302bcd61052423f757355a71c3bc62362bac13f7f130de16e439716f66091ff5bdecda418e8fa0271d4c725f860f0ee23ab7bf6e769f7a8bb16dfcb531 - languageName: node - linkType: hard - "@babel/compat-data@npm:^7.28.6": version: 7.28.6 resolution: "@babel/compat-data@npm:7.28.6" @@ -94,30 +66,7 @@ __metadata: languageName: node linkType: hard -"@babel/core@npm:^7.11.6, @babel/core@npm:^7.12.3, @babel/core@npm:^7.18.5, @babel/core@npm:^7.23.9": - version: 7.28.0 - resolution: "@babel/core@npm:7.28.0" - dependencies: - "@ampproject/remapping": "npm:^2.2.0" - "@babel/code-frame": "npm:^7.27.1" - "@babel/generator": "npm:^7.28.0" - "@babel/helper-compilation-targets": "npm:^7.27.2" - "@babel/helper-module-transforms": "npm:^7.27.3" - "@babel/helpers": "npm:^7.27.6" - "@babel/parser": "npm:^7.28.0" - "@babel/template": "npm:^7.27.2" - "@babel/traverse": "npm:^7.28.0" - "@babel/types": "npm:^7.28.0" - convert-source-map: "npm:^2.0.0" - debug: "npm:^4.1.0" - gensync: "npm:^1.0.0-beta.2" - json5: "npm:^2.2.3" - semver: "npm:^6.3.1" - checksum: 10c0/423302e7c721e73b1c096217880272e02020dfb697a55ccca60ad01bba90037015f84d0c20c6ce297cf33a19bb704bc5c2b3d3095f5284dfa592bd1de0b9e8c3 - languageName: node - linkType: hard - -"@babel/core@npm:^7.24.4": +"@babel/core@npm:^7.11.6, @babel/core@npm:^7.12.3, @babel/core@npm:^7.18.5, @babel/core@npm:^7.23.9, @babel/core@npm:^7.24.4": version: 7.28.6 resolution: "@babel/core@npm:7.28.6" dependencies: @@ -140,20 +89,7 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:^7.28.0, @babel/generator@npm:^7.7.2": - version: 7.28.0 - resolution: "@babel/generator@npm:7.28.0" - dependencies: - "@babel/parser": "npm:^7.28.0" - "@babel/types": "npm:^7.28.0" - "@jridgewell/gen-mapping": "npm:^0.3.12" - "@jridgewell/trace-mapping": "npm:^0.3.28" - jsesc: "npm:^3.0.2" - checksum: 10c0/1b3d122268ea3df50fde707ad864d9a55c72621357d5cebb972db3dd76859c45810c56e16ad23123f18f80cc2692f5a015d2858361300f0f224a05dc43d36a92 - languageName: node - linkType: hard - -"@babel/generator@npm:^7.28.6": +"@babel/generator@npm:^7.28.6, @babel/generator@npm:^7.7.2": version: 7.28.6 resolution: "@babel/generator@npm:7.28.6" dependencies: @@ -166,19 +102,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-compilation-targets@npm:^7.27.2": - version: 7.27.2 - resolution: "@babel/helper-compilation-targets@npm:7.27.2" - dependencies: - "@babel/compat-data": "npm:^7.27.2" - "@babel/helper-validator-option": "npm:^7.27.1" - browserslist: "npm:^4.24.0" - lru-cache: "npm:^5.1.1" - semver: "npm:^6.3.1" - checksum: 10c0/f338fa00dcfea931804a7c55d1a1c81b6f0a09787e528ec580d5c21b3ecb3913f6cb0f361368973ce953b824d910d3ac3e8a8ee15192710d3563826447193ad1 - languageName: node - linkType: hard - "@babel/helper-compilation-targets@npm:^7.28.6": version: 7.28.6 resolution: "@babel/helper-compilation-targets@npm:7.28.6" @@ -199,16 +122,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-imports@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/helper-module-imports@npm:7.27.1" - dependencies: - "@babel/traverse": "npm:^7.27.1" - "@babel/types": "npm:^7.27.1" - checksum: 10c0/e00aace096e4e29290ff8648455c2bc4ed982f0d61dbf2db1b5e750b9b98f318bf5788d75a4f974c151bd318fd549e81dbcab595f46b14b81c12eda3023f51e8 - languageName: node - linkType: hard - "@babel/helper-module-imports@npm:^7.28.6": version: 7.28.6 resolution: "@babel/helper-module-imports@npm:7.28.6" @@ -219,19 +132,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-transforms@npm:^7.27.3": - version: 7.27.3 - resolution: "@babel/helper-module-transforms@npm:7.27.3" - dependencies: - "@babel/helper-module-imports": "npm:^7.27.1" - "@babel/helper-validator-identifier": "npm:^7.27.1" - "@babel/traverse": "npm:^7.27.3" - peerDependencies: - "@babel/core": ^7.0.0 - checksum: 10c0/fccb4f512a13b4c069af51e1b56b20f54024bcf1591e31e978a30f3502567f34f90a80da6a19a6148c249216292a8074a0121f9e52602510ef0f32dbce95ca01 - languageName: node - linkType: hard - "@babel/helper-module-transforms@npm:^7.28.6": version: 7.28.6 resolution: "@babel/helper-module-transforms@npm:7.28.6" @@ -259,13 +159,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-validator-identifier@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/helper-validator-identifier@npm:7.27.1" - checksum: 10c0/c558f11c4871d526498e49d07a84752d1800bf72ac0d3dad100309a2eaba24efbf56ea59af5137ff15e3a00280ebe588560534b0e894a4750f8b1411d8f78b84 - languageName: node - linkType: hard - "@babel/helper-validator-identifier@npm:^7.28.5": version: 7.28.5 resolution: "@babel/helper-validator-identifier@npm:7.28.5" @@ -280,16 +173,6 @@ __metadata: languageName: node linkType: hard -"@babel/helpers@npm:^7.27.6": - version: 7.28.2 - resolution: "@babel/helpers@npm:7.28.2" - dependencies: - "@babel/template": "npm:^7.27.2" - "@babel/types": "npm:^7.28.2" - checksum: 10c0/f3e7b21517e2699c4ca193663ecfb1bf1b2ae2762d8ba4a9f1786feaca0d6984537fc60bf2206e92c43640a6dada6b438f523cc1ad78610d0151aeb061b37f63 - languageName: node - linkType: hard - "@babel/helpers@npm:^7.28.6": version: 7.28.6 resolution: "@babel/helpers@npm:7.28.6" @@ -300,18 +183,7 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.23.9, @babel/parser@npm:^7.27.2, @babel/parser@npm:^7.28.0": - version: 7.28.0 - resolution: "@babel/parser@npm:7.28.0" - dependencies: - "@babel/types": "npm:^7.28.0" - bin: - parser: ./bin/babel-parser.js - checksum: 10c0/c2ef81d598990fa949d1d388429df327420357cb5200271d0d0a2784f1e6d54afc8301eb8bdf96d8f6c77781e402da93c7dc07980fcc136ac5b9d5f1fce701b5 - languageName: node - linkType: hard - -"@babel/parser@npm:^7.24.4, @babel/parser@npm:^7.28.6": +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.23.9, @babel/parser@npm:^7.24.4, @babel/parser@npm:^7.28.6": version: 7.28.6 resolution: "@babel/parser@npm:7.28.6" dependencies: @@ -516,18 +388,7 @@ __metadata: languageName: node linkType: hard -"@babel/template@npm:^7.27.2, @babel/template@npm:^7.3.3": - version: 7.27.2 - resolution: "@babel/template@npm:7.27.2" - dependencies: - "@babel/code-frame": "npm:^7.27.1" - "@babel/parser": "npm:^7.27.2" - "@babel/types": "npm:^7.27.1" - checksum: 10c0/ed9e9022651e463cc5f2cc21942f0e74544f1754d231add6348ff1b472985a3b3502041c0be62dc99ed2d12cfae0c51394bf827452b98a2f8769c03b87aadc81 - languageName: node - linkType: hard - -"@babel/template@npm:^7.28.6": +"@babel/template@npm:^7.28.6, @babel/template@npm:^7.3.3": version: 7.28.6 resolution: "@babel/template@npm:7.28.6" dependencies: @@ -538,21 +399,6 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.27.1, @babel/traverse@npm:^7.27.3, @babel/traverse@npm:^7.28.0": - version: 7.28.0 - resolution: "@babel/traverse@npm:7.28.0" - dependencies: - "@babel/code-frame": "npm:^7.27.1" - "@babel/generator": "npm:^7.28.0" - "@babel/helper-globals": "npm:^7.28.0" - "@babel/parser": "npm:^7.28.0" - "@babel/template": "npm:^7.27.2" - "@babel/types": "npm:^7.28.0" - debug: "npm:^4.3.1" - checksum: 10c0/32794402457827ac558173bcebdcc0e3a18fa339b7c41ca35621f9f645f044534d91bb923ff385f5f960f2e495f56ce18d6c7b0d064d2f0ccb55b285fa6bc7b9 - languageName: node - linkType: hard - "@babel/traverse@npm:^7.28.6": version: 7.28.6 resolution: "@babel/traverse@npm:7.28.6" @@ -568,17 +414,7 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.27.1, @babel/types@npm:^7.28.0, @babel/types@npm:^7.28.2, @babel/types@npm:^7.3.3": - version: 7.28.2 - resolution: "@babel/types@npm:7.28.2" - dependencies: - "@babel/helper-string-parser": "npm:^7.27.1" - "@babel/helper-validator-identifier": "npm:^7.27.1" - checksum: 10c0/24b11c9368e7e2c291fe3c1bcd1ed66f6593a3975f479cbb9dd7b8c8d8eab8a962b0d2fca616c043396ce82500ac7d23d594fbbbd013828182c01596370a0b10 - languageName: node - linkType: hard - -"@babel/types@npm:^7.28.6": +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.28.6, @babel/types@npm:^7.3.3": version: 7.28.6 resolution: "@babel/types@npm:7.28.6" dependencies: @@ -850,18 +686,7 @@ __metadata: languageName: node linkType: hard -"@eslint-community/eslint-utils@npm:^4.1.2, @eslint-community/eslint-utils@npm:^4.4.0, @eslint-community/eslint-utils@npm:^4.5.0, @eslint-community/eslint-utils@npm:^4.8.0, @eslint-community/eslint-utils@npm:^4.9.0": - version: 4.9.0 - resolution: "@eslint-community/eslint-utils@npm:4.9.0" - dependencies: - eslint-visitor-keys: "npm:^3.4.3" - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - checksum: 10c0/8881e22d519326e7dba85ea915ac7a143367c805e6ba1374c987aa2fbdd09195cc51183d2da72c0e2ff388f84363e1b220fd0d19bef10c272c63455162176817 - languageName: node - linkType: hard - -"@eslint-community/eslint-utils@npm:^4.9.1": +"@eslint-community/eslint-utils@npm:^4.1.2, @eslint-community/eslint-utils@npm:^4.5.0, @eslint-community/eslint-utils@npm:^4.8.0, @eslint-community/eslint-utils@npm:^4.9.0, @eslint-community/eslint-utils@npm:^4.9.1": version: 4.9.1 resolution: "@eslint-community/eslint-utils@npm:4.9.1" dependencies: @@ -872,14 +697,7 @@ __metadata: languageName: node linkType: hard -"@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.11.0, @eslint-community/regexpp@npm:^4.12.1": - version: 4.12.1 - resolution: "@eslint-community/regexpp@npm:4.12.1" - checksum: 10c0/a03d98c246bcb9109aec2c08e4d10c8d010256538dcb3f56610191607214523d4fb1b00aa81df830b6dffb74c5fa0be03642513a289c567949d3e550ca11cdf6 - languageName: node - linkType: hard - -"@eslint-community/regexpp@npm:^4.12.2": +"@eslint-community/regexpp@npm:^4.11.0, @eslint-community/regexpp@npm:^4.12.1, @eslint-community/regexpp@npm:^4.12.2": version: 4.12.2 resolution: "@eslint-community/regexpp@npm:4.12.2" checksum: 10c0/fddcbc66851b308478d04e302a4d771d6917a0b3740dc351513c0da9ca2eab8a1adf99f5e0aa7ab8b13fa0df005c81adeee7e63a92f3effd7d367a163b721c2d @@ -906,15 +724,6 @@ __metadata: languageName: node linkType: hard -"@eslint/core@npm:^0.16.0": - version: 0.16.0 - resolution: "@eslint/core@npm:0.16.0" - dependencies: - "@types/json-schema": "npm:^7.0.15" - checksum: 10c0/f27496a244ccfdca3e0fbc3331f9da3f603bdf1aa431af0045a3205826789a54493bc619ad6311a9090eaf7bc25798ff4e265dea1eccd2df9ce3b454f7e7da27 - languageName: node - linkType: hard - "@eslint/core@npm:^0.17.0": version: 0.17.0 resolution: "@eslint/core@npm:0.17.0" @@ -955,17 +764,7 @@ __metadata: languageName: node linkType: hard -"@eslint/plugin-kit@npm:^0.4.0": - version: 0.4.0 - resolution: "@eslint/plugin-kit@npm:0.4.0" - dependencies: - "@eslint/core": "npm:^0.16.0" - levn: "npm:^0.4.1" - checksum: 10c0/125614e902bb34c041da859794c47ac2ec4a814f5d9e7c4d37fcd34b38d8ee5cf1f97020d38d168885d9bf4046a9a7decb86b4cee8dac9eedcc6ad08ebafe204 - languageName: node - linkType: hard - -"@eslint/plugin-kit@npm:^0.4.1": +"@eslint/plugin-kit@npm:^0.4.0, @eslint/plugin-kit@npm:^0.4.1": version: 0.4.1 resolution: "@eslint/plugin-kit@npm:0.4.1" dependencies: @@ -995,6 +794,21 @@ __metadata: languageName: node linkType: hard +"@expo/styleguide-cookie-consent@npm:^0.1.11": + version: 0.1.11 + resolution: "@expo/styleguide-cookie-consent@npm:0.1.11" + dependencies: + "@radix-ui/react-accordion": "npm:^1.2.4" + "@radix-ui/react-slot": "npm:^1.2.0" + "@radix-ui/react-switch": "npm:^1.1.4" + clsx: "npm:^2.1.1" + zustand: "npm:^5.0.3" + peerDependencies: + react: ">= 19" + checksum: 10c0/a5eea96abb9716b42eb9aa498898c472e771e81d7c10a7e47bb980c6b609b8a5728505eafb5e2a80323f0184b5883dbfebfc50c1e8d776fdb7615b1e98fa2e29 + languageName: node + linkType: hard + "@expo/styleguide-icons@npm:^2.3.4": version: 2.3.4 resolution: "@expo/styleguide-icons@npm:2.3.4" @@ -2143,7 +1957,7 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/core@npm:2.5.0, @opentelemetry/core@npm:^2.5.0": +"@opentelemetry/core@npm:2.5.0": version: 2.5.0 resolution: "@opentelemetry/core@npm:2.5.0" dependencies: @@ -2154,14 +1968,14 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/core@npm:^2.0.0": - version: 2.1.0 - resolution: "@opentelemetry/core@npm:2.1.0" +"@opentelemetry/core@npm:2.5.1, @opentelemetry/core@npm:^2.0.0, @opentelemetry/core@npm:^2.5.0": + version: 2.5.1 + resolution: "@opentelemetry/core@npm:2.5.1" dependencies: "@opentelemetry/semantic-conventions": "npm:^1.29.0" peerDependencies: "@opentelemetry/api": ">=1.0.0 <1.10.0" - checksum: 10c0/562c44c89150ef9cc7be4fcbfccfb62f71eb95d487de79b6a2716bb960da7d181f5e2ae3354ed6bd0bba0a3903fe5b7dad14b9a4a92fa90ab1b9172f11a3743d + checksum: 10c0/cbaf36953364d1295ef2ff4587c3f99eca121c7c2dbd2553699100ccbd91017f20fb1a710ac76fad832d9762dc98ae009ce0e96ab8fb00e5b539dc401d57f217 languageName: node linkType: hard @@ -2477,46 +2291,32 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/resources@npm:2.5.0, @opentelemetry/resources@npm:^2.5.0": - version: 2.5.0 - resolution: "@opentelemetry/resources@npm:2.5.0" +"@opentelemetry/resources@npm:2.5.1, @opentelemetry/resources@npm:^2.5.0": + version: 2.5.1 + resolution: "@opentelemetry/resources@npm:2.5.1" dependencies: - "@opentelemetry/core": "npm:2.5.0" + "@opentelemetry/core": "npm:2.5.1" "@opentelemetry/semantic-conventions": "npm:^1.29.0" peerDependencies: "@opentelemetry/api": ">=1.3.0 <1.10.0" - checksum: 10c0/30073a5db368e5ed8c44ac87e6ebd4da53b5050e14e367610fa79a049eee3e5e5a82c4fbc1a9cc539d845b68983b74643c094e111baf114159e75ded1d67db08 + checksum: 10c0/c336d5066fa7457272bcffb5a9826f090e1e07c2a70c5976942cf2bb188be685842658982a0f323ddfc1d6fbc364f123b6b0e433e230b023aefd88ec60062ba4 languageName: node linkType: hard "@opentelemetry/sdk-trace-base@npm:^2.5.0": - version: 2.5.0 - resolution: "@opentelemetry/sdk-trace-base@npm:2.5.0" + version: 2.5.1 + resolution: "@opentelemetry/sdk-trace-base@npm:2.5.1" dependencies: - "@opentelemetry/core": "npm:2.5.0" - "@opentelemetry/resources": "npm:2.5.0" + "@opentelemetry/core": "npm:2.5.1" + "@opentelemetry/resources": "npm:2.5.1" "@opentelemetry/semantic-conventions": "npm:^1.29.0" peerDependencies: "@opentelemetry/api": ">=1.3.0 <1.10.0" - checksum: 10c0/5b9f90f128dbdfdda4ccd17a3fa7580cf8389d30c0b5be34d810d5cf2873954c6c662241d0a88caa217e691720c40daebb189e1baf4ba93620c153ae9ee4672a - languageName: node - linkType: hard - -"@opentelemetry/semantic-conventions@npm:^1.24.0, @opentelemetry/semantic-conventions@npm:^1.33.0, @opentelemetry/semantic-conventions@npm:^1.36.0": - version: 1.38.0 - resolution: "@opentelemetry/semantic-conventions@npm:1.38.0" - checksum: 10c0/ae93e39ac18bf47df2b11d43e9a0dc1673b9d33e5f1e7f357c92968e6329fb9a67cf8a447e9a7150948ee3f8178b38274db365b8fa775a8c54802e0c6ccdd2ca - languageName: node - linkType: hard - -"@opentelemetry/semantic-conventions@npm:^1.27.0, @opentelemetry/semantic-conventions@npm:^1.29.0, @opentelemetry/semantic-conventions@npm:^1.30.0, @opentelemetry/semantic-conventions@npm:^1.33.1, @opentelemetry/semantic-conventions@npm:^1.34.0, @opentelemetry/semantic-conventions@npm:^1.37.0": - version: 1.37.0 - resolution: "@opentelemetry/semantic-conventions@npm:1.37.0" - checksum: 10c0/ddce99f36e390603d6bbc556a50c070e41303d764a830808a4c451f02f4e6a3d989dbde8bcfac15e4e5bba13686b36c6664a323321c9259f9030eb70522a7c68 + checksum: 10c0/a1833343cc030f435339e795c20e3e3507e144fd72079325dd4ee2677eccc3602f0e47fc768278ba6b45d18ee03a6700b38db7756eaa8f084dd18d6c26a17bc8 languageName: node linkType: hard -"@opentelemetry/semantic-conventions@npm:^1.39.0": +"@opentelemetry/semantic-conventions@npm:^1.24.0, @opentelemetry/semantic-conventions@npm:^1.27.0, @opentelemetry/semantic-conventions@npm:^1.29.0, @opentelemetry/semantic-conventions@npm:^1.30.0, @opentelemetry/semantic-conventions@npm:^1.33.0, @opentelemetry/semantic-conventions@npm:^1.33.1, @opentelemetry/semantic-conventions@npm:^1.34.0, @opentelemetry/semantic-conventions@npm:^1.36.0, @opentelemetry/semantic-conventions@npm:^1.37.0, @opentelemetry/semantic-conventions@npm:^1.39.0": version: 1.39.0 resolution: "@opentelemetry/semantic-conventions@npm:1.39.0" checksum: 10c0/1a8cc16e83ccd80aeb910e78146e8cde8482ac45feb3693348eec5983d8ad254f977f2b61db76f043ab0fa6009a27df610a9cff286a217d6cd4c114216861d0f @@ -2623,6 +2423,33 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-accordion@npm:^1.2.4": + version: 1.2.12 + resolution: "@radix-ui/react-accordion@npm:1.2.12" + dependencies: + "@radix-ui/primitive": "npm:1.1.3" + "@radix-ui/react-collapsible": "npm:1.1.12" + "@radix-ui/react-collection": "npm:1.1.7" + "@radix-ui/react-compose-refs": "npm:1.1.2" + "@radix-ui/react-context": "npm:1.1.2" + "@radix-ui/react-direction": "npm:1.1.1" + "@radix-ui/react-id": "npm:1.1.1" + "@radix-ui/react-primitive": "npm:2.1.3" + "@radix-ui/react-use-controllable-state": "npm:1.2.2" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/c64a53ce766a1ef529cf6413ed7382598c94f78879b3a83ceda27cb1894ed6eb6e8ad61f6a550ca3c7fa813657045dadfc7328dbf1d736a37e1cf3c446db43de + languageName: node + linkType: hard + "@radix-ui/react-arrow@npm:1.1.7": version: 1.1.7 resolution: "@radix-ui/react-arrow@npm:1.1.7" @@ -2642,6 +2469,32 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-collapsible@npm:1.1.12": + version: 1.1.12 + resolution: "@radix-ui/react-collapsible@npm:1.1.12" + dependencies: + "@radix-ui/primitive": "npm:1.1.3" + "@radix-ui/react-compose-refs": "npm:1.1.2" + "@radix-ui/react-context": "npm:1.1.2" + "@radix-ui/react-id": "npm:1.1.1" + "@radix-ui/react-presence": "npm:1.1.5" + "@radix-ui/react-primitive": "npm:2.1.3" + "@radix-ui/react-use-controllable-state": "npm:1.2.2" + "@radix-ui/react-use-layout-effect": "npm:1.1.1" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/777cced73fbbec9cfafe6325aa5605e90f49d889af2778f4c4a6be101c07cacd69ae817d0b41cc27e3181f49392e2c06db7f32d6b084db047a51805ec70729b3 + languageName: node + linkType: hard + "@radix-ui/react-collection@npm:1.1.7": version: 1.1.7 resolution: "@radix-ui/react-collection@npm:1.1.7" @@ -3191,6 +3044,46 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-slot@npm:^1.2.0": + version: 1.2.4 + resolution: "@radix-ui/react-slot@npm:1.2.4" + dependencies: + "@radix-ui/react-compose-refs": "npm:1.1.2" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/8b719bb934f1ae5ac0e37214783085c17c2f1080217caf514c1c6cc3d9ca56c7e19d25470b26da79aa6e605ab36589edaade149b76f5fc0666f1063e2fc0a0dc + languageName: node + linkType: hard + +"@radix-ui/react-switch@npm:^1.1.4": + version: 1.2.6 + resolution: "@radix-ui/react-switch@npm:1.2.6" + dependencies: + "@radix-ui/primitive": "npm:1.1.3" + "@radix-ui/react-compose-refs": "npm:1.1.2" + "@radix-ui/react-context": "npm:1.1.2" + "@radix-ui/react-primitive": "npm:2.1.3" + "@radix-ui/react-use-controllable-state": "npm:1.2.2" + "@radix-ui/react-use-previous": "npm:1.1.1" + "@radix-ui/react-use-size": "npm:1.1.1" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/888303cbeb0e69ebba5676b225f9ea0f00f61453c6b8a6b66384b5c5c4c7fb0ccc53493c1eb14ec6d436e5b867b302aadd6af51a1f2e6c04581c583fd9be65be + languageName: node + linkType: hard + "@radix-ui/react-tooltip@npm:^1.2.8": version: 1.2.8 resolution: "@radix-ui/react-tooltip@npm:1.2.8" @@ -4503,12 +4396,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:*, @types/node@npm:^22.0.0, @types/node@npm:^22.18.11": - version: 22.18.11 - resolution: "@types/node@npm:22.18.11" +"@types/node@npm:*": + version: 25.2.3 + resolution: "@types/node@npm:25.2.3" dependencies: - undici-types: "npm:~6.21.0" - checksum: 10c0/3802f598608638e13ca350fbe2db0db5dde9a0b6704295fa1b6cec6defe24f9baf6a891eee6eaecd016bcd5ea18edecdaf71679d87079fe468913701adb61387 + undici-types: "npm:~7.16.0" + checksum: 10c0/925833029ce0bb4a72c36f90b93287184d3511aeb0fa60a994ae94b5430c22f9be6693d67d210df79267cb54c6f6978caaefb149d99ab5f83af5827ba7cb9822 languageName: node linkType: hard @@ -4519,6 +4412,15 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:^22.0.0, @types/node@npm:^22.18.11": + version: 22.18.11 + resolution: "@types/node@npm:22.18.11" + dependencies: + undici-types: "npm:~6.21.0" + checksum: 10c0/3802f598608638e13ca350fbe2db0db5dde9a0b6704295fa1b6cec6defe24f9baf6a891eee6eaecd016bcd5ea18edecdaf71679d87079fe468913701adb61387 + languageName: node + linkType: hard + "@types/nprogress@npm:^0.2.3": version: 0.2.3 resolution: "@types/nprogress@npm:0.2.3" @@ -4535,18 +4437,7 @@ __metadata: languageName: node linkType: hard -"@types/pg@npm:*": - version: 8.15.5 - resolution: "@types/pg@npm:8.15.5" - dependencies: - "@types/node": "npm:*" - pg-protocol: "npm:*" - pg-types: "npm:^2.2.0" - checksum: 10c0/19a3cc1811918753f8c827733648c3a85c7b0355bf207c44eb1a3b79b2e6a0d85cb5457ec550d860fc9be7e88c7587a3600958ec8c61fa1ad573061c63af93f0 - languageName: node - linkType: hard - -"@types/pg@npm:8.15.6": +"@types/pg@npm:*, @types/pg@npm:8.15.6": version: 8.15.6 resolution: "@types/pg@npm:8.15.6" dependencies: @@ -4672,7 +4563,7 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:8.54.0": +"@typescript-eslint/eslint-plugin@npm:8.54.0, @typescript-eslint/eslint-plugin@npm:^8.29.1": version: 8.54.0 resolution: "@typescript-eslint/eslint-plugin@npm:8.54.0" dependencies: @@ -4692,28 +4583,7 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:^8.29.1": - version: 8.29.1 - resolution: "@typescript-eslint/eslint-plugin@npm:8.29.1" - dependencies: - "@eslint-community/regexpp": "npm:^4.10.0" - "@typescript-eslint/scope-manager": "npm:8.29.1" - "@typescript-eslint/type-utils": "npm:8.29.1" - "@typescript-eslint/utils": "npm:8.29.1" - "@typescript-eslint/visitor-keys": "npm:8.29.1" - graphemer: "npm:^1.4.0" - ignore: "npm:^5.3.1" - natural-compare: "npm:^1.4.0" - ts-api-utils: "npm:^2.0.1" - peerDependencies: - "@typescript-eslint/parser": ^8.0.0 || ^8.0.0-alpha.0 - eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <5.9.0" - checksum: 10c0/a3ed7556edcac374cab622862f2f9adedc91ca305d6937db6869a0253d675858c296cb5413980e8404fc39737117faaf35b00c6804664b3c542bdc417502532f - languageName: node - linkType: hard - -"@typescript-eslint/parser@npm:8.54.0": +"@typescript-eslint/parser@npm:8.54.0, @typescript-eslint/parser@npm:^8.29.1": version: 8.54.0 resolution: "@typescript-eslint/parser@npm:8.54.0" dependencies: @@ -4729,22 +4599,6 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/parser@npm:^8.29.1": - version: 8.29.1 - resolution: "@typescript-eslint/parser@npm:8.29.1" - dependencies: - "@typescript-eslint/scope-manager": "npm:8.29.1" - "@typescript-eslint/types": "npm:8.29.1" - "@typescript-eslint/typescript-estree": "npm:8.29.1" - "@typescript-eslint/visitor-keys": "npm:8.29.1" - debug: "npm:^4.3.4" - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <5.9.0" - checksum: 10c0/af3570ff58c42c2014e5c117bebf91120737fb139d94415ca2711844990e95252c3006ccc699871fe3f592cc1a3f4ebfdc9dd5f6cb29b6b128c2524fcf311b75 - languageName: node - linkType: hard - "@typescript-eslint/project-service@npm:8.54.0": version: 8.54.0 resolution: "@typescript-eslint/project-service@npm:8.54.0" @@ -4758,17 +4612,7 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:8.29.1, @typescript-eslint/scope-manager@npm:^8.15.0": - version: 8.29.1 - resolution: "@typescript-eslint/scope-manager@npm:8.29.1" - dependencies: - "@typescript-eslint/types": "npm:8.29.1" - "@typescript-eslint/visitor-keys": "npm:8.29.1" - checksum: 10c0/8b87a04f01ebc13075e352509bca8f31c757c3220857fa473ac155f6bdf7f30fe82765d0c3d8e790f7fad394a32765bd9f716b97c08e17581d358c76086d51af - languageName: node - linkType: hard - -"@typescript-eslint/scope-manager@npm:8.54.0": +"@typescript-eslint/scope-manager@npm:8.54.0, @typescript-eslint/scope-manager@npm:^8.15.0": version: 8.54.0 resolution: "@typescript-eslint/scope-manager@npm:8.54.0" dependencies: @@ -4787,21 +4631,6 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:8.29.1": - version: 8.29.1 - resolution: "@typescript-eslint/type-utils@npm:8.29.1" - dependencies: - "@typescript-eslint/typescript-estree": "npm:8.29.1" - "@typescript-eslint/utils": "npm:8.29.1" - debug: "npm:^4.3.4" - ts-api-utils: "npm:^2.0.1" - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <5.9.0" - checksum: 10c0/72cc01dbac866b0a7c7b1f637ad03ffd22f6d3617f70f06f485cf3096fddfc821fdc56de1a072cc6af70250c63698a3e5a910f67fe46eea941955b6e0da1b2bd - languageName: node - linkType: hard - "@typescript-eslint/type-utils@npm:8.54.0": version: 8.54.0 resolution: "@typescript-eslint/type-utils@npm:8.54.0" @@ -4818,13 +4647,6 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/types@npm:8.29.1": - version: 8.29.1 - resolution: "@typescript-eslint/types@npm:8.29.1" - checksum: 10c0/bbcb9e4f38df4485092b51ac6bb62d65f321d914ab58dc0ff1eaa7787dc0b4a39e237c2617b9f2c2bcb91a343f30de523e3544f69affa1ee4287a3ef2fc10ce7 - languageName: node - linkType: hard - "@typescript-eslint/types@npm:8.54.0, @typescript-eslint/types@npm:^8.54.0": version: 8.54.0 resolution: "@typescript-eslint/types@npm:8.54.0" @@ -4832,24 +4654,6 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:8.29.1": - version: 8.29.1 - resolution: "@typescript-eslint/typescript-estree@npm:8.29.1" - dependencies: - "@typescript-eslint/types": "npm:8.29.1" - "@typescript-eslint/visitor-keys": "npm:8.29.1" - debug: "npm:^4.3.4" - fast-glob: "npm:^3.3.2" - is-glob: "npm:^4.0.3" - minimatch: "npm:^9.0.4" - semver: "npm:^7.6.0" - ts-api-utils: "npm:^2.0.1" - peerDependencies: - typescript: ">=4.8.4 <5.9.0" - checksum: 10c0/33c46c667d9262e5625d5d0064338711b342e62c5675ded6811a2cb13ee5de2f71b90e9d0be5cb338b11b1a329c376a6bbf6c3d24fa8fb457b2eefc9f3298513 - languageName: node - linkType: hard - "@typescript-eslint/typescript-estree@npm:8.54.0": version: 8.54.0 resolution: "@typescript-eslint/typescript-estree@npm:8.54.0" @@ -4869,22 +4673,7 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/utils@npm:8.29.1, @typescript-eslint/utils@npm:^8.15.0": - version: 8.29.1 - resolution: "@typescript-eslint/utils@npm:8.29.1" - dependencies: - "@eslint-community/eslint-utils": "npm:^4.4.0" - "@typescript-eslint/scope-manager": "npm:8.29.1" - "@typescript-eslint/types": "npm:8.29.1" - "@typescript-eslint/typescript-estree": "npm:8.29.1" - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <5.9.0" - checksum: 10c0/1b2704b769b0c9353cf26a320ecf9775ba51c94c7c30e2af80ca31f4cb230f319762ab06535fcb26b6963144bbeaa53233b34965907c506283861b013f5b95fc - languageName: node - linkType: hard - -"@typescript-eslint/utils@npm:8.54.0": +"@typescript-eslint/utils@npm:8.54.0, @typescript-eslint/utils@npm:^8.15.0": version: 8.54.0 resolution: "@typescript-eslint/utils@npm:8.54.0" dependencies: @@ -4899,16 +4688,6 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:8.29.1": - version: 8.29.1 - resolution: "@typescript-eslint/visitor-keys@npm:8.29.1" - dependencies: - "@typescript-eslint/types": "npm:8.29.1" - eslint-visitor-keys: "npm:^4.2.0" - checksum: 10c0/0c12e83c84a754161c89e594a96454799669979c7021a8936515ec574a1fa1d6e3119e0eacf502e07a0fa7254974558ea7a48901c8bfed3c46579a61b655e4f5 - languageName: node - linkType: hard - "@typescript-eslint/visitor-keys@npm:8.54.0": version: 8.54.0 resolution: "@typescript-eslint/visitor-keys@npm:8.54.0" @@ -5032,7 +4811,7 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.0.0, acorn@npm:^8.1.0, acorn@npm:^8.11.0, acorn@npm:^8.14.0, acorn@npm:^8.15.0, acorn@npm:^8.8.1": +"acorn@npm:^8.0.0, acorn@npm:^8.1.0, acorn@npm:^8.11.0, acorn@npm:^8.15.0, acorn@npm:^8.8.1": version: 8.15.0 resolution: "acorn@npm:8.15.0" bin: @@ -5190,21 +4969,7 @@ __metadata: languageName: node linkType: hard -"array-includes@npm:^3.1.6, array-includes@npm:^3.1.8": - version: 3.1.8 - resolution: "array-includes@npm:3.1.8" - dependencies: - call-bind: "npm:^1.0.7" - define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.23.2" - es-object-atoms: "npm:^1.0.0" - get-intrinsic: "npm:^1.2.4" - is-string: "npm:^1.0.7" - checksum: 10c0/5b1004d203e85873b96ddc493f090c9672fd6c80d7a60b798da8a14bff8a670ff95db5aafc9abc14a211943f05220dacf8ea17638ae0af1a6a47b8c0b48ce370 - languageName: node - linkType: hard - -"array-includes@npm:^3.1.9": +"array-includes@npm:^3.1.6, array-includes@npm:^3.1.8, array-includes@npm:^3.1.9": version: 3.1.9 resolution: "array-includes@npm:3.1.9" dependencies: @@ -5234,20 +4999,6 @@ __metadata: languageName: node linkType: hard -"array.prototype.findlastindex@npm:^1.2.5": - version: 1.2.5 - resolution: "array.prototype.findlastindex@npm:1.2.5" - dependencies: - call-bind: "npm:^1.0.7" - define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.23.2" - es-errors: "npm:^1.3.0" - es-object-atoms: "npm:^1.0.0" - es-shim-unscopables: "npm:^1.0.2" - checksum: 10c0/962189487728b034f3134802b421b5f39e42ee2356d13b42d2ddb0e52057ffdcc170b9524867f4f0611a6f638f4c19b31e14606e8bcbda67799e26685b195aa3 - languageName: node - linkType: hard - "array.prototype.findlastindex@npm:^1.2.6": version: 1.2.6 resolution: "array.prototype.findlastindex@npm:1.2.6" @@ -5263,7 +5014,7 @@ __metadata: languageName: node linkType: hard -"array.prototype.flat@npm:^1.3.1, array.prototype.flat@npm:^1.3.2, array.prototype.flat@npm:^1.3.3": +"array.prototype.flat@npm:^1.3.1, array.prototype.flat@npm:^1.3.3": version: 1.3.3 resolution: "array.prototype.flat@npm:1.3.3" dependencies: @@ -5611,21 +5362,7 @@ __metadata: languageName: node linkType: hard -"browserslist@npm:^4.24.0, browserslist@npm:^4.24.4": - version: 4.24.4 - resolution: "browserslist@npm:4.24.4" - dependencies: - caniuse-lite: "npm:^1.0.30001688" - electron-to-chromium: "npm:^1.5.73" - node-releases: "npm:^2.0.19" - update-browserslist-db: "npm:^1.1.1" - bin: - browserslist: cli.js - checksum: 10c0/db7ebc1733cf471e0b490b4f47e3e2ea2947ce417192c9246644e92c667dd56a71406cc58f62ca7587caf828364892e9952904a02b7aead752bc65b62a37cfe9 - languageName: node - linkType: hard - -"browserslist@npm:^4.28.0": +"browserslist@npm:^4.24.0, browserslist@npm:^4.24.4, browserslist@npm:^4.28.0": version: 4.28.0 resolution: "browserslist@npm:4.28.0" dependencies: @@ -5757,14 +5494,7 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.30001579, caniuse-lite@npm:^1.0.30001688, caniuse-lite@npm:^1.0.30001702": - version: 1.0.30001709 - resolution: "caniuse-lite@npm:1.0.30001709" - checksum: 10c0/0acf91f59f52661fc47042e4eee1b527deb54044ae4c79ae7464d0789b79146ad587153a76d78b09157261b9fad89235eb161cd8ea7a58d36fc7f25a2e937df5 - languageName: node - linkType: hard - -"caniuse-lite@npm:^1.0.30001754": +"caniuse-lite@npm:^1.0.30001579, caniuse-lite@npm:^1.0.30001702, caniuse-lite@npm:^1.0.30001754": version: 1.0.30001755 resolution: "caniuse-lite@npm:1.0.30001755" checksum: 10c0/7b8e32a4ec307b50f557d30176651cf69f20a0ea4de6f5f34149ea65a1f0cfcc0677b403484aea3661c7469ab11f2df6528027b9ec2d0265635ede9d5b517380 @@ -5816,9 +5546,9 @@ __metadata: linkType: hard "chalk@npm:^5.0.0": - version: 5.4.1 - resolution: "chalk@npm:5.4.1" - checksum: 10c0/b23e88132c702f4855ca6d25cb5538b1114343e41472d5263ee8a37cccfccd9c4216d111e1097c6a27830407a1dc81fecdf2a56f2c63033d4dbbd88c10b0dcef + version: 5.6.2 + resolution: "chalk@npm:5.6.2" + checksum: 10c0/99a4b0f0e7991796b1e7e3f52dceb9137cae2a9dfc8fc0784a550dc4c558e15ab32ed70b14b21b52beb2679b4892b41a0aa44249bcb996f01e125d58477c6976 languageName: node linkType: hard @@ -5937,21 +5667,14 @@ __metadata: languageName: node linkType: hard -"ci-info@npm:^4.0.0": - version: 4.2.0 - resolution: "ci-info@npm:4.2.0" - checksum: 10c0/37a2f4b6a213a5cf835890eb0241f0d5b022f6cfefde58a69e9af8e3a0e71e06d6ad7754b0d4efb9cd2613e58a7a33996d71b56b0d04242722e86666f3f3d058 - languageName: node - linkType: hard - -"ci-info@npm:^4.3.1": +"ci-info@npm:^4.0.0, ci-info@npm:^4.3.1": version: 4.3.1 resolution: "ci-info@npm:4.3.1" checksum: 10c0/7dd82000f514d76ddfe7775e4cb0d66e5c638f5fa0e2a3be29557e898da0d32ac04f231217d414d07fb968b1fbc6d980ee17ddde0d2c516f23da9cfff608f6c1 languageName: node linkType: hard -"cjs-module-lexer@npm:^1.0.0, cjs-module-lexer@npm:^1.2.2": +"cjs-module-lexer@npm:^1.0.0": version: 1.4.3 resolution: "cjs-module-lexer@npm:1.4.3" checksum: 10c0/076b3af85adc4d65dbdab1b5b240fe5b45d44fcf0ef9d429044dd94d19be5589376805c44fb2d4b3e684e5fe6a9b7cf3e426476a6507c45283c5fc6ff95240be @@ -6020,7 +5743,7 @@ __metadata: languageName: node linkType: hard -"clsx@npm:^2.0.0": +"clsx@npm:^2.0.0, clsx@npm:^2.1.1": version: 2.1.1 resolution: "clsx@npm:2.1.1" checksum: 10c0/c4c8eb865f8c82baab07e71bfa8897c73454881c4f99d6bc81585aecd7c441746c1399d08363dc096c550cceaf97bd4ce1e8854e1771e9998d9f94c4fe075839 @@ -6723,13 +6446,6 @@ __metadata: languageName: node linkType: hard -"electron-to-chromium@npm:^1.5.73": - version: 1.5.76 - resolution: "electron-to-chromium@npm:1.5.76" - checksum: 10c0/5a977be9fd5810769a7b4eae0e4b41b6beca65f2b3f3b7442819f6c93366d767d183cfbf408714f944a9bf3aa304f8c9ab9d0cdfd8e878ab8f2cbb61f8b22acd - languageName: node - linkType: hard - "emittery@npm:^0.13.1": version: 0.13.1 resolution: "emittery@npm:0.13.1" @@ -6787,7 +6503,7 @@ __metadata: languageName: node linkType: hard -"entities@npm:^4.2.0, entities@npm:^4.5.0": +"entities@npm:^4.2.0": version: 4.5.0 resolution: "entities@npm:4.5.0" checksum: 10c0/5b039739f7621f5d1ad996715e53d964035f75ad3b9a4d38c6b3804bb226e282ffeae2443624d8fdd9c47d8e926ae9ac009c54671243f0c3294c26af7cc85250 @@ -6838,66 +6554,7 @@ __metadata: languageName: node linkType: hard -"es-abstract@npm:^1.17.5, es-abstract@npm:^1.23.2, es-abstract@npm:^1.23.3, es-abstract@npm:^1.23.5, es-abstract@npm:^1.23.6, es-abstract@npm:^1.23.9": - version: 1.23.9 - resolution: "es-abstract@npm:1.23.9" - dependencies: - array-buffer-byte-length: "npm:^1.0.2" - arraybuffer.prototype.slice: "npm:^1.0.4" - available-typed-arrays: "npm:^1.0.7" - call-bind: "npm:^1.0.8" - call-bound: "npm:^1.0.3" - data-view-buffer: "npm:^1.0.2" - data-view-byte-length: "npm:^1.0.2" - data-view-byte-offset: "npm:^1.0.1" - es-define-property: "npm:^1.0.1" - es-errors: "npm:^1.3.0" - es-object-atoms: "npm:^1.0.0" - es-set-tostringtag: "npm:^2.1.0" - es-to-primitive: "npm:^1.3.0" - function.prototype.name: "npm:^1.1.8" - get-intrinsic: "npm:^1.2.7" - get-proto: "npm:^1.0.0" - get-symbol-description: "npm:^1.1.0" - globalthis: "npm:^1.0.4" - gopd: "npm:^1.2.0" - has-property-descriptors: "npm:^1.0.2" - has-proto: "npm:^1.2.0" - has-symbols: "npm:^1.1.0" - hasown: "npm:^2.0.2" - internal-slot: "npm:^1.1.0" - is-array-buffer: "npm:^3.0.5" - is-callable: "npm:^1.2.7" - is-data-view: "npm:^1.0.2" - is-regex: "npm:^1.2.1" - is-shared-array-buffer: "npm:^1.0.4" - is-string: "npm:^1.1.1" - is-typed-array: "npm:^1.1.15" - is-weakref: "npm:^1.1.0" - math-intrinsics: "npm:^1.1.0" - object-inspect: "npm:^1.13.3" - object-keys: "npm:^1.1.1" - object.assign: "npm:^4.1.7" - own-keys: "npm:^1.0.1" - regexp.prototype.flags: "npm:^1.5.3" - safe-array-concat: "npm:^1.1.3" - safe-push-apply: "npm:^1.0.0" - safe-regex-test: "npm:^1.1.0" - set-proto: "npm:^1.0.0" - string.prototype.trim: "npm:^1.2.10" - string.prototype.trimend: "npm:^1.0.9" - string.prototype.trimstart: "npm:^1.0.8" - typed-array-buffer: "npm:^1.0.3" - typed-array-byte-length: "npm:^1.0.3" - typed-array-byte-offset: "npm:^1.0.4" - typed-array-length: "npm:^1.0.7" - unbox-primitive: "npm:^1.1.0" - which-typed-array: "npm:^1.1.18" - checksum: 10c0/1de229c9e08fe13c17fe5abaec8221545dfcd57e51f64909599a6ae896df84b8fd2f7d16c60cb00d7bf495b9298ca3581aded19939d4b7276854a4b066f8422b - languageName: node - linkType: hard - -"es-abstract@npm:^1.24.0": +"es-abstract@npm:^1.17.5, es-abstract@npm:^1.23.2, es-abstract@npm:^1.23.3, es-abstract@npm:^1.23.5, es-abstract@npm:^1.23.6, es-abstract@npm:^1.23.9, es-abstract@npm:^1.24.0": version: 1.24.1 resolution: "es-abstract@npm:1.24.1" dependencies: @@ -7018,16 +6675,7 @@ __metadata: languageName: node linkType: hard -"es-shim-unscopables@npm:^1.0.2": - version: 1.0.2 - resolution: "es-shim-unscopables@npm:1.0.2" - dependencies: - hasown: "npm:^2.0.0" - checksum: 10c0/f495af7b4b7601a4c0cfb893581c352636e5c08654d129590386a33a0432cf13a7bdc7b6493801cadd990d838e2839b9013d1de3b880440cb537825e834fe783 - languageName: node - linkType: hard - -"es-shim-unscopables@npm:^1.1.0": +"es-shim-unscopables@npm:^1.0.2, es-shim-unscopables@npm:^1.1.0": version: 1.1.0 resolution: "es-shim-unscopables@npm:1.1.0" dependencies: @@ -7345,18 +6993,6 @@ __metadata: languageName: node linkType: hard -"eslint-module-utils@npm:^2.12.0": - version: 2.12.0 - resolution: "eslint-module-utils@npm:2.12.0" - dependencies: - debug: "npm:^3.2.7" - peerDependenciesMeta: - eslint: - optional: true - checksum: 10c0/4d8b46dcd525d71276f9be9ffac1d2be61c9d54cc53c992e6333cf957840dee09381842b1acbbb15fc6b255ebab99cd481c5007ab438e5455a14abe1a0468558 - languageName: node - linkType: hard - "eslint-module-utils@npm:^2.12.1": version: 2.12.1 resolution: "eslint-module-utils@npm:2.12.1" @@ -7394,36 +7030,7 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-import@npm:^2.31.0": - version: 2.31.0 - resolution: "eslint-plugin-import@npm:2.31.0" - dependencies: - "@rtsao/scc": "npm:^1.1.0" - array-includes: "npm:^3.1.8" - array.prototype.findlastindex: "npm:^1.2.5" - array.prototype.flat: "npm:^1.3.2" - array.prototype.flatmap: "npm:^1.3.2" - debug: "npm:^3.2.7" - doctrine: "npm:^2.1.0" - eslint-import-resolver-node: "npm:^0.3.9" - eslint-module-utils: "npm:^2.12.0" - hasown: "npm:^2.0.2" - is-core-module: "npm:^2.15.1" - is-glob: "npm:^4.0.3" - minimatch: "npm:^3.1.2" - object.fromentries: "npm:^2.0.8" - object.groupby: "npm:^1.0.3" - object.values: "npm:^1.2.0" - semver: "npm:^6.3.1" - string.prototype.trimend: "npm:^1.0.8" - tsconfig-paths: "npm:^3.15.0" - peerDependencies: - eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 - checksum: 10c0/e21d116ddd1900e091ad120b3eb68c5dd5437fe2c930f1211781cd38b246f090a6b74d5f3800b8255a0ed29782591521ad44eb21c5534960a8f1fb4040fd913a - languageName: node - linkType: hard - -"eslint-plugin-import@npm:^2.32.0": +"eslint-plugin-import@npm:^2.31.0, eslint-plugin-import@npm:^2.32.0": version: 2.32.0 resolution: "eslint-plugin-import@npm:2.32.0" dependencies: @@ -7699,7 +7306,7 @@ __metadata: languageName: node linkType: hard -"eslint-visitor-keys@npm:^4.2.0, eslint-visitor-keys@npm:^4.2.1": +"eslint-visitor-keys@npm:^4.2.1": version: 4.2.1 resolution: "eslint-visitor-keys@npm:4.2.1" checksum: 10c0/fcd43999199d6740db26c58dbe0c2594623e31ca307e616ac05153c9272f12f1364f5a0b1917a8e962268fdecc6f3622c1c2908b4fcc2e047a106fe6de69dc43 @@ -7958,6 +7565,7 @@ __metadata: "@expo/spawn-async": "npm:^1.7.2" "@expo/styleguide": "npm:^9.3.1" "@expo/styleguide-base": "npm:^2.0.5" + "@expo/styleguide-cookie-consent": "npm:^0.1.11" "@expo/styleguide-icons": "npm:^2.3.4" "@expo/styleguide-search-ui": "npm:^3.3.3" "@kapaai/react-sdk": "npm:^0.9.0" @@ -8151,19 +7759,7 @@ __metadata: languageName: node linkType: hard -"fdir@npm:^6.2.0": - version: 6.4.6 - resolution: "fdir@npm:6.4.6" - peerDependencies: - picomatch: ^3 || ^4 - peerDependenciesMeta: - picomatch: - optional: true - checksum: 10c0/45b559cff889934ebb8bc498351e5acba40750ada7e7d6bde197768d2fa67c149be8ae7f8ff34d03f4e1eb20f2764116e56440aaa2f6689e9a4aa7ef06acafe9 - languageName: node - linkType: hard - -"fdir@npm:^6.5.0": +"fdir@npm:^6.2.0, fdir@npm:^6.5.0": version: 6.5.0 resolution: "fdir@npm:6.5.0" peerDependencies: @@ -8247,16 +7843,7 @@ __metadata: languageName: node linkType: hard -"for-each@npm:^0.3.3": - version: 0.3.3 - resolution: "for-each@npm:0.3.3" - dependencies: - is-callable: "npm:^1.1.3" - checksum: 10c0/22330d8a2db728dbf003ec9182c2d421fbcd2969b02b4f97ec288721cda63eb28f2c08585ddccd0f77cb2930af8d958005c9e72f47141dc51816127a118f39aa - languageName: node - linkType: hard - -"for-each@npm:^0.3.5": +"for-each@npm:^0.3.3, for-each@npm:^0.3.5": version: 0.3.5 resolution: "for-each@npm:0.3.5" dependencies: @@ -8564,23 +8151,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:^10.0.0, glob@npm:^10.2.2, glob@npm:^10.3.10, glob@npm:^10.3.7": - version: 10.4.5 - resolution: "glob@npm:10.4.5" - dependencies: - foreground-child: "npm:^3.1.0" - jackspeak: "npm:^3.1.2" - minimatch: "npm:^9.0.4" - minipass: "npm:^7.1.2" - package-json-from-dist: "npm:^1.0.0" - path-scurry: "npm:^1.11.1" - bin: - glob: dist/esm/bin.mjs - checksum: 10c0/19a9759ea77b8e3ca0a43c2f07ecddc2ad46216b786bb8f993c445aee80d345925a21e5280c7b7c6c59e860a0154b84e4b2b60321fea92cd3c56b4a7489f160e - languageName: node - linkType: hard - -"glob@npm:^10.5.0": +"glob@npm:^10.0.0, glob@npm:^10.2.2, glob@npm:^10.3.10, glob@npm:^10.3.7, glob@npm:^10.5.0": version: 10.5.0 resolution: "glob@npm:10.5.0" dependencies: @@ -8631,14 +8202,7 @@ __metadata: languageName: node linkType: hard -"globals@npm:^16.0.0": - version: 16.0.0 - resolution: "globals@npm:16.0.0" - checksum: 10c0/8906d5f01838df64a81d6c2a7b7214312e2216cf65c5ed1546dc9a7d0febddf55ffa906cf04efd5b01eec2534d6f14859a89535d1a68241832810e41ef3fd5bb - languageName: node - linkType: hard - -"globals@npm:^16.4.0": +"globals@npm:^16.0.0, globals@npm:^16.4.0": version: 16.5.0 resolution: "globals@npm:16.5.0" checksum: 10c0/615241dae7851c8012f5aa0223005b1ed6607713d6813de0741768bd4ddc39353117648f1a7086b4b0fa45eae733f1c0a0fe369aa4e543bb63f8de8990178ea9 @@ -8669,13 +8233,6 @@ __metadata: languageName: node linkType: hard -"graphemer@npm:^1.4.0": - version: 1.4.0 - resolution: "graphemer@npm:1.4.0" - checksum: 10c0/e951259d8cd2e0d196c72ec711add7115d42eb9a8146c8eeda5b8d3ac91e5dd816b9cd68920726d9fd4490368e7ed86e9c423f40db87e2d8dfafa00fa17c3a31 - languageName: node - linkType: hard - "has-bigints@npm:^1.0.2": version: 1.1.0 resolution: "has-bigints@npm:1.1.0" @@ -8724,7 +8281,7 @@ __metadata: languageName: node linkType: hard -"hasown@npm:^2.0.0, hasown@npm:^2.0.2": +"hasown@npm:^2.0.2": version: 2.0.2 resolution: "hasown@npm:2.0.2" dependencies: @@ -8999,7 +8556,7 @@ __metadata: languageName: node linkType: hard -"ignore@npm:^5.1.1, ignore@npm:^5.2.0, ignore@npm:^5.3.1, ignore@npm:^5.3.2": +"ignore@npm:^5.1.1, ignore@npm:^5.2.0, ignore@npm:^5.3.2": version: 5.3.2 resolution: "ignore@npm:5.3.2" checksum: 10c0/f9f652c957983634ded1e7f02da3b559a0d4cc210fca3792cb67f1b153623c9c42efdc1c4121af171e295444459fc4a9201101fb041b1104a3c000bccb188337 @@ -9037,19 +8594,7 @@ __metadata: languageName: node linkType: hard -"import-in-the-middle@npm:^2.0.0": - version: 2.0.0 - resolution: "import-in-the-middle@npm:2.0.0" - dependencies: - acorn: "npm:^8.14.0" - acorn-import-attributes: "npm:^1.9.5" - cjs-module-lexer: "npm:^1.2.2" - module-details-from-path: "npm:^1.0.3" - checksum: 10c0/b4349a1bac96a5ffb584564c24bb5ff70085d1e6f0a614392f7cd2321c9a1871bc6c3e93a01cbc0eeb7663ae572b717b808e9d24fe213b4ce373dd87d59ca8c5 - languageName: node - linkType: hard - -"import-in-the-middle@npm:^2.0.1": +"import-in-the-middle@npm:^2.0.0, import-in-the-middle@npm:^2.0.1": version: 2.0.6 resolution: "import-in-the-middle@npm:2.0.6" dependencies: @@ -9262,14 +8807,14 @@ __metadata: languageName: node linkType: hard -"is-callable@npm:^1.1.3, is-callable@npm:^1.2.7": +"is-callable@npm:^1.2.7": version: 1.2.7 resolution: "is-callable@npm:1.2.7" checksum: 10c0/ceebaeb9d92e8adee604076971dd6000d38d6afc40bb843ea8e45c5579b57671c3f3b50d7f04869618242c6cee08d1b67806a8cb8edaaaf7c0748b3720d6066f languageName: node linkType: hard -"is-core-module@npm:^2.13.0, is-core-module@npm:^2.15.1, is-core-module@npm:^2.16.0, is-core-module@npm:^2.16.1": +"is-core-module@npm:^2.13.0, is-core-module@npm:^2.16.0, is-core-module@npm:^2.16.1": version: 2.16.1 resolution: "is-core-module@npm:2.16.1" dependencies: @@ -9467,7 +9012,7 @@ __metadata: languageName: node linkType: hard -"is-string@npm:^1.0.7, is-string@npm:^1.1.1": +"is-string@npm:^1.1.1": version: 1.1.1 resolution: "is-string@npm:1.1.1" dependencies: @@ -9504,16 +9049,7 @@ __metadata: languageName: node linkType: hard -"is-weakref@npm:^1.0.2, is-weakref@npm:^1.1.0": - version: 1.1.0 - resolution: "is-weakref@npm:1.1.0" - dependencies: - call-bound: "npm:^1.0.2" - checksum: 10c0/aa835f62e29cb60132ecb3ec7d11bd0f39ec7322325abe8412b805aef47153ec2daefdb21759b049711c674f49b13202a31d8d126bcdff7d8671c78babd4ae5b - languageName: node - linkType: hard - -"is-weakref@npm:^1.1.1": +"is-weakref@npm:^1.0.2, is-weakref@npm:^1.1.1": version: 1.1.1 resolution: "is-weakref@npm:1.1.1" dependencies: @@ -10446,14 +9982,7 @@ __metadata: languageName: node linkType: hard -"lodash@npm:^4.17.14, lodash@npm:^4.17.21": - version: 4.17.21 - resolution: "lodash@npm:4.17.21" - checksum: 10c0/d8cbea072bb08655bb4c989da418994b073a608dffa608b09ac04b43a791b12aeae7cd7ad919aa4c925f33b48490b5cfe6c1f71d827956071dae2e7bb3a6b74c - languageName: node - linkType: hard - -"lodash@npm:^4.17.23": +"lodash@npm:^4.17.14, lodash@npm:^4.17.21, lodash@npm:^4.17.23": version: 4.17.23 resolution: "lodash@npm:4.17.23" checksum: 10c0/1264a90469f5bb95d4739c43eb6277d15b6d9e186df4ac68c3620443160fc669e2f14c11e7d8b2ccf078b81d06147c01a8ccced9aab9f9f63d50dcf8cace6bf6 @@ -10843,20 +10372,13 @@ __metadata: languageName: node linkType: hard -"media-tracks@npm:^0.3.4": +"media-tracks@npm:^0.3.4, media-tracks@npm:~0.3.3": version: 0.3.4 resolution: "media-tracks@npm:0.3.4" checksum: 10c0/5d42013c1dfe885c3c4642edf35273df62412fdd36e19bf9741e09e33cde8134ad80ff742e99868cf53dc226ae9a938b09d61237e0205c9a8d2763fd564bc07f languageName: node linkType: hard -"media-tracks@npm:~0.3.3": - version: 0.3.3 - resolution: "media-tracks@npm:0.3.3" - checksum: 10c0/ecd57e628222b6e0611f21813a291a47b30c96aa1c9d7e13546932b59e8bb206651961a36360cc5584bf76bf890ce01be3bb0c045facf76ab8b1cfacecf9808b - languageName: node - linkType: hard - "merge-stream@npm:^2.0.0": version: 2.0.0 resolution: "merge-stream@npm:2.0.0" @@ -11805,13 +11327,6 @@ __metadata: languageName: node linkType: hard -"node-releases@npm:^2.0.19": - version: 2.0.19 - resolution: "node-releases@npm:2.0.19" - checksum: 10c0/52a0dbd25ccf545892670d1551690fe0facb6a471e15f2cfa1b20142a5b255b3aa254af5f59d6ecb69c2bec7390bc643c43aa63b13bf5e64b6075952e716b1aa - languageName: node - linkType: hard - "node-releases@npm:^2.0.27": version: 2.0.27 resolution: "node-releases@npm:2.0.27" @@ -11952,14 +11467,7 @@ __metadata: languageName: node linkType: hard -"object-inspect@npm:^1.13.3": - version: 1.13.3 - resolution: "object-inspect@npm:1.13.3" - checksum: 10c0/cc3f15213406be89ffdc54b525e115156086796a515410a8d390215915db9f23c8eab485a06f1297402f440a33715fe8f71a528c1dcbad6e1a3bcaf5a46921d4 - languageName: node - linkType: hard - -"object-inspect@npm:^1.13.4": +"object-inspect@npm:^1.13.3, object-inspect@npm:^1.13.4": version: 1.13.4 resolution: "object-inspect@npm:1.13.4" checksum: 10c0/d7f8711e803b96ea3191c745d6f8056ce1f2496e530e6a19a0e92d89b0fa3c76d910c31f0aa270432db6bd3b2f85500a376a83aaba849a8d518c8845b3211692 @@ -12022,7 +11530,7 @@ __metadata: languageName: node linkType: hard -"object.values@npm:^1.1.6, object.values@npm:^1.2.0, object.values@npm:^1.2.1": +"object.values@npm:^1.1.6, object.values@npm:^1.2.1": version: 1.2.1 resolution: "object.values@npm:1.2.1" dependencies: @@ -12211,16 +11719,7 @@ __metadata: languageName: node linkType: hard -"parse5@npm:^7.0.0, parse5@npm:^7.1.1": - version: 7.2.1 - resolution: "parse5@npm:7.2.1" - dependencies: - entities: "npm:^4.5.0" - checksum: 10c0/829d37a0c709215a887e410a7118d754f8e1afd7edb529db95bc7bbf8045fb0266a7b67801331d8e8d9d073ea75793624ec27ce9ff3b96862c3b9008f4d68e80 - languageName: node - linkType: hard - -"parse5@npm:^7.3.0": +"parse5@npm:^7.0.0, parse5@npm:^7.1.1, parse5@npm:^7.3.0": version: 7.3.0 resolution: "parse5@npm:7.3.0" dependencies: @@ -12315,7 +11814,7 @@ __metadata: languageName: node linkType: hard -"picocolors@npm:1.1.1, picocolors@npm:^1.0.0, picocolors@npm:^1.1.0, picocolors@npm:^1.1.1": +"picocolors@npm:1.1.1, picocolors@npm:^1.0.0, picocolors@npm:^1.1.1": version: 1.1.1 resolution: "picocolors@npm:1.1.1" checksum: 10c0/e2e3e8170ab9d7c7421969adaa7e1b31434f789afb9b3f115f6b96d91945041ac3ceb02e9ec6fe6510ff036bcc0bf91e69a1772edc0b707e12b19c0f2d6bcf58 @@ -13715,12 +13214,12 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.1.1, semver@npm:^7.3.5, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.6.3, semver@npm:^7.7.3": - version: 7.7.3 - resolution: "semver@npm:7.7.3" +"semver@npm:^7.1.1, semver@npm:^7.3.5, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.3, semver@npm:^7.7.3": + version: 7.7.4 + resolution: "semver@npm:7.7.4" bin: semver: bin/semver.js - checksum: 10c0/4afe5c986567db82f44c8c6faef8fe9df2a9b1d98098fc1721f57c696c4c21cebd572f297fc21002f81889492345b8470473bc6f4aff5fb032a6ea59ea2bc45e + checksum: 10c0/5215ad0234e2845d4ea5bb9d836d42b03499546ddafb12075566899fc617f68794bb6f146076b6881d755de17d6c6cc73372555879ec7dce2c2feee947866ad2 languageName: node linkType: hard @@ -14230,7 +13729,7 @@ __metadata: languageName: node linkType: hard -"string.prototype.trimend@npm:^1.0.8, string.prototype.trimend@npm:^1.0.9": +"string.prototype.trimend@npm:^1.0.9": version: 1.0.9 resolution: "string.prototype.trimend@npm:1.0.9" dependencies: @@ -14684,15 +14183,6 @@ __metadata: languageName: node linkType: hard -"ts-api-utils@npm:^2.0.1": - version: 2.0.1 - resolution: "ts-api-utils@npm:2.0.1" - peerDependencies: - typescript: ">=4.8.4" - checksum: 10c0/23fd56a958b332cac00150a652e4c84730df30571bd2faa1ba6d7b511356d1a61656621492bb6c7f15dd6e18847a1408357a0e406671d358115369a17f5bfedd - languageName: node - linkType: hard - "ts-api-utils@npm:^2.4.0": version: 2.4.0 resolution: "ts-api-utils@npm:2.4.0" @@ -14920,6 +14410,13 @@ __metadata: languageName: node linkType: hard +"undici-types@npm:~7.16.0": + version: 7.16.0 + resolution: "undici-types@npm:7.16.0" + checksum: 10c0/3033e2f2b5c9f1504bdc5934646cb54e37ecaca0f9249c983f7b1fc2e87c6d18399ebb05dc7fd5419e02b2e915f734d872a65da2e3eeed1813951c427d33cc9a + languageName: node + linkType: hard + "undici@npm:7.18.2": version: 7.18.2 resolution: "undici@npm:7.18.2" @@ -15219,20 +14716,6 @@ __metadata: languageName: node linkType: hard -"update-browserslist-db@npm:^1.1.1": - version: 1.1.1 - resolution: "update-browserslist-db@npm:1.1.1" - dependencies: - escalade: "npm:^3.2.0" - picocolors: "npm:^1.1.0" - peerDependencies: - browserslist: ">= 4.21.0" - bin: - update-browserslist-db: cli.js - checksum: 10c0/536a2979adda2b4be81b07e311bd2f3ad5e978690987956bc5f514130ad50cac87cd22c710b686d79731e00fbee8ef43efe5fcd72baa241045209195d43dcc80 - languageName: node - linkType: hard - "update-browserslist-db@npm:^1.1.4": version: 1.1.4 resolution: "update-browserslist-db@npm:1.1.4" @@ -15641,21 +15124,7 @@ __metadata: languageName: node linkType: hard -"which-typed-array@npm:^1.1.16, which-typed-array@npm:^1.1.18": - version: 1.1.18 - resolution: "which-typed-array@npm:1.1.18" - dependencies: - available-typed-arrays: "npm:^1.0.7" - call-bind: "npm:^1.0.8" - call-bound: "npm:^1.0.3" - for-each: "npm:^0.3.3" - gopd: "npm:^1.2.0" - has-tostringtag: "npm:^1.0.2" - checksum: 10c0/0412f4a91880ca1a2a63056187c2e3de6b129b2b5b6c17bc3729f0f7041047ae48fb7424813e51506addb2c97320003ee18b8c57469d2cde37983ef62126143c - languageName: node - linkType: hard - -"which-typed-array@npm:^1.1.19": +"which-typed-array@npm:^1.1.16, which-typed-array@npm:^1.1.19": version: 1.1.20 resolution: "which-typed-array@npm:1.1.20" dependencies: @@ -15997,6 +15466,27 @@ __metadata: languageName: node linkType: hard +"zustand@npm:^5.0.3": + version: 5.0.11 + resolution: "zustand@npm:5.0.11" + peerDependencies: + "@types/react": ">=18.0.0" + immer: ">=9.0.6" + react: ">=18.0.0" + use-sync-external-store: ">=1.2.0" + peerDependenciesMeta: + "@types/react": + optional: true + immer: + optional: true + react: + optional: true + use-sync-external-store: + optional: true + checksum: 10c0/61836b48dac5978c9d1b8289d5162a151bee77828371b9aba6431a079b77faca0635ba53da3f7b331295fbc4e78318a109a4527f7a051cb63abfe79b69ccbecf + languageName: node + linkType: hard + "zwitch@npm:^2.0.0": version: 2.0.4 resolution: "zwitch@npm:2.0.4" diff --git a/packages/expo-modules-autolinking/CHANGELOG.md b/packages/expo-modules-autolinking/CHANGELOG.md index c08ed1ba7cbd6a..f9c512b8edfe9b 100644 --- a/packages/expo-modules-autolinking/CHANGELOG.md +++ b/packages/expo-modules-autolinking/CHANGELOG.md @@ -10,6 +10,9 @@ ### 💡 Others +- Reduce memory retained after autolinking runs ([#42947](https://github.com/expo/expo/pull/42947) by [@kitten](https://github.com/kitten)) +- Add concurrency limits to IO-bound autolinking tasks ([#42968](https://github.com/expo/expo/pull/42968) by [@kitten](https://github.com/kitten)) + ## 55.0.5 — 2026-02-16 _This version does not introduce any user-facing changes._ diff --git a/packages/expo-modules-autolinking/build/ExpoModuleConfig.d.ts b/packages/expo-modules-autolinking/build/ExpoModuleConfig.d.ts index 97639d5993d8f9..4d3363a924d021 100644 --- a/packages/expo-modules-autolinking/build/ExpoModuleConfig.d.ts +++ b/packages/expo-modules-autolinking/build/ExpoModuleConfig.d.ts @@ -85,4 +85,4 @@ export declare class ExpoModuleConfig { */ toJSON(): RawExpoModuleConfig; } -export declare const discoverExpoModuleConfigAsync: (input: string, ...args: any[]) => Promise; +export declare const discoverExpoModuleConfigAsync: import("./memoize").MemoizableAsyncFn; diff --git a/packages/expo-modules-autolinking/build/ExpoModuleConfig.js b/packages/expo-modules-autolinking/build/ExpoModuleConfig.js index eabd12a683bba7..b9718a90555ccb 100644 --- a/packages/expo-modules-autolinking/build/ExpoModuleConfig.js +++ b/packages/expo-modules-autolinking/build/ExpoModuleConfig.js @@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.discoverExpoModuleConfigAsync = exports.ExpoModuleConfig = exports.ExpoAndroidProjectConfig = exports.ExpoAndroidModuleConfig = void 0; const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); -const utils_1 = require("./utils"); +const memoize_1 = require("./memoize"); function arrayize(value) { if (Array.isArray(value)) { return value; @@ -174,7 +174,7 @@ class ExpoModuleConfig { exports.ExpoModuleConfig = ExpoModuleConfig; /** Names of Expo Module config files (highest to lowest priority) */ const EXPO_MODULE_CONFIG_FILENAMES = ['expo-module.config.json', 'unimodule.json']; -exports.discoverExpoModuleConfigAsync = (0, utils_1.memoize)(async function discoverExpoModuleConfigAsync(directoryPath) { +exports.discoverExpoModuleConfigAsync = (0, memoize_1.memoize)(async function discoverExpoModuleConfigAsync(directoryPath) { for (let idx = 0; idx < EXPO_MODULE_CONFIG_FILENAMES.length; idx++) { // TODO: Validate the raw config against a schema. // TODO: Support for `*.js` files, not only static `*.json`. diff --git a/packages/expo-modules-autolinking/build/ExpoModuleConfig.js.map b/packages/expo-modules-autolinking/build/ExpoModuleConfig.js.map index 49b2d68fd558dc..29d3987db1e3cb 100644 --- a/packages/expo-modules-autolinking/build/ExpoModuleConfig.js.map +++ b/packages/expo-modules-autolinking/build/ExpoModuleConfig.js.map @@ -1 +1 @@ -{"version":3,"file":"ExpoModuleConfig.js","sourceRoot":"","sources":["../src/ExpoModuleConfig.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs';\nimport path from 'path';\n\nimport {\n AndroidGradleAarProjectDescriptor,\n AndroidGradlePluginDescriptor,\n AndroidPublication,\n RawExpoModuleConfig,\n RawModuleConfigApple,\n SupportedPlatform,\n} from './types';\nimport { memoize } from './utils';\n\nfunction arrayize(value: T[] | T | undefined): T[] {\n if (Array.isArray(value)) {\n return value;\n }\n return value != null ? [value] : [];\n}\n\nexport class ExpoAndroidModuleConfig {\n constructor(\n public classifier: string,\n public name: string | null\n ) {}\n}\n\nexport class ExpoAndroidProjectConfig {\n constructor(\n public name: string,\n public path: string,\n public modules?: ExpoAndroidModuleConfig[],\n public services?: string[],\n public publication?: AndroidPublication,\n public gradleAarProjects?: AndroidGradleAarProjectDescriptor[],\n public shouldUsePublicationScriptPath?: string,\n /**\n * Whether this project is the root one.\n */\n public isDefault: boolean = false\n ) {}\n}\n\n/**\n * A class that wraps the raw config (`expo-module.json` or `unimodule.json`).\n */\nexport class ExpoModuleConfig {\n constructor(readonly rawConfig: RawExpoModuleConfig) {}\n\n /**\n * Whether the module supports given platform.\n */\n supportsPlatform(platform: SupportedPlatform): boolean {\n const supportedPlatforms = this.rawConfig.platforms ?? [];\n\n if (platform === 'web') {\n // Web platform is implicitly supported for autolinking resolution but has no special behavior\n return true;\n } else if (platform === 'apple') {\n // Apple platform is supported when any of iOS, macOS and tvOS is supported.\n return supportedPlatforms.some((supportedPlatform) => {\n return ['apple', 'ios', 'macos', 'tvos'].includes(supportedPlatform);\n });\n }\n switch (platform) {\n case 'ios':\n case 'macos':\n case 'tvos':\n // ios|macos|tvos are supported when the module supports \"apple\" as a platform in general\n return supportedPlatforms.includes(platform) || supportedPlatforms.includes('apple');\n default:\n return supportedPlatforms.includes(platform);\n }\n }\n\n /**\n * Returns the generic config for all Apple platforms with a fallback to the legacy iOS config.\n */\n getAppleConfig(): RawModuleConfigApple | null {\n return this.rawConfig.apple ?? this.rawConfig.ios ?? null;\n }\n\n /**\n * Returns a list of names of Swift native modules classes to put to the generated modules provider file.\n */\n appleModules() {\n const appleConfig = this.getAppleConfig();\n return appleConfig?.modules ?? [];\n }\n\n /**\n * Returns a list of names of Swift classes that receives AppDelegate life-cycle events.\n */\n appleAppDelegateSubscribers(): string[] {\n return this.getAppleConfig()?.appDelegateSubscribers ?? [];\n }\n\n /**\n * Returns a list of names of Swift classes that implement `ExpoReactDelegateHandler`.\n */\n appleReactDelegateHandlers(): string[] {\n return this.getAppleConfig()?.reactDelegateHandlers ?? [];\n }\n\n /**\n * Returns podspec paths defined by the module author.\n */\n applePodspecPaths(): string[] {\n return arrayize(this.getAppleConfig()?.podspecPath);\n }\n\n /**\n * Returns the product module names, if defined by the module author.\n */\n appleSwiftModuleNames(): string[] {\n return arrayize(this.getAppleConfig()?.swiftModuleName);\n }\n\n /**\n * Returns whether this module will be added only to the debug configuration\n */\n appleDebugOnly(): boolean {\n return this.getAppleConfig()?.debugOnly ?? false;\n }\n\n /**\n * Returns information about Android projects defined by the module author.\n */\n androidProjects(defaultProjectName: string): ExpoAndroidProjectConfig[] {\n const androidProjects: ExpoAndroidProjectConfig[] = [];\n\n // Adding the \"root\" Android project - it might not be valide.\n androidProjects.push(\n new ExpoAndroidProjectConfig(\n this.rawConfig.android?.name ?? defaultProjectName,\n this.rawConfig.android?.path ?? 'android',\n this.rawConfig.android?.modules?.map((module) =>\n typeof module === 'string'\n ? new ExpoAndroidModuleConfig(module, null)\n : new ExpoAndroidModuleConfig(module.class, module.name)\n ),\n this.rawConfig.android?.services,\n this.rawConfig.android?.publication,\n this.rawConfig.android?.gradleAarProjects,\n this.rawConfig.android?.shouldUsePublicationScriptPath,\n !this.rawConfig.android?.path // it's default project because path is not defined\n )\n );\n\n this.rawConfig.android?.projects?.forEach((project) => {\n androidProjects.push(\n new ExpoAndroidProjectConfig(\n project.name,\n project.path,\n project.modules?.map((module) =>\n typeof module === 'string'\n ? new ExpoAndroidModuleConfig(module, null)\n : new ExpoAndroidModuleConfig(module.class, module.name)\n ),\n project.services,\n project.publication,\n project.gradleAarProjects,\n project.shouldUsePublicationScriptPath\n )\n );\n });\n\n return androidProjects;\n }\n\n /**\n * Returns gradle plugins descriptors defined by the module author.\n */\n androidGradlePlugins(): AndroidGradlePluginDescriptor[] {\n return arrayize(this.rawConfig.android?.gradlePlugins ?? []);\n }\n\n /**\n * Returns gradle projects containing AAR files defined by the module author.\n */\n androidGradleAarProjects(): AndroidGradleAarProjectDescriptor[] {\n return arrayize(this.rawConfig.android?.gradleAarProjects ?? []);\n }\n\n /**\n * Returns the publication config for Android.\n */\n androidPublication(): AndroidPublication | undefined {\n return this.rawConfig.android?.publication;\n }\n\n /**\n * Returns core features required by the module author.\n */\n coreFeatures(): string[] {\n return arrayize(this.rawConfig.coreFeatures ?? []);\n }\n\n /**\n * Returns serializable raw config.\n */\n toJSON(): RawExpoModuleConfig {\n return this.rawConfig;\n }\n}\n\n/** Names of Expo Module config files (highest to lowest priority) */\nconst EXPO_MODULE_CONFIG_FILENAMES = ['expo-module.config.json', 'unimodule.json'];\n\nexport const discoverExpoModuleConfigAsync = memoize(async function discoverExpoModuleConfigAsync(\n directoryPath: string\n): Promise {\n for (let idx = 0; idx < EXPO_MODULE_CONFIG_FILENAMES.length; idx++) {\n // TODO: Validate the raw config against a schema.\n // TODO: Support for `*.js` files, not only static `*.json`.\n const targetPath = path.join(directoryPath, EXPO_MODULE_CONFIG_FILENAMES[idx]);\n let text: string;\n try {\n text = await fs.promises.readFile(targetPath, 'utf8');\n } catch {\n // try the next file\n continue;\n }\n return new ExpoModuleConfig(JSON.parse(text) as RawExpoModuleConfig);\n }\n return null;\n});\n"]} \ No newline at end of file +{"version":3,"file":"ExpoModuleConfig.js","sourceRoot":"","sources":["../src/ExpoModuleConfig.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs';\nimport path from 'path';\n\nimport { memoize } from './memoize';\nimport {\n AndroidGradleAarProjectDescriptor,\n AndroidGradlePluginDescriptor,\n AndroidPublication,\n RawExpoModuleConfig,\n RawModuleConfigApple,\n SupportedPlatform,\n} from './types';\n\nfunction arrayize(value: T[] | T | undefined): T[] {\n if (Array.isArray(value)) {\n return value;\n }\n return value != null ? [value] : [];\n}\n\nexport class ExpoAndroidModuleConfig {\n constructor(\n public classifier: string,\n public name: string | null\n ) {}\n}\n\nexport class ExpoAndroidProjectConfig {\n constructor(\n public name: string,\n public path: string,\n public modules?: ExpoAndroidModuleConfig[],\n public services?: string[],\n public publication?: AndroidPublication,\n public gradleAarProjects?: AndroidGradleAarProjectDescriptor[],\n public shouldUsePublicationScriptPath?: string,\n /**\n * Whether this project is the root one.\n */\n public isDefault: boolean = false\n ) {}\n}\n\n/**\n * A class that wraps the raw config (`expo-module.json` or `unimodule.json`).\n */\nexport class ExpoModuleConfig {\n constructor(readonly rawConfig: RawExpoModuleConfig) {}\n\n /**\n * Whether the module supports given platform.\n */\n supportsPlatform(platform: SupportedPlatform): boolean {\n const supportedPlatforms = this.rawConfig.platforms ?? [];\n\n if (platform === 'web') {\n // Web platform is implicitly supported for autolinking resolution but has no special behavior\n return true;\n } else if (platform === 'apple') {\n // Apple platform is supported when any of iOS, macOS and tvOS is supported.\n return supportedPlatforms.some((supportedPlatform) => {\n return ['apple', 'ios', 'macos', 'tvos'].includes(supportedPlatform);\n });\n }\n switch (platform) {\n case 'ios':\n case 'macos':\n case 'tvos':\n // ios|macos|tvos are supported when the module supports \"apple\" as a platform in general\n return supportedPlatforms.includes(platform) || supportedPlatforms.includes('apple');\n default:\n return supportedPlatforms.includes(platform);\n }\n }\n\n /**\n * Returns the generic config for all Apple platforms with a fallback to the legacy iOS config.\n */\n getAppleConfig(): RawModuleConfigApple | null {\n return this.rawConfig.apple ?? this.rawConfig.ios ?? null;\n }\n\n /**\n * Returns a list of names of Swift native modules classes to put to the generated modules provider file.\n */\n appleModules() {\n const appleConfig = this.getAppleConfig();\n return appleConfig?.modules ?? [];\n }\n\n /**\n * Returns a list of names of Swift classes that receives AppDelegate life-cycle events.\n */\n appleAppDelegateSubscribers(): string[] {\n return this.getAppleConfig()?.appDelegateSubscribers ?? [];\n }\n\n /**\n * Returns a list of names of Swift classes that implement `ExpoReactDelegateHandler`.\n */\n appleReactDelegateHandlers(): string[] {\n return this.getAppleConfig()?.reactDelegateHandlers ?? [];\n }\n\n /**\n * Returns podspec paths defined by the module author.\n */\n applePodspecPaths(): string[] {\n return arrayize(this.getAppleConfig()?.podspecPath);\n }\n\n /**\n * Returns the product module names, if defined by the module author.\n */\n appleSwiftModuleNames(): string[] {\n return arrayize(this.getAppleConfig()?.swiftModuleName);\n }\n\n /**\n * Returns whether this module will be added only to the debug configuration\n */\n appleDebugOnly(): boolean {\n return this.getAppleConfig()?.debugOnly ?? false;\n }\n\n /**\n * Returns information about Android projects defined by the module author.\n */\n androidProjects(defaultProjectName: string): ExpoAndroidProjectConfig[] {\n const androidProjects: ExpoAndroidProjectConfig[] = [];\n\n // Adding the \"root\" Android project - it might not be valide.\n androidProjects.push(\n new ExpoAndroidProjectConfig(\n this.rawConfig.android?.name ?? defaultProjectName,\n this.rawConfig.android?.path ?? 'android',\n this.rawConfig.android?.modules?.map((module) =>\n typeof module === 'string'\n ? new ExpoAndroidModuleConfig(module, null)\n : new ExpoAndroidModuleConfig(module.class, module.name)\n ),\n this.rawConfig.android?.services,\n this.rawConfig.android?.publication,\n this.rawConfig.android?.gradleAarProjects,\n this.rawConfig.android?.shouldUsePublicationScriptPath,\n !this.rawConfig.android?.path // it's default project because path is not defined\n )\n );\n\n this.rawConfig.android?.projects?.forEach((project) => {\n androidProjects.push(\n new ExpoAndroidProjectConfig(\n project.name,\n project.path,\n project.modules?.map((module) =>\n typeof module === 'string'\n ? new ExpoAndroidModuleConfig(module, null)\n : new ExpoAndroidModuleConfig(module.class, module.name)\n ),\n project.services,\n project.publication,\n project.gradleAarProjects,\n project.shouldUsePublicationScriptPath\n )\n );\n });\n\n return androidProjects;\n }\n\n /**\n * Returns gradle plugins descriptors defined by the module author.\n */\n androidGradlePlugins(): AndroidGradlePluginDescriptor[] {\n return arrayize(this.rawConfig.android?.gradlePlugins ?? []);\n }\n\n /**\n * Returns gradle projects containing AAR files defined by the module author.\n */\n androidGradleAarProjects(): AndroidGradleAarProjectDescriptor[] {\n return arrayize(this.rawConfig.android?.gradleAarProjects ?? []);\n }\n\n /**\n * Returns the publication config for Android.\n */\n androidPublication(): AndroidPublication | undefined {\n return this.rawConfig.android?.publication;\n }\n\n /**\n * Returns core features required by the module author.\n */\n coreFeatures(): string[] {\n return arrayize(this.rawConfig.coreFeatures ?? []);\n }\n\n /**\n * Returns serializable raw config.\n */\n toJSON(): RawExpoModuleConfig {\n return this.rawConfig;\n }\n}\n\n/** Names of Expo Module config files (highest to lowest priority) */\nconst EXPO_MODULE_CONFIG_FILENAMES = ['expo-module.config.json', 'unimodule.json'];\n\nexport const discoverExpoModuleConfigAsync = memoize(async function discoverExpoModuleConfigAsync(\n directoryPath: string\n): Promise {\n for (let idx = 0; idx < EXPO_MODULE_CONFIG_FILENAMES.length; idx++) {\n // TODO: Validate the raw config against a schema.\n // TODO: Support for `*.js` files, not only static `*.json`.\n const targetPath = path.join(directoryPath, EXPO_MODULE_CONFIG_FILENAMES[idx]);\n let text: string;\n try {\n text = await fs.promises.readFile(targetPath, 'utf8');\n } catch {\n // try the next file\n continue;\n }\n return new ExpoModuleConfig(JSON.parse(text) as RawExpoModuleConfig);\n }\n return null;\n});\n"]} \ No newline at end of file diff --git a/packages/expo-modules-autolinking/build/autolinking/findModules.js b/packages/expo-modules-autolinking/build/autolinking/findModules.js index f907746d6dc898..d4ba449206366a 100644 --- a/packages/expo-modules-autolinking/build/autolinking/findModules.js +++ b/packages/expo-modules-autolinking/build/autolinking/findModules.js @@ -4,6 +4,7 @@ exports.resolveExpoModule = resolveExpoModule; exports.findModulesAsync = findModulesAsync; const ExpoModuleConfig_1 = require("../ExpoModuleConfig"); const dependencies_1 = require("../dependencies"); +const memoize_1 = require("../memoize"); async function resolveExpoModule(resolution, platform, excludeNames) { if (excludeNames.has(resolution.name)) { return null; @@ -28,14 +29,17 @@ async function resolveExpoModule(resolution, platform, excludeNames) { } /** Searches for modules to link based on given config. */ async function findModulesAsync({ appRoot, autolinkingOptions, }) { + const memoizer = (0, memoize_1.createMemoizer)(); const excludeNames = new Set(autolinkingOptions.exclude); // custom native modules should be resolved first so that they can override other modules const searchPaths = autolinkingOptions.nativeModulesDir ? [autolinkingOptions.nativeModulesDir, ...autolinkingOptions.searchPaths] : autolinkingOptions.searchPaths; - return (0, dependencies_1.filterMapResolutionResult)((0, dependencies_1.mergeResolutionResults)(await Promise.all([ - ...searchPaths.map((searchPath) => (0, dependencies_1.scanDependenciesInSearchPath)(searchPath)), - (0, dependencies_1.scanDependenciesRecursively)(appRoot), - ])), (resolution) => resolveExpoModule(resolution, autolinkingOptions.platform, excludeNames)); + return memoizer.withMemoizer(async () => { + return (0, dependencies_1.filterMapResolutionResult)((0, dependencies_1.mergeResolutionResults)(await Promise.all([ + ...searchPaths.map((searchPath) => (0, dependencies_1.scanDependenciesInSearchPath)(searchPath)), + (0, dependencies_1.scanDependenciesRecursively)(appRoot), + ])), (resolution) => resolveExpoModule(resolution, autolinkingOptions.platform, excludeNames)); + }); } //# sourceMappingURL=findModules.js.map \ No newline at end of file diff --git a/packages/expo-modules-autolinking/build/autolinking/findModules.js.map b/packages/expo-modules-autolinking/build/autolinking/findModules.js.map index 0cc6b3bc6628a2..41e9cb2d4dd280 100644 --- a/packages/expo-modules-autolinking/build/autolinking/findModules.js.map +++ b/packages/expo-modules-autolinking/build/autolinking/findModules.js.map @@ -1 +1 @@ -{"version":3,"file":"findModules.js","sourceRoot":"","sources":["../../src/autolinking/findModules.ts"],"names":[],"mappings":";;AAWA,8CAyBC;AAQD,4CAoBC;AAhED,0DAAoE;AAEpE,kDAMyB;AAGlB,KAAK,UAAU,iBAAiB,CACrC,UAAgC,EAChC,QAA2B,EAC3B,YAAyB;IAEzB,IAAI,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,gBAAgB,GAAG,MAAM,IAAA,gDAA6B,EAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAC9E,IAAI,gBAAgB,IAAI,gBAAgB,CAAC,gBAAgB,CAAC,QAAQ,CAAC,EAAE,CAAC;QACpE,OAAO;YACL,IAAI,EAAE,UAAU,CAAC,IAAI;YACrB,IAAI,EAAE,UAAU,CAAC,IAAI;YACrB,OAAO,EAAE,UAAU,CAAC,OAAO;YAC3B,MAAM,EAAE,gBAAgB;YACxB,UAAU,EACR,UAAU,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;gBACzC,IAAI,EAAE,SAAS,CAAC,IAAI;gBACpB,IAAI,EAAE,SAAS,CAAC,IAAI;gBACpB,OAAO,EAAE,SAAS,CAAC,OAAO;aAC3B,CAAC,CAAC,IAAI,EAAE;SACZ,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAOD,0DAA0D;AACnD,KAAK,UAAU,gBAAgB,CAAC,EACrC,OAAO,EACP,kBAAkB,GACA;IAClB,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAEzD,yFAAyF;IACzF,MAAM,WAAW,GAAG,kBAAkB,CAAC,gBAAgB;QACrD,CAAC,CAAC,CAAC,kBAAkB,CAAC,gBAAgB,EAAE,GAAG,kBAAkB,CAAC,WAAW,CAAC;QAC1E,CAAC,CAAC,kBAAkB,CAAC,WAAW,CAAC;IAEnC,OAAO,IAAA,wCAAyB,EAC9B,IAAA,qCAAsB,EACpB,MAAM,OAAO,CAAC,GAAG,CAAC;QAChB,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,IAAA,2CAA4B,EAAC,UAAU,CAAC,CAAC;QAC5E,IAAA,0CAA2B,EAAC,OAAO,CAAC;KACrC,CAAC,CACH,EACD,CAAC,UAAU,EAAE,EAAE,CAAC,iBAAiB,CAAC,UAAU,EAAE,kBAAkB,CAAC,QAAQ,EAAE,YAAY,CAAC,CACzF,CAAC;AACJ,CAAC","sourcesContent":["import { discoverExpoModuleConfigAsync } from '../ExpoModuleConfig';\nimport { AutolinkingOptions } from '../commands/autolinkingOptions';\nimport {\n type DependencyResolution,\n scanDependenciesRecursively,\n scanDependenciesInSearchPath,\n filterMapResolutionResult,\n mergeResolutionResults,\n} from '../dependencies';\nimport { PackageRevision, SearchResults, SupportedPlatform } from '../types';\n\nexport async function resolveExpoModule(\n resolution: DependencyResolution,\n platform: SupportedPlatform,\n excludeNames: Set\n): Promise {\n if (excludeNames.has(resolution.name)) {\n return null;\n }\n const expoModuleConfig = await discoverExpoModuleConfigAsync(resolution.path);\n if (expoModuleConfig && expoModuleConfig.supportsPlatform(platform)) {\n return {\n name: resolution.name,\n path: resolution.path,\n version: resolution.version,\n config: expoModuleConfig,\n duplicates:\n resolution.duplicates?.map((duplicate) => ({\n name: duplicate.name,\n path: duplicate.path,\n version: duplicate.version,\n })) ?? [],\n };\n } else {\n return null;\n }\n}\n\ninterface FindModulesParams {\n appRoot: string;\n autolinkingOptions: AutolinkingOptions & { platform: SupportedPlatform };\n}\n\n/** Searches for modules to link based on given config. */\nexport async function findModulesAsync({\n appRoot,\n autolinkingOptions,\n}: FindModulesParams): Promise {\n const excludeNames = new Set(autolinkingOptions.exclude);\n\n // custom native modules should be resolved first so that they can override other modules\n const searchPaths = autolinkingOptions.nativeModulesDir\n ? [autolinkingOptions.nativeModulesDir, ...autolinkingOptions.searchPaths]\n : autolinkingOptions.searchPaths;\n\n return filterMapResolutionResult(\n mergeResolutionResults(\n await Promise.all([\n ...searchPaths.map((searchPath) => scanDependenciesInSearchPath(searchPath)),\n scanDependenciesRecursively(appRoot),\n ])\n ),\n (resolution) => resolveExpoModule(resolution, autolinkingOptions.platform, excludeNames)\n );\n}\n"]} \ No newline at end of file +{"version":3,"file":"findModules.js","sourceRoot":"","sources":["../../src/autolinking/findModules.ts"],"names":[],"mappings":";;AAYA,8CAyBC;AAQD,4CAuBC;AApED,0DAAoE;AAEpE,kDAMyB;AACzB,wCAA4C;AAGrC,KAAK,UAAU,iBAAiB,CACrC,UAAgC,EAChC,QAA2B,EAC3B,YAAyB;IAEzB,IAAI,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,gBAAgB,GAAG,MAAM,IAAA,gDAA6B,EAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAC9E,IAAI,gBAAgB,IAAI,gBAAgB,CAAC,gBAAgB,CAAC,QAAQ,CAAC,EAAE,CAAC;QACpE,OAAO;YACL,IAAI,EAAE,UAAU,CAAC,IAAI;YACrB,IAAI,EAAE,UAAU,CAAC,IAAI;YACrB,OAAO,EAAE,UAAU,CAAC,OAAO;YAC3B,MAAM,EAAE,gBAAgB;YACxB,UAAU,EACR,UAAU,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;gBACzC,IAAI,EAAE,SAAS,CAAC,IAAI;gBACpB,IAAI,EAAE,SAAS,CAAC,IAAI;gBACpB,OAAO,EAAE,SAAS,CAAC,OAAO;aAC3B,CAAC,CAAC,IAAI,EAAE;SACZ,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAOD,0DAA0D;AACnD,KAAK,UAAU,gBAAgB,CAAC,EACrC,OAAO,EACP,kBAAkB,GACA;IAClB,MAAM,QAAQ,GAAG,IAAA,wBAAc,GAAE,CAAC;IAClC,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAEzD,yFAAyF;IACzF,MAAM,WAAW,GAAG,kBAAkB,CAAC,gBAAgB;QACrD,CAAC,CAAC,CAAC,kBAAkB,CAAC,gBAAgB,EAAE,GAAG,kBAAkB,CAAC,WAAW,CAAC;QAC1E,CAAC,CAAC,kBAAkB,CAAC,WAAW,CAAC;IAEnC,OAAO,QAAQ,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE;QACtC,OAAO,IAAA,wCAAyB,EAC9B,IAAA,qCAAsB,EACpB,MAAM,OAAO,CAAC,GAAG,CAAC;YAChB,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,IAAA,2CAA4B,EAAC,UAAU,CAAC,CAAC;YAC5E,IAAA,0CAA2B,EAAC,OAAO,CAAC;SACrC,CAAC,CACH,EACD,CAAC,UAAU,EAAE,EAAE,CAAC,iBAAiB,CAAC,UAAU,EAAE,kBAAkB,CAAC,QAAQ,EAAE,YAAY,CAAC,CACzF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { discoverExpoModuleConfigAsync } from '../ExpoModuleConfig';\nimport { AutolinkingOptions } from '../commands/autolinkingOptions';\nimport {\n type DependencyResolution,\n scanDependenciesRecursively,\n scanDependenciesInSearchPath,\n filterMapResolutionResult,\n mergeResolutionResults,\n} from '../dependencies';\nimport { createMemoizer } from '../memoize';\nimport { PackageRevision, SearchResults, SupportedPlatform } from '../types';\n\nexport async function resolveExpoModule(\n resolution: DependencyResolution,\n platform: SupportedPlatform,\n excludeNames: Set\n): Promise {\n if (excludeNames.has(resolution.name)) {\n return null;\n }\n const expoModuleConfig = await discoverExpoModuleConfigAsync(resolution.path);\n if (expoModuleConfig && expoModuleConfig.supportsPlatform(platform)) {\n return {\n name: resolution.name,\n path: resolution.path,\n version: resolution.version,\n config: expoModuleConfig,\n duplicates:\n resolution.duplicates?.map((duplicate) => ({\n name: duplicate.name,\n path: duplicate.path,\n version: duplicate.version,\n })) ?? [],\n };\n } else {\n return null;\n }\n}\n\ninterface FindModulesParams {\n appRoot: string;\n autolinkingOptions: AutolinkingOptions & { platform: SupportedPlatform };\n}\n\n/** Searches for modules to link based on given config. */\nexport async function findModulesAsync({\n appRoot,\n autolinkingOptions,\n}: FindModulesParams): Promise {\n const memoizer = createMemoizer();\n const excludeNames = new Set(autolinkingOptions.exclude);\n\n // custom native modules should be resolved first so that they can override other modules\n const searchPaths = autolinkingOptions.nativeModulesDir\n ? [autolinkingOptions.nativeModulesDir, ...autolinkingOptions.searchPaths]\n : autolinkingOptions.searchPaths;\n\n return memoizer.withMemoizer(async () => {\n return filterMapResolutionResult(\n mergeResolutionResults(\n await Promise.all([\n ...searchPaths.map((searchPath) => scanDependenciesInSearchPath(searchPath)),\n scanDependenciesRecursively(appRoot),\n ])\n ),\n (resolution) => resolveExpoModule(resolution, autolinkingOptions.platform, excludeNames)\n );\n });\n}\n"]} \ No newline at end of file diff --git a/packages/expo-modules-autolinking/build/autolinking/resolveModules.js b/packages/expo-modules-autolinking/build/autolinking/resolveModules.js index 20dced0ad7e6c4..2b34a6ef99ea13 100644 --- a/packages/expo-modules-autolinking/build/autolinking/resolveModules.js +++ b/packages/expo-modules-autolinking/build/autolinking/resolveModules.js @@ -2,13 +2,14 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.resolveModulesAsync = resolveModulesAsync; exports.resolveExtraBuildDependenciesAsync = resolveExtraBuildDependenciesAsync; +const concurrency_1 = require("../concurrency"); const platforms_1 = require("../platforms"); /** Resolves search results to a list of platform-specific configuration. */ async function resolveModulesAsync(searchResults, autolinkingOptions) { const platformLinking = (0, platforms_1.getLinkingImplementationForPlatform)(autolinkingOptions.platform); // Additional output property for Cocoapods flags const extraOutput = { flags: autolinkingOptions.flags }; - const moduleDescriptorList = await Promise.all(Object.entries(searchResults).map(async ([packageName, revision]) => { + const moduleDescriptorList = await (0, concurrency_1.taskAll)(Object.entries(searchResults), async ([packageName, revision]) => { const resolvedModule = await platformLinking.resolveModuleAsync(packageName, revision, extraOutput); return resolvedModule ? { @@ -17,7 +18,7 @@ async function resolveModulesAsync(searchResults, autolinkingOptions) { packageName: resolvedModule.packageName ?? packageName, } : null; - })); + }); return moduleDescriptorList .filter((moduleDescriptor) => moduleDescriptor != null) .sort((a, b) => a.packageName.localeCompare(b.packageName)); diff --git a/packages/expo-modules-autolinking/build/autolinking/resolveModules.js.map b/packages/expo-modules-autolinking/build/autolinking/resolveModules.js.map index f8969869d184af..d9ac2a98209817 100644 --- a/packages/expo-modules-autolinking/build/autolinking/resolveModules.js.map +++ b/packages/expo-modules-autolinking/build/autolinking/resolveModules.js.map @@ -1 +1 @@ -{"version":3,"file":"resolveModules.js","sourceRoot":"","sources":["../../src/autolinking/resolveModules.ts"],"names":[],"mappings":";;AAUA,kDA4BC;AAQD,gFAYC;AAzDD,4CAAmE;AAQnE,4EAA4E;AACrE,KAAK,UAAU,mBAAmB,CACvC,aAA4B,EAC5B,kBAAwE;IAExE,MAAM,eAAe,GAAG,IAAA,+CAAmC,EAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IACzF,iDAAiD;IACjD,MAAM,WAAW,GAAG,EAAE,KAAK,EAAE,kBAAkB,CAAC,KAAK,EAAE,CAAC;IAExD,MAAM,oBAAoB,GAAG,MAAM,OAAO,CAAC,GAAG,CAC5C,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,QAAQ,CAAC,EAAE,EAAE;QAClE,MAAM,cAAc,GAAG,MAAM,eAAe,CAAC,kBAAkB,CAC7D,WAAW,EACX,QAAQ,EACR,WAAW,CACZ,CAAC;QACF,OAAO,cAAc;YACnB,CAAC,CAAC;gBACE,GAAG,cAAc;gBACjB,cAAc,EAAE,QAAQ,CAAC,OAAO;gBAChC,WAAW,EAAE,cAAc,CAAC,WAAW,IAAI,WAAW;aACvD;YACH,CAAC,CAAC,IAAI,CAAC;IACX,CAAC,CAAC,CACH,CAAC;IAEF,OAAO,oBAAoB;SACxB,MAAM,CAAC,CAAC,gBAAgB,EAAE,EAAE,CAAC,gBAAgB,IAAI,IAAI,CAAC;SACtD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;AAChE,CAAC;AAOD,sHAAsH;AAC/G,KAAK,UAAU,kCAAkC,CAAC,EACvD,WAAW,EACX,QAAQ,GAC4B;IACpC,MAAM,eAAe,GAAG,IAAA,+CAAmC,EAAC,QAAQ,CAAC,CAAC;IACtE,MAAM,iBAAiB,GAAG,MAAM,eAAe,CAAC,kCAAkC;IAChF,2DAA2D;IAC3D,oGAAoG;IACpG,iCAAiC;IACjC,WAAW,CACZ,CAAC;IACF,OAAO,iBAAiB,IAAI,EAAE,CAAC;AACjC,CAAC","sourcesContent":["import { AutolinkingOptions } from '../commands/autolinkingOptions';\nimport { getLinkingImplementationForPlatform } from '../platforms';\nimport type {\n ExtraDependencies,\n ModuleDescriptor,\n SearchResults,\n SupportedPlatform,\n} from '../types';\n\n/** Resolves search results to a list of platform-specific configuration. */\nexport async function resolveModulesAsync(\n searchResults: SearchResults,\n autolinkingOptions: AutolinkingOptions & { platform: SupportedPlatform }\n): Promise {\n const platformLinking = getLinkingImplementationForPlatform(autolinkingOptions.platform);\n // Additional output property for Cocoapods flags\n const extraOutput = { flags: autolinkingOptions.flags };\n\n const moduleDescriptorList = await Promise.all(\n Object.entries(searchResults).map(async ([packageName, revision]) => {\n const resolvedModule = await platformLinking.resolveModuleAsync(\n packageName,\n revision,\n extraOutput\n );\n return resolvedModule\n ? {\n ...resolvedModule,\n packageVersion: revision.version,\n packageName: resolvedModule.packageName ?? packageName,\n }\n : null;\n })\n );\n\n return moduleDescriptorList\n .filter((moduleDescriptor) => moduleDescriptor != null)\n .sort((a, b) => a.packageName.localeCompare(b.packageName));\n}\n\ninterface ResolveExtraBuildDependenciesParams {\n commandRoot: string;\n platform: SupportedPlatform;\n}\n\n/** Resolves the extra build dependencies for the project, such as additional Maven repositories or CocoaPods pods. */\nexport async function resolveExtraBuildDependenciesAsync({\n commandRoot,\n platform,\n}: ResolveExtraBuildDependenciesParams): Promise {\n const platformLinking = getLinkingImplementationForPlatform(platform);\n const extraDependencies = await platformLinking.resolveExtraBuildDependenciesAsync(\n // NOTE: We assume we must be inside the native folder here\n // The `resolve` command either is invoked in the CWD of `./{android,ios}` or has a `--project-root`\n // that's in the native directory\n commandRoot\n );\n return extraDependencies ?? [];\n}\n"]} \ No newline at end of file +{"version":3,"file":"resolveModules.js","sourceRoot":"","sources":["../../src/autolinking/resolveModules.ts"],"names":[],"mappings":";;AAWA,kDA6BC;AAQD,gFAYC;AA3DD,gDAAyC;AACzC,4CAAmE;AAQnE,4EAA4E;AACrE,KAAK,UAAU,mBAAmB,CACvC,aAA4B,EAC5B,kBAAwE;IAExE,MAAM,eAAe,GAAG,IAAA,+CAAmC,EAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IACzF,iDAAiD;IACjD,MAAM,WAAW,GAAG,EAAE,KAAK,EAAE,kBAAkB,CAAC,KAAK,EAAE,CAAC;IAExD,MAAM,oBAAoB,GAAG,MAAM,IAAA,qBAAO,EACxC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,EAC7B,KAAK,EAAE,CAAC,WAAW,EAAE,QAAQ,CAAC,EAAE,EAAE;QAChC,MAAM,cAAc,GAAG,MAAM,eAAe,CAAC,kBAAkB,CAC7D,WAAW,EACX,QAAQ,EACR,WAAW,CACZ,CAAC;QACF,OAAO,cAAc;YACnB,CAAC,CAAC;gBACE,GAAG,cAAc;gBACjB,cAAc,EAAE,QAAQ,CAAC,OAAO;gBAChC,WAAW,EAAE,cAAc,CAAC,WAAW,IAAI,WAAW;aACvD;YACH,CAAC,CAAC,IAAI,CAAC;IACX,CAAC,CACF,CAAC;IAEF,OAAO,oBAAoB;SACxB,MAAM,CAAC,CAAC,gBAAgB,EAAE,EAAE,CAAC,gBAAgB,IAAI,IAAI,CAAC;SACtD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;AAChE,CAAC;AAOD,sHAAsH;AAC/G,KAAK,UAAU,kCAAkC,CAAC,EACvD,WAAW,EACX,QAAQ,GAC4B;IACpC,MAAM,eAAe,GAAG,IAAA,+CAAmC,EAAC,QAAQ,CAAC,CAAC;IACtE,MAAM,iBAAiB,GAAG,MAAM,eAAe,CAAC,kCAAkC;IAChF,2DAA2D;IAC3D,oGAAoG;IACpG,iCAAiC;IACjC,WAAW,CACZ,CAAC;IACF,OAAO,iBAAiB,IAAI,EAAE,CAAC;AACjC,CAAC","sourcesContent":["import { AutolinkingOptions } from '../commands/autolinkingOptions';\nimport { taskAll } from '../concurrency';\nimport { getLinkingImplementationForPlatform } from '../platforms';\nimport type {\n ExtraDependencies,\n ModuleDescriptor,\n SearchResults,\n SupportedPlatform,\n} from '../types';\n\n/** Resolves search results to a list of platform-specific configuration. */\nexport async function resolveModulesAsync(\n searchResults: SearchResults,\n autolinkingOptions: AutolinkingOptions & { platform: SupportedPlatform }\n): Promise {\n const platformLinking = getLinkingImplementationForPlatform(autolinkingOptions.platform);\n // Additional output property for Cocoapods flags\n const extraOutput = { flags: autolinkingOptions.flags };\n\n const moduleDescriptorList = await taskAll(\n Object.entries(searchResults),\n async ([packageName, revision]) => {\n const resolvedModule = await platformLinking.resolveModuleAsync(\n packageName,\n revision,\n extraOutput\n );\n return resolvedModule\n ? {\n ...resolvedModule,\n packageVersion: revision.version,\n packageName: resolvedModule.packageName ?? packageName,\n }\n : null;\n }\n );\n\n return moduleDescriptorList\n .filter((moduleDescriptor) => moduleDescriptor != null)\n .sort((a, b) => a.packageName.localeCompare(b.packageName));\n}\n\ninterface ResolveExtraBuildDependenciesParams {\n commandRoot: string;\n platform: SupportedPlatform;\n}\n\n/** Resolves the extra build dependencies for the project, such as additional Maven repositories or CocoaPods pods. */\nexport async function resolveExtraBuildDependenciesAsync({\n commandRoot,\n platform,\n}: ResolveExtraBuildDependenciesParams): Promise {\n const platformLinking = getLinkingImplementationForPlatform(platform);\n const extraDependencies = await platformLinking.resolveExtraBuildDependenciesAsync(\n // NOTE: We assume we must be inside the native folder here\n // The `resolve` command either is invoked in the CWD of `./{android,ios}` or has a `--project-root`\n // that's in the native directory\n commandRoot\n );\n return extraDependencies ?? [];\n}\n"]} \ No newline at end of file diff --git a/packages/expo-modules-autolinking/build/concurrency.d.ts b/packages/expo-modules-autolinking/build/concurrency.d.ts new file mode 100644 index 00000000000000..a6dda83f309bd1 --- /dev/null +++ b/packages/expo-modules-autolinking/build/concurrency.d.ts @@ -0,0 +1,5 @@ +export interface Limiter { + (fn: (...args: Arguments) => PromiseLike | ReturnType, ...args: Arguments): Promise; +} +export declare const createLimiter: (limit: number) => Limiter; +export declare const taskAll: (inputs: T[], map: (input: T) => Promise) => Promise; diff --git a/packages/expo-modules-autolinking/build/concurrency.js b/packages/expo-modules-autolinking/build/concurrency.js new file mode 100644 index 00000000000000..159df667f230ba --- /dev/null +++ b/packages/expo-modules-autolinking/build/concurrency.js @@ -0,0 +1,59 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.taskAll = exports.createLimiter = void 0; +const createLimiter = (limit) => { + let running = 0; + let head = null; + let tail = null; + const enqueue = () => new Promise((resolve) => { + const item = { resolve, next: null }; + if (tail) { + tail.next = item; + tail = item; + } + else { + head = item; + tail = item; + } + }); + const dequeue = () => { + if (running < limit && head !== null) { + const { resolve, next } = head; + head.next = null; + head = next; + if (head === null) { + tail = null; + } + running++; + resolve(); + } + }; + return async (fn, ...args) => { + if (running < limit) { + running++; + } + else { + await enqueue(); + } + try { + return await fn(...args); + } + finally { + running--; + dequeue(); + } + }; +}; +exports.createLimiter = createLimiter; +const taskAll = (inputs, map) => { + // NOTE: This doesn't depend on CPU cores, but instead is hard-coded depending on + // number of concurrent IO-bound tasks. `taskAll` can be called concurrently, and + // we don't keep track of concurrent `taskAll` calls in expo-modules-autolinking. + // There's a fixed number of concurrent pending IO operations that Node.js handles + // nicely. It seems that expo-modules-autolinking behaves nicely when this number + // is around ~8, but this may be higher if disk + core speed is higher. + const limiter = (0, exports.createLimiter)(8); + return Promise.all(inputs.map((input) => limiter(map, input))); +}; +exports.taskAll = taskAll; +//# sourceMappingURL=concurrency.js.map \ No newline at end of file diff --git a/packages/expo-modules-autolinking/build/concurrency.js.map b/packages/expo-modules-autolinking/build/concurrency.js.map new file mode 100644 index 00000000000000..dbfbab3adbf92c --- /dev/null +++ b/packages/expo-modules-autolinking/build/concurrency.js.map @@ -0,0 +1 @@ +{"version":3,"file":"concurrency.js","sourceRoot":"","sources":["../src/concurrency.ts"],"names":[],"mappings":";;;AAYO,MAAM,aAAa,GAAG,CAAC,KAAa,EAAW,EAAE;IACtD,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,IAAI,GAAqB,IAAI,CAAC;IAClC,IAAI,IAAI,GAAqB,IAAI,CAAC;IAElC,MAAM,OAAO,GAAG,GAAG,EAAE,CACnB,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;QAC5B,MAAM,IAAI,GAAc,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QAChD,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;YACjB,IAAI,GAAG,IAAI,CAAC;QACd,CAAC;aAAM,CAAC;YACN,IAAI,GAAG,IAAI,CAAC;YACZ,IAAI,GAAG,IAAI,CAAC;QACd,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,MAAM,OAAO,GAAG,GAAG,EAAE;QACnB,IAAI,OAAO,GAAG,KAAK,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YACrC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;YAC/B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;YACjB,IAAI,GAAG,IAAI,CAAC;YACZ,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;gBAClB,IAAI,GAAG,IAAI,CAAC;YACd,CAAC;YACD,OAAO,EAAE,CAAC;YACV,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,KAAK,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE;QAC3B,IAAI,OAAO,GAAG,KAAK,EAAE,CAAC;YACpB,OAAO,EAAE,CAAC;QACZ,CAAC;aAAM,CAAC;YACN,MAAM,OAAO,EAAE,CAAC;QAClB,CAAC;QACD,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;QAC3B,CAAC;gBAAS,CAAC;YACT,OAAO,EAAE,CAAC;YACV,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC,CAAC;AACJ,CAAC,CAAC;AA3CW,QAAA,aAAa,iBA2CxB;AAEK,MAAM,OAAO,GAAG,CAAO,MAAW,EAAE,GAA6B,EAAgB,EAAE;IACxF,iFAAiF;IACjF,iFAAiF;IACjF,iFAAiF;IACjF,kFAAkF;IAClF,iFAAiF;IACjF,uEAAuE;IACvE,MAAM,OAAO,GAAG,IAAA,qBAAa,EAAC,CAAC,CAAC,CAAC;IACjC,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;AACjE,CAAC,CAAC;AATW,QAAA,OAAO,WASlB","sourcesContent":["export interface Limiter {\n (\n fn: (...args: Arguments) => PromiseLike | ReturnType,\n ...args: Arguments\n ): Promise;\n}\n\ninterface QueueItem {\n resolve(): void;\n next: QueueItem | null;\n}\n\nexport const createLimiter = (limit: number): Limiter => {\n let running = 0;\n let head: QueueItem | null = null;\n let tail: QueueItem | null = null;\n\n const enqueue = () =>\n new Promise((resolve) => {\n const item: QueueItem = { resolve, next: null };\n if (tail) {\n tail.next = item;\n tail = item;\n } else {\n head = item;\n tail = item;\n }\n });\n\n const dequeue = () => {\n if (running < limit && head !== null) {\n const { resolve, next } = head;\n head.next = null;\n head = next;\n if (head === null) {\n tail = null;\n }\n running++;\n resolve();\n }\n };\n\n return async (fn, ...args) => {\n if (running < limit) {\n running++;\n } else {\n await enqueue();\n }\n try {\n return await fn(...args);\n } finally {\n running--;\n dequeue();\n }\n };\n};\n\nexport const taskAll = (inputs: T[], map: (input: T) => Promise): Promise => {\n // NOTE: This doesn't depend on CPU cores, but instead is hard-coded depending on\n // number of concurrent IO-bound tasks. `taskAll` can be called concurrently, and\n // we don't keep track of concurrent `taskAll` calls in expo-modules-autolinking.\n // There's a fixed number of concurrent pending IO operations that Node.js handles\n // nicely. It seems that expo-modules-autolinking behaves nicely when this number\n // is around ~8, but this may be higher if disk + core speed is higher.\n const limiter = createLimiter(8);\n return Promise.all(inputs.map((input) => limiter(map, input)));\n};\n"]} \ No newline at end of file diff --git a/packages/expo-modules-autolinking/build/dependencies/CachedDependenciesLinker.d.ts b/packages/expo-modules-autolinking/build/dependencies/CachedDependenciesLinker.d.ts index 975b6bd6e9b51b..74ad968e852a02 100644 --- a/packages/expo-modules-autolinking/build/dependencies/CachedDependenciesLinker.d.ts +++ b/packages/expo-modules-autolinking/build/dependencies/CachedDependenciesLinker.d.ts @@ -1,11 +1,13 @@ import { PackageRevision, SupportedPlatform } from '../types'; import { type ResolutionResult } from './types'; +import { type Memoizer } from '../memoize'; import { RNConfigReactNativeProjectConfig } from '../reactNativeConfig'; export interface CachedDependenciesSearchOptions { excludeNames: Set; searchPaths: string[]; } export interface CachedDependenciesLinker { + memoizer: Memoizer; getOptionsForPlatform(platform: SupportedPlatform): Promise; loadReactNativeProjectConfig(): Promise; scanDependenciesFromRNProjectConfig(): Promise; diff --git a/packages/expo-modules-autolinking/build/dependencies/CachedDependenciesLinker.js b/packages/expo-modules-autolinking/build/dependencies/CachedDependenciesLinker.js index 8a53754f615863..a7c36078b2277d 100644 --- a/packages/expo-modules-autolinking/build/dependencies/CachedDependenciesLinker.js +++ b/packages/expo-modules-autolinking/build/dependencies/CachedDependenciesLinker.js @@ -13,9 +13,11 @@ const scanning_1 = require("./scanning"); const utils_1 = require("./utils"); const findModules_1 = require("../autolinking/findModules"); const autolinkingOptions_1 = require("../commands/autolinkingOptions"); +const memoize_1 = require("../memoize"); const reactNativeConfig_1 = require("../reactNativeConfig"); const config_1 = require("../reactNativeConfig/config"); function makeCachedDependenciesLinker(params) { + const memoizer = (0, memoize_1.createMemoizer)(); const autolinkingOptionsLoader = (0, autolinkingOptions_1.createAutolinkingOptionsLoader)({ projectRoot: params.projectRoot, }); @@ -26,29 +28,37 @@ function makeCachedDependenciesLinker(params) { let reactNativeProjectConfigDependencies; let recursiveDependencies; return { + memoizer, async getOptionsForPlatform(platform) { const options = await autolinkingOptionsLoader.getPlatformOptions(platform); return makeCachedDependenciesSearchOptions(options); }, async loadReactNativeProjectConfig() { if (reactNativeProjectConfig === undefined) { - reactNativeProjectConfig = (0, config_1.loadConfigAsync)(await getAppRoot()); + reactNativeProjectConfig = memoizer.call(config_1.loadConfigAsync, await getAppRoot()); } return reactNativeProjectConfig; }, async scanDependenciesFromRNProjectConfig() { - const reactNativeProjectConfig = await this.loadReactNativeProjectConfig(); - return (reactNativeProjectConfigDependencies || - (reactNativeProjectConfigDependencies = (0, rncliLocal_1.scanDependenciesFromRNProjectConfig)(await getAppRoot(), reactNativeProjectConfig))); + if (reactNativeProjectConfigDependencies === undefined) { + reactNativeProjectConfigDependencies = memoizer.withMemoizer(async () => { + return await (0, rncliLocal_1.scanDependenciesFromRNProjectConfig)(await getAppRoot(), await this.loadReactNativeProjectConfig()); + }); + } + return reactNativeProjectConfigDependencies; }, async scanDependenciesRecursively() { - return (recursiveDependencies || - (recursiveDependencies = (0, resolution_1.scanDependenciesRecursively)(await getAppRoot()))); + if (recursiveDependencies === undefined) { + recursiveDependencies = memoizer.withMemoizer(async () => { + return (0, resolution_1.scanDependenciesRecursively)(await getAppRoot()); + }); + } + return recursiveDependencies; }, async scanDependenciesInSearchPath(searchPath) { let result = dependenciesResultBySearchPath.get(searchPath); if (!result) { - dependenciesResultBySearchPath.set(searchPath, (result = (0, scanning_1.scanDependenciesInSearchPath)(searchPath))); + dependenciesResultBySearchPath.set(searchPath, (result = memoizer.withMemoizer(scanning_1.scanDependenciesInSearchPath, searchPath))); } return result; }, @@ -65,33 +75,35 @@ async function scanDependencyResolutionsForPlatform(linker, platform, include) { }), linker.scanDependenciesRecursively(), ])); - const dependencies = await (0, utils_1.filterMapResolutionResult)(resolutions, async (resolution) => { - if (excludeNames.has(resolution.name)) { - return null; - } - else if (includeNames.has(resolution.name)) { - return resolution; - } - else if (resolution.source === 2 /* DependencyResolutionSource.RN_CLI_LOCAL */) { - // If the dependency was resolved frpom the React Native project config, we'll only - // attempt to resolve it as a React Native module - const reactNativeModuleDesc = await (0, reactNativeConfig_1.resolveReactNativeModule)(resolution, reactNativeProjectConfig, platform, excludeNames); - if (!reactNativeModuleDesc) { + return await linker.memoizer.withMemoizer(async () => { + const dependencies = await (0, utils_1.filterMapResolutionResult)(resolutions, async (resolution) => { + if (excludeNames.has(resolution.name)) { return null; } - } - else { - const [reactNativeModule, expoModule] = await Promise.all([ - (0, reactNativeConfig_1.resolveReactNativeModule)(resolution, reactNativeProjectConfig, platform, excludeNames), - (0, findModules_1.resolveExpoModule)(resolution, platform, excludeNames), - ]); - if (!reactNativeModule && !expoModule) { - return null; + else if (includeNames.has(resolution.name)) { + return resolution; } - } - return resolution; + else if (resolution.source === 2 /* DependencyResolutionSource.RN_CLI_LOCAL */) { + // If the dependency was resolved frpom the React Native project config, we'll only + // attempt to resolve it as a React Native module + const reactNativeModuleDesc = await (0, reactNativeConfig_1.resolveReactNativeModule)(resolution, reactNativeProjectConfig, platform, excludeNames); + if (!reactNativeModuleDesc) { + return null; + } + } + else { + const [reactNativeModule, expoModule] = await Promise.all([ + (0, reactNativeConfig_1.resolveReactNativeModule)(resolution, reactNativeProjectConfig, platform, excludeNames), + (0, findModules_1.resolveExpoModule)(resolution, platform, excludeNames), + ]); + if (!reactNativeModule && !expoModule) { + return null; + } + } + return resolution; + }); + return dependencies; }); - return dependencies; } async function scanExpoModuleResolutionsForPlatform(linker, platform) { const { excludeNames, searchPaths } = await linker.getOptionsForPlatform(platform); @@ -101,10 +113,12 @@ async function scanExpoModuleResolutionsForPlatform(linker, platform) { }), linker.scanDependenciesRecursively(), ].filter((x) => x != null))); - return await (0, utils_1.filterMapResolutionResult)(resolutions, async (resolution) => { - return !excludeNames.has(resolution.name) - ? await (0, findModules_1.resolveExpoModule)(resolution, platform, excludeNames) - : null; + return await linker.memoizer.withMemoizer(async () => { + return await (0, utils_1.filterMapResolutionResult)(resolutions, async (resolution) => { + return !excludeNames.has(resolution.name) + ? await (0, findModules_1.resolveExpoModule)(resolution, platform, excludeNames) + : null; + }); }); } const makeCachedDependenciesSearchOptions = (options) => ({ diff --git a/packages/expo-modules-autolinking/build/dependencies/CachedDependenciesLinker.js.map b/packages/expo-modules-autolinking/build/dependencies/CachedDependenciesLinker.js.map index f31498b102ee47..fa4d1576983ad9 100644 --- a/packages/expo-modules-autolinking/build/dependencies/CachedDependenciesLinker.js.map +++ b/packages/expo-modules-autolinking/build/dependencies/CachedDependenciesLinker.js.map @@ -1 +1 @@ -{"version":3,"file":"CachedDependenciesLinker.js","sourceRoot":"","sources":["../../src/dependencies/CachedDependenciesLinker.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs';\n\nimport { PackageRevision, SupportedPlatform } from '../types';\nimport { scanDependenciesRecursively } from './resolution';\nimport { scanDependenciesFromRNProjectConfig } from './rncliLocal';\nimport { scanDependenciesInSearchPath } from './scanning';\nimport { type ResolutionResult, DependencyResolutionSource } from './types';\nimport { filterMapResolutionResult, mergeResolutionResults } from './utils';\nimport { resolveExpoModule } from '../autolinking/findModules';\nimport { AutolinkingOptions, createAutolinkingOptionsLoader } from '../commands/autolinkingOptions';\nimport { resolveReactNativeModule, RNConfigReactNativeProjectConfig } from '../reactNativeConfig';\nimport { loadConfigAsync } from '../reactNativeConfig/config';\n\nexport interface CachedDependenciesSearchOptions {\n excludeNames: Set;\n searchPaths: string[];\n}\n\nexport interface CachedDependenciesLinker {\n getOptionsForPlatform(platform: SupportedPlatform): Promise;\n loadReactNativeProjectConfig(): Promise;\n scanDependenciesFromRNProjectConfig(): Promise;\n scanDependenciesRecursively(): Promise;\n scanDependenciesInSearchPath(searchPath: string): Promise;\n}\n\nexport function makeCachedDependenciesLinker(params: {\n projectRoot: string;\n}): CachedDependenciesLinker {\n const autolinkingOptionsLoader = createAutolinkingOptionsLoader({\n projectRoot: params.projectRoot,\n });\n\n let appRoot: Promise | undefined;\n const getAppRoot = () => appRoot || (appRoot = autolinkingOptionsLoader.getAppRoot());\n\n const dependenciesResultBySearchPath = new Map>();\n let reactNativeProjectConfig: Promise | undefined;\n let reactNativeProjectConfigDependencies: Promise | undefined;\n let recursiveDependencies: Promise | undefined;\n\n return {\n async getOptionsForPlatform(platform) {\n const options = await autolinkingOptionsLoader.getPlatformOptions(platform);\n return makeCachedDependenciesSearchOptions(options);\n },\n async loadReactNativeProjectConfig() {\n if (reactNativeProjectConfig === undefined) {\n reactNativeProjectConfig = loadConfigAsync(\n await getAppRoot()\n ) as Promise;\n }\n return reactNativeProjectConfig;\n },\n async scanDependenciesFromRNProjectConfig() {\n const reactNativeProjectConfig = await this.loadReactNativeProjectConfig();\n return (\n reactNativeProjectConfigDependencies ||\n (reactNativeProjectConfigDependencies = scanDependenciesFromRNProjectConfig(\n await getAppRoot(),\n reactNativeProjectConfig\n ))\n );\n },\n async scanDependenciesRecursively() {\n return (\n recursiveDependencies ||\n (recursiveDependencies = scanDependenciesRecursively(await getAppRoot()))\n );\n },\n async scanDependenciesInSearchPath(searchPath: string) {\n let result = dependenciesResultBySearchPath.get(searchPath);\n if (!result) {\n dependenciesResultBySearchPath.set(\n searchPath,\n (result = scanDependenciesInSearchPath(searchPath))\n );\n }\n return result;\n },\n };\n}\n\nexport async function scanDependencyResolutionsForPlatform(\n linker: CachedDependenciesLinker,\n platform: SupportedPlatform,\n include?: string[]\n): Promise {\n const { excludeNames, searchPaths } = await linker.getOptionsForPlatform(platform);\n const includeNames = new Set(include);\n const reactNativeProjectConfig = await linker.loadReactNativeProjectConfig();\n\n const resolutions = mergeResolutionResults(\n await Promise.all([\n linker.scanDependenciesFromRNProjectConfig(),\n ...searchPaths.map((searchPath) => {\n return linker.scanDependenciesInSearchPath(searchPath);\n }),\n linker.scanDependenciesRecursively(),\n ])\n );\n\n const dependencies = await filterMapResolutionResult(resolutions, async (resolution) => {\n if (excludeNames.has(resolution.name)) {\n return null;\n } else if (includeNames.has(resolution.name)) {\n return resolution;\n } else if (resolution.source === DependencyResolutionSource.RN_CLI_LOCAL) {\n // If the dependency was resolved frpom the React Native project config, we'll only\n // attempt to resolve it as a React Native module\n const reactNativeModuleDesc = await resolveReactNativeModule(\n resolution,\n reactNativeProjectConfig,\n platform,\n excludeNames\n );\n if (!reactNativeModuleDesc) {\n return null;\n }\n } else {\n const [reactNativeModule, expoModule] = await Promise.all([\n resolveReactNativeModule(resolution, reactNativeProjectConfig, platform, excludeNames),\n resolveExpoModule(resolution, platform, excludeNames),\n ]);\n if (!reactNativeModule && !expoModule) {\n return null;\n }\n }\n return resolution;\n });\n\n return dependencies;\n}\n\nexport async function scanExpoModuleResolutionsForPlatform(\n linker: CachedDependenciesLinker,\n platform: SupportedPlatform\n): Promise> {\n const { excludeNames, searchPaths } = await linker.getOptionsForPlatform(platform);\n const resolutions = mergeResolutionResults(\n await Promise.all(\n [\n ...searchPaths.map((searchPath) => {\n return linker.scanDependenciesInSearchPath(searchPath);\n }),\n linker.scanDependenciesRecursively(),\n ].filter((x) => x != null)\n )\n );\n return await filterMapResolutionResult(resolutions, async (resolution) => {\n return !excludeNames.has(resolution.name)\n ? await resolveExpoModule(resolution, platform, excludeNames)\n : null;\n });\n}\n\nconst makeCachedDependenciesSearchOptions = (options: AutolinkingOptions) => ({\n excludeNames: new Set(options.exclude),\n searchPaths:\n options.nativeModulesDir && fs.existsSync(options.nativeModulesDir)\n ? [options.nativeModulesDir, ...(options.searchPaths ?? [])]\n : (options.searchPaths ?? []),\n});\n"]} \ No newline at end of file +{"version":3,"file":"CachedDependenciesLinker.js","sourceRoot":"","sources":["../../src/dependencies/CachedDependenciesLinker.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs';\n\nimport { PackageRevision, SupportedPlatform } from '../types';\nimport { scanDependenciesRecursively } from './resolution';\nimport { scanDependenciesFromRNProjectConfig } from './rncliLocal';\nimport { scanDependenciesInSearchPath } from './scanning';\nimport { type ResolutionResult, DependencyResolutionSource } from './types';\nimport { filterMapResolutionResult, mergeResolutionResults } from './utils';\nimport { resolveExpoModule } from '../autolinking/findModules';\nimport { AutolinkingOptions, createAutolinkingOptionsLoader } from '../commands/autolinkingOptions';\nimport { createMemoizer, type Memoizer } from '../memoize';\nimport { resolveReactNativeModule, RNConfigReactNativeProjectConfig } from '../reactNativeConfig';\nimport { loadConfigAsync } from '../reactNativeConfig/config';\n\nexport interface CachedDependenciesSearchOptions {\n excludeNames: Set;\n searchPaths: string[];\n}\n\nexport interface CachedDependenciesLinker {\n memoizer: Memoizer;\n getOptionsForPlatform(platform: SupportedPlatform): Promise;\n loadReactNativeProjectConfig(): Promise;\n scanDependenciesFromRNProjectConfig(): Promise;\n scanDependenciesRecursively(): Promise;\n scanDependenciesInSearchPath(searchPath: string): Promise;\n}\n\nexport function makeCachedDependenciesLinker(params: {\n projectRoot: string;\n}): CachedDependenciesLinker {\n const memoizer = createMemoizer();\n\n const autolinkingOptionsLoader = createAutolinkingOptionsLoader({\n projectRoot: params.projectRoot,\n });\n\n let appRoot: Promise | undefined;\n const getAppRoot = () => appRoot || (appRoot = autolinkingOptionsLoader.getAppRoot());\n\n const dependenciesResultBySearchPath = new Map>();\n let reactNativeProjectConfig: Promise | undefined;\n let reactNativeProjectConfigDependencies: Promise | undefined;\n let recursiveDependencies: Promise | undefined;\n\n return {\n memoizer,\n async getOptionsForPlatform(platform) {\n const options = await autolinkingOptionsLoader.getPlatformOptions(platform);\n return makeCachedDependenciesSearchOptions(options);\n },\n async loadReactNativeProjectConfig() {\n if (reactNativeProjectConfig === undefined) {\n reactNativeProjectConfig = memoizer.call(\n loadConfigAsync,\n await getAppRoot()\n ) as Promise;\n }\n return reactNativeProjectConfig;\n },\n async scanDependenciesFromRNProjectConfig() {\n if (reactNativeProjectConfigDependencies === undefined) {\n reactNativeProjectConfigDependencies = memoizer.withMemoizer(async () => {\n return await scanDependenciesFromRNProjectConfig(\n await getAppRoot(),\n await this.loadReactNativeProjectConfig()\n );\n });\n }\n return reactNativeProjectConfigDependencies;\n },\n async scanDependenciesRecursively() {\n if (recursiveDependencies === undefined) {\n recursiveDependencies = memoizer.withMemoizer(async () => {\n return scanDependenciesRecursively(await getAppRoot());\n });\n }\n return recursiveDependencies;\n },\n async scanDependenciesInSearchPath(searchPath: string) {\n let result = dependenciesResultBySearchPath.get(searchPath);\n if (!result) {\n dependenciesResultBySearchPath.set(\n searchPath,\n (result = memoizer.withMemoizer(scanDependenciesInSearchPath, searchPath))\n );\n }\n return result;\n },\n };\n}\n\nexport async function scanDependencyResolutionsForPlatform(\n linker: CachedDependenciesLinker,\n platform: SupportedPlatform,\n include?: string[]\n): Promise {\n const { excludeNames, searchPaths } = await linker.getOptionsForPlatform(platform);\n const includeNames = new Set(include);\n const reactNativeProjectConfig = await linker.loadReactNativeProjectConfig();\n\n const resolutions = mergeResolutionResults(\n await Promise.all([\n linker.scanDependenciesFromRNProjectConfig(),\n ...searchPaths.map((searchPath) => {\n return linker.scanDependenciesInSearchPath(searchPath);\n }),\n linker.scanDependenciesRecursively(),\n ])\n );\n\n return await linker.memoizer.withMemoizer(async () => {\n const dependencies = await filterMapResolutionResult(resolutions, async (resolution) => {\n if (excludeNames.has(resolution.name)) {\n return null;\n } else if (includeNames.has(resolution.name)) {\n return resolution;\n } else if (resolution.source === DependencyResolutionSource.RN_CLI_LOCAL) {\n // If the dependency was resolved frpom the React Native project config, we'll only\n // attempt to resolve it as a React Native module\n const reactNativeModuleDesc = await resolveReactNativeModule(\n resolution,\n reactNativeProjectConfig,\n platform,\n excludeNames\n );\n if (!reactNativeModuleDesc) {\n return null;\n }\n } else {\n const [reactNativeModule, expoModule] = await Promise.all([\n resolveReactNativeModule(resolution, reactNativeProjectConfig, platform, excludeNames),\n resolveExpoModule(resolution, platform, excludeNames),\n ]);\n if (!reactNativeModule && !expoModule) {\n return null;\n }\n }\n return resolution;\n });\n\n return dependencies;\n });\n}\n\nexport async function scanExpoModuleResolutionsForPlatform(\n linker: CachedDependenciesLinker,\n platform: SupportedPlatform\n): Promise> {\n const { excludeNames, searchPaths } = await linker.getOptionsForPlatform(platform);\n const resolutions = mergeResolutionResults(\n await Promise.all(\n [\n ...searchPaths.map((searchPath) => {\n return linker.scanDependenciesInSearchPath(searchPath);\n }),\n linker.scanDependenciesRecursively(),\n ].filter((x) => x != null)\n )\n );\n return await linker.memoizer.withMemoizer(async () => {\n return await filterMapResolutionResult(resolutions, async (resolution) => {\n return !excludeNames.has(resolution.name)\n ? await resolveExpoModule(resolution, platform, excludeNames)\n : null;\n });\n });\n}\n\nconst makeCachedDependenciesSearchOptions = (options: AutolinkingOptions) => ({\n excludeNames: new Set(options.exclude),\n searchPaths:\n options.nativeModulesDir && fs.existsSync(options.nativeModulesDir)\n ? [options.nativeModulesDir, ...(options.searchPaths ?? [])]\n : (options.searchPaths ?? []),\n});\n"]} \ No newline at end of file diff --git a/packages/expo-modules-autolinking/build/dependencies/resolution.js b/packages/expo-modules-autolinking/build/dependencies/resolution.js index b7e7fd73111d77..6394337e2b340f 100644 --- a/packages/expo-modules-autolinking/build/dependencies/resolution.js +++ b/packages/expo-modules-autolinking/build/dependencies/resolution.js @@ -6,6 +6,8 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.scanDependenciesRecursively = scanDependenciesRecursively; const node_module_1 = __importDefault(require("node:module")); const utils_1 = require("./utils"); +const concurrency_1 = require("../concurrency"); +const utils_2 = require("../utils"); // NOTE(@kitten): There's no need to search very deep for modules // We don't expect native modules to be excessively nested in the dependency tree const MAX_DEPTH = 8; @@ -18,7 +20,7 @@ const createNodeModulePathsCreator = () => { const nodeModulePath = nodeModulePaths[idx]; let target = _nodeModulePathCache.get(nodeModulePath); if (target === undefined) { - target = await (0, utils_1.maybeRealpath)(nodeModulePath); + target = await (0, utils_2.maybeRealpath)(nodeModulePath); if (idx !== 0) { _nodeModulePathCache.set(nodeModulePath, target); } @@ -57,8 +59,8 @@ async function resolveDependencies(packageJson, nodeModulePaths, depth, shouldIn } const resolveDependency = async (dependencyName) => { for (let idx = 0; idx < nodeModulePaths.length; idx++) { - const originPath = (0, utils_1.fastJoin)(nodeModulePaths[idx], dependencyName); - const nodeModulePath = await (0, utils_1.maybeRealpath)(originPath); + const originPath = (0, utils_2.fastJoin)(nodeModulePaths[idx], dependencyName); + const nodeModulePath = await (0, utils_2.maybeRealpath)(originPath); if (nodeModulePath != null) { return { source: 0 /* DependencyResolutionSource.RECURSIVE_RESOLUTION */, @@ -73,13 +75,11 @@ async function resolveDependencies(packageJson, nodeModulePaths, depth, shouldIn } return null; }; - const modules = await Promise.all(Object.keys(dependencies) - .filter((dependencyName) => shouldIncludeDependency(dependencyName)) - .map((dependencyName) => resolveDependency(dependencyName))); + const modules = await (0, concurrency_1.taskAll)(Object.keys(dependencies).filter((dependencyName) => shouldIncludeDependency(dependencyName)), (dependencyName) => resolveDependency(dependencyName)); return modules.filter((resolution) => resolution != null); } async function scanDependenciesRecursively(rawPath, { shouldIncludeDependency = utils_1.defaultShouldIncludeDependency, limitDepth } = {}) { - const rootPath = await (0, utils_1.maybeRealpath)(rawPath); + const rootPath = await (0, utils_2.maybeRealpath)(rawPath); if (!rootPath) { return {}; } @@ -96,7 +96,7 @@ async function scanDependenciesRecursively(rawPath, { shouldIncludeDependency = } const [nodeModulePaths, packageJson] = await Promise.all([ getNodeModulePaths(resolution.path), - (0, utils_1.loadPackageJson)((0, utils_1.fastJoin)(resolution.path, 'package.json')), + (0, utils_2.loadPackageJson)((0, utils_2.fastJoin)(resolution.path, 'package.json')), ]); if (!packageJson) { return searchResults; @@ -109,7 +109,7 @@ async function scanDependenciesRecursively(rawPath, { shouldIncludeDependency = searchResults[modules[idx].name] = modules[idx]; } if (depth + 1 < maxDepth) { - const childResults = await Promise.all(modules.map((resolution) => recurse(resolution, depth + 1))); + const childResults = await (0, concurrency_1.taskAll)(modules, (resolution) => recurse(resolution, depth + 1)); return (0, utils_1.mergeResolutionResults)(childResults, searchResults); } else { diff --git a/packages/expo-modules-autolinking/build/dependencies/resolution.js.map b/packages/expo-modules-autolinking/build/dependencies/resolution.js.map index b63c6e6c0deda4..143e927d87fbd3 100644 --- a/packages/expo-modules-autolinking/build/dependencies/resolution.js.map +++ b/packages/expo-modules-autolinking/build/dependencies/resolution.js.map @@ -1 +1 @@ -{"version":3,"file":"resolution.js","sourceRoot":"","sources":["../../src/dependencies/resolution.ts"],"names":[],"mappings":"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","sourcesContent":["import Module from 'node:module';\n\nimport {\n type ResolutionResult,\n type DependencyResolution,\n DependencyResolutionSource,\n} from './types';\nimport {\n type PackageJson,\n defaultShouldIncludeDependency,\n mergeResolutionResults,\n loadPackageJson,\n maybeRealpath,\n fastJoin,\n} from './utils';\n\ndeclare module 'node:module' {\n export function _nodeModulePaths(base: string): readonly string[];\n}\n\n// NOTE(@kitten): There's no need to search very deep for modules\n// We don't expect native modules to be excessively nested in the dependency tree\nconst MAX_DEPTH = 8;\n\nconst createNodeModulePathsCreator = () => {\n const _nodeModulePathCache = new Map();\n return async function getNodeModulePaths(packagePath: string) {\n const outputPaths: string[] = [];\n const nodeModulePaths = Module._nodeModulePaths(packagePath);\n for (let idx = 0; idx < nodeModulePaths.length; idx++) {\n const nodeModulePath = nodeModulePaths[idx];\n let target = _nodeModulePathCache.get(nodeModulePath);\n if (target === undefined) {\n target = await maybeRealpath(nodeModulePath);\n if (idx !== 0) {\n _nodeModulePathCache.set(nodeModulePath, target);\n }\n }\n if (target != null) {\n outputPaths.push(target);\n }\n }\n return outputPaths;\n };\n};\n\nasync function resolveDependencies(\n packageJson: PackageJson,\n nodeModulePaths: readonly string[],\n depth: number,\n shouldIncludeDependency: (dependencyName: string) => boolean\n): Promise {\n const dependencies: Record = Object.create(null);\n if (packageJson.dependencies != null && typeof packageJson.dependencies === 'object') {\n Object.assign(dependencies, packageJson.dependencies);\n }\n // NOTE(@kitten): Also traverse devDependencies for top-level package.json\n if (\n depth === 0 &&\n packageJson.devDependencies != null &&\n typeof packageJson.devDependencies === 'object'\n ) {\n Object.assign(dependencies, packageJson.devDependencies);\n }\n if (packageJson.peerDependencies != null && typeof packageJson.peerDependencies === 'object') {\n const peerDependenciesMeta =\n packageJson.peerDependenciesMeta != null &&\n typeof packageJson.peerDependenciesMeta === 'object'\n ? (packageJson.peerDependenciesMeta as Record)\n : undefined;\n for (const dependencyName in packageJson.peerDependencies) {\n // NOTE(@kitten): We only check peer dependencies because some package managers auto-install them\n // which would mean they'd have no reference in any dependencies. However, optional peer dependencies\n // don't auto-install and we can skip them\n if (!isOptionalPeerDependencyMeta(peerDependenciesMeta, dependencyName)) {\n dependencies[dependencyName] = '';\n }\n }\n }\n\n const resolveDependency = async (\n dependencyName: string\n ): Promise => {\n for (let idx = 0; idx < nodeModulePaths.length; idx++) {\n const originPath = fastJoin(nodeModulePaths[idx], dependencyName);\n const nodeModulePath = await maybeRealpath(originPath);\n if (nodeModulePath != null) {\n return {\n source: DependencyResolutionSource.RECURSIVE_RESOLUTION,\n name: dependencyName,\n version: '',\n path: nodeModulePath,\n originPath,\n duplicates: null,\n depth,\n };\n }\n }\n return null;\n };\n\n const modules = await Promise.all(\n Object.keys(dependencies)\n .filter((dependencyName) => shouldIncludeDependency(dependencyName))\n .map((dependencyName) => resolveDependency(dependencyName))\n );\n\n return modules.filter((resolution) => resolution != null);\n}\n\ninterface ResolutionOptions {\n shouldIncludeDependency?(name: string): boolean;\n limitDepth?: number;\n}\n\nexport async function scanDependenciesRecursively(\n rawPath: string,\n { shouldIncludeDependency = defaultShouldIncludeDependency, limitDepth }: ResolutionOptions = {}\n): Promise {\n const rootPath = await maybeRealpath(rawPath);\n if (!rootPath) {\n return {};\n }\n\n const _visitedPackagePaths = new Set();\n const getNodeModulePaths = createNodeModulePathsCreator();\n const maxDepth = limitDepth != null ? limitDepth : MAX_DEPTH;\n\n const recurse = async (\n resolution: DependencyResolution,\n depth = 0\n ): Promise => {\n const searchResults: ResolutionResult = Object.create(null);\n if (_visitedPackagePaths.has(resolution.path)) {\n return searchResults;\n } else {\n _visitedPackagePaths.add(resolution.path);\n }\n const [nodeModulePaths, packageJson] = await Promise.all([\n getNodeModulePaths(resolution.path),\n loadPackageJson(fastJoin(resolution.path, 'package.json')),\n ]);\n if (!packageJson) {\n return searchResults;\n } else {\n resolution.version = packageJson.version || '';\n }\n\n const modules = await resolveDependencies(\n packageJson,\n nodeModulePaths,\n depth,\n shouldIncludeDependency\n );\n for (let idx = 0; idx < modules.length; idx++) {\n searchResults[modules[idx].name] = modules[idx];\n }\n\n if (depth + 1 < maxDepth) {\n const childResults = await Promise.all(\n modules.map((resolution) => recurse(resolution, depth + 1))\n );\n return mergeResolutionResults(childResults, searchResults);\n } else {\n return searchResults;\n }\n };\n\n const searchResults = await recurse({\n source: DependencyResolutionSource.RECURSIVE_RESOLUTION,\n name: '',\n version: '',\n path: rootPath,\n originPath: rawPath,\n duplicates: null,\n depth: -1,\n });\n\n return searchResults;\n}\n\nconst isOptionalPeerDependencyMeta = (\n peerDependenciesMeta: Record | undefined,\n packageName: string\n) => {\n return (\n peerDependenciesMeta &&\n peerDependenciesMeta[packageName] != null &&\n typeof peerDependenciesMeta[packageName] === 'object' &&\n 'optional' in peerDependenciesMeta[packageName] &&\n !!peerDependenciesMeta[packageName].optional\n );\n};\n"]} \ No newline at end of file +{"version":3,"file":"resolution.js","sourceRoot":"","sources":["../../src/dependencies/resolution.ts"],"names":[],"mappings":"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","sourcesContent":["import Module from 'node:module';\n\nimport {\n type ResolutionResult,\n type DependencyResolution,\n DependencyResolutionSource,\n} from './types';\nimport { defaultShouldIncludeDependency, mergeResolutionResults } from './utils';\nimport { taskAll } from '../concurrency';\nimport { type PackageJson, loadPackageJson, maybeRealpath, fastJoin } from '../utils';\n\ndeclare module 'node:module' {\n export function _nodeModulePaths(base: string): readonly string[];\n}\n\n// NOTE(@kitten): There's no need to search very deep for modules\n// We don't expect native modules to be excessively nested in the dependency tree\nconst MAX_DEPTH = 8;\n\nconst createNodeModulePathsCreator = () => {\n const _nodeModulePathCache = new Map();\n return async function getNodeModulePaths(packagePath: string) {\n const outputPaths: string[] = [];\n const nodeModulePaths = Module._nodeModulePaths(packagePath);\n for (let idx = 0; idx < nodeModulePaths.length; idx++) {\n const nodeModulePath = nodeModulePaths[idx];\n let target = _nodeModulePathCache.get(nodeModulePath);\n if (target === undefined) {\n target = await maybeRealpath(nodeModulePath);\n if (idx !== 0) {\n _nodeModulePathCache.set(nodeModulePath, target);\n }\n }\n if (target != null) {\n outputPaths.push(target);\n }\n }\n return outputPaths;\n };\n};\n\nasync function resolveDependencies(\n packageJson: PackageJson,\n nodeModulePaths: readonly string[],\n depth: number,\n shouldIncludeDependency: (dependencyName: string) => boolean\n): Promise {\n const dependencies: Record = Object.create(null);\n if (packageJson.dependencies != null && typeof packageJson.dependencies === 'object') {\n Object.assign(dependencies, packageJson.dependencies);\n }\n // NOTE(@kitten): Also traverse devDependencies for top-level package.json\n if (\n depth === 0 &&\n packageJson.devDependencies != null &&\n typeof packageJson.devDependencies === 'object'\n ) {\n Object.assign(dependencies, packageJson.devDependencies);\n }\n if (packageJson.peerDependencies != null && typeof packageJson.peerDependencies === 'object') {\n const peerDependenciesMeta =\n packageJson.peerDependenciesMeta != null &&\n typeof packageJson.peerDependenciesMeta === 'object'\n ? (packageJson.peerDependenciesMeta as Record)\n : undefined;\n for (const dependencyName in packageJson.peerDependencies) {\n // NOTE(@kitten): We only check peer dependencies because some package managers auto-install them\n // which would mean they'd have no reference in any dependencies. However, optional peer dependencies\n // don't auto-install and we can skip them\n if (!isOptionalPeerDependencyMeta(peerDependenciesMeta, dependencyName)) {\n dependencies[dependencyName] = '';\n }\n }\n }\n\n const resolveDependency = async (\n dependencyName: string\n ): Promise => {\n for (let idx = 0; idx < nodeModulePaths.length; idx++) {\n const originPath = fastJoin(nodeModulePaths[idx], dependencyName);\n const nodeModulePath = await maybeRealpath(originPath);\n if (nodeModulePath != null) {\n return {\n source: DependencyResolutionSource.RECURSIVE_RESOLUTION,\n name: dependencyName,\n version: '',\n path: nodeModulePath,\n originPath,\n duplicates: null,\n depth,\n };\n }\n }\n return null;\n };\n\n const modules = await taskAll(\n Object.keys(dependencies).filter((dependencyName) => shouldIncludeDependency(dependencyName)),\n (dependencyName) => resolveDependency(dependencyName)\n );\n\n return modules.filter((resolution) => resolution != null);\n}\n\ninterface ResolutionOptions {\n shouldIncludeDependency?(name: string): boolean;\n limitDepth?: number;\n}\n\nexport async function scanDependenciesRecursively(\n rawPath: string,\n { shouldIncludeDependency = defaultShouldIncludeDependency, limitDepth }: ResolutionOptions = {}\n): Promise {\n const rootPath = await maybeRealpath(rawPath);\n if (!rootPath) {\n return {};\n }\n\n const _visitedPackagePaths = new Set();\n const getNodeModulePaths = createNodeModulePathsCreator();\n const maxDepth = limitDepth != null ? limitDepth : MAX_DEPTH;\n\n const recurse = async (\n resolution: DependencyResolution,\n depth = 0\n ): Promise => {\n const searchResults: ResolutionResult = Object.create(null);\n if (_visitedPackagePaths.has(resolution.path)) {\n return searchResults;\n } else {\n _visitedPackagePaths.add(resolution.path);\n }\n const [nodeModulePaths, packageJson] = await Promise.all([\n getNodeModulePaths(resolution.path),\n loadPackageJson(fastJoin(resolution.path, 'package.json')),\n ]);\n if (!packageJson) {\n return searchResults;\n } else {\n resolution.version = packageJson.version || '';\n }\n\n const modules = await resolveDependencies(\n packageJson,\n nodeModulePaths,\n depth,\n shouldIncludeDependency\n );\n for (let idx = 0; idx < modules.length; idx++) {\n searchResults[modules[idx].name] = modules[idx];\n }\n\n if (depth + 1 < maxDepth) {\n const childResults = await taskAll(modules, (resolution) => recurse(resolution, depth + 1));\n return mergeResolutionResults(childResults, searchResults);\n } else {\n return searchResults;\n }\n };\n\n const searchResults = await recurse({\n source: DependencyResolutionSource.RECURSIVE_RESOLUTION,\n name: '',\n version: '',\n path: rootPath,\n originPath: rawPath,\n duplicates: null,\n depth: -1,\n });\n\n return searchResults;\n}\n\nconst isOptionalPeerDependencyMeta = (\n peerDependenciesMeta: Record | undefined,\n packageName: string\n) => {\n return (\n peerDependenciesMeta &&\n peerDependenciesMeta[packageName] != null &&\n typeof peerDependenciesMeta[packageName] === 'object' &&\n 'optional' in peerDependenciesMeta[packageName] &&\n !!peerDependenciesMeta[packageName].optional\n );\n};\n"]} \ No newline at end of file diff --git a/packages/expo-modules-autolinking/build/dependencies/rncliLocal.js b/packages/expo-modules-autolinking/build/dependencies/rncliLocal.js index 82084707f36525..15da7efacc4352 100644 --- a/packages/expo-modules-autolinking/build/dependencies/rncliLocal.js +++ b/packages/expo-modules-autolinking/build/dependencies/rncliLocal.js @@ -6,20 +6,19 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.scanDependenciesFromRNProjectConfig = scanDependenciesFromRNProjectConfig; const path_1 = __importDefault(require("path")); const utils_1 = require("./utils"); +const concurrency_1 = require("../concurrency"); +const utils_2 = require("../utils"); async function scanDependenciesFromRNProjectConfig(rawPath, projectConfig, { shouldIncludeDependency = utils_1.defaultShouldIncludeDependency } = {}) { - const rootPath = await (0, utils_1.maybeRealpath)(rawPath); + const rootPath = await (0, utils_2.maybeRealpath)(rawPath); const searchResults = Object.create(null); if (!rootPath || !projectConfig || !projectConfig.dependencies) { return searchResults; } - for (const dependencyName in projectConfig.dependencies) { - if (!shouldIncludeDependency(dependencyName)) { - continue; - } + await (0, concurrency_1.taskAll)(Object.keys(projectConfig.dependencies).filter((dependencyName) => shouldIncludeDependency(dependencyName)), async (dependencyName) => { const dependencyConfig = projectConfig.dependencies[dependencyName]; if (dependencyConfig && dependencyConfig.root && typeof dependencyConfig.root === 'string') { const originPath = path_1.default.resolve(rootPath, dependencyConfig.root); - const realPath = await (0, utils_1.maybeRealpath)(originPath); + const realPath = await (0, utils_2.maybeRealpath)(originPath); if (realPath) { searchResults[dependencyName] = { source: 2 /* DependencyResolutionSource.RN_CLI_LOCAL */, @@ -32,7 +31,7 @@ async function scanDependenciesFromRNProjectConfig(rawPath, projectConfig, { sho }; } } - } + }); return searchResults; } //# sourceMappingURL=rncliLocal.js.map \ No newline at end of file diff --git a/packages/expo-modules-autolinking/build/dependencies/rncliLocal.js.map b/packages/expo-modules-autolinking/build/dependencies/rncliLocal.js.map index be64d01a83f1da..ebc0f51c029b08 100644 --- a/packages/expo-modules-autolinking/build/dependencies/rncliLocal.js.map +++ b/packages/expo-modules-autolinking/build/dependencies/rncliLocal.js.map @@ -1 +1 @@ -{"version":3,"file":"rncliLocal.js","sourceRoot":"","sources":["../../src/dependencies/rncliLocal.ts"],"names":[],"mappings":";;;;;AAUA,kFAkCC;AA5CD,gDAAwB;AAGxB,mCAAwE;AAOjE,KAAK,UAAU,mCAAmC,CACvD,OAAe,EACf,aAAsD,EACtD,EAAE,uBAAuB,GAAG,sCAA8B,KAAwB,EAAE;IAEpF,MAAM,QAAQ,GAAG,MAAM,IAAA,qBAAa,EAAC,OAAO,CAAC,CAAC;IAC9C,MAAM,aAAa,GAAqB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC5D,IAAI,CAAC,QAAQ,IAAI,CAAC,aAAa,IAAI,CAAC,aAAa,CAAC,YAAY,EAAE,CAAC;QAC/D,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,KAAK,MAAM,cAAc,IAAI,aAAa,CAAC,YAAY,EAAE,CAAC;QACxD,IAAI,CAAC,uBAAuB,CAAC,cAAc,CAAC,EAAE,CAAC;YAC7C,SAAS;QACX,CAAC;QACD,MAAM,gBAAgB,GAAG,aAAa,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC;QACpE,IAAI,gBAAgB,IAAI,gBAAgB,CAAC,IAAI,IAAI,OAAO,gBAAgB,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC3F,MAAM,UAAU,GAAG,cAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,gBAAgB,CAAC,IAAI,CAAC,CAAC;YACjE,MAAM,QAAQ,GAAG,MAAM,IAAA,qBAAa,EAAC,UAAU,CAAC,CAAC;YACjD,IAAI,QAAQ,EAAE,CAAC;gBACb,aAAa,CAAC,cAAc,CAAC,GAAG;oBAC9B,MAAM,iDAAyC;oBAC/C,IAAI,EAAE,cAAc;oBACpB,OAAO,EAAE,EAAE;oBACX,IAAI,EAAE,QAAQ;oBACd,UAAU;oBACV,UAAU,EAAE,IAAI;oBAChB,KAAK,EAAE,CAAC;iBACT,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,aAAa,CAAC;AACvB,CAAC","sourcesContent":["import path from 'path';\n\nimport { DependencyResolutionSource, type ResolutionResult } from './types';\nimport { defaultShouldIncludeDependency, maybeRealpath } from './utils';\nimport { RNConfigReactNativeProjectConfig } from '../reactNativeConfig';\n\ninterface ResolutionOptions {\n shouldIncludeDependency?(name: string): boolean;\n}\n\nexport async function scanDependenciesFromRNProjectConfig(\n rawPath: string,\n projectConfig: RNConfigReactNativeProjectConfig | null,\n { shouldIncludeDependency = defaultShouldIncludeDependency }: ResolutionOptions = {}\n): Promise {\n const rootPath = await maybeRealpath(rawPath);\n const searchResults: ResolutionResult = Object.create(null);\n if (!rootPath || !projectConfig || !projectConfig.dependencies) {\n return searchResults;\n }\n\n for (const dependencyName in projectConfig.dependencies) {\n if (!shouldIncludeDependency(dependencyName)) {\n continue;\n }\n const dependencyConfig = projectConfig.dependencies[dependencyName];\n if (dependencyConfig && dependencyConfig.root && typeof dependencyConfig.root === 'string') {\n const originPath = path.resolve(rootPath, dependencyConfig.root);\n const realPath = await maybeRealpath(originPath);\n if (realPath) {\n searchResults[dependencyName] = {\n source: DependencyResolutionSource.RN_CLI_LOCAL,\n name: dependencyName,\n version: '',\n path: realPath,\n originPath,\n duplicates: null,\n depth: 0,\n };\n }\n }\n }\n\n return searchResults;\n}\n"]} \ No newline at end of file +{"version":3,"file":"rncliLocal.js","sourceRoot":"","sources":["../../src/dependencies/rncliLocal.ts"],"names":[],"mappings":";;;;;AAYA,kFAoCC;AAhDD,gDAAwB;AAGxB,mCAAyD;AACzD,gDAAyC;AAEzC,oCAAyC;AAMlC,KAAK,UAAU,mCAAmC,CACvD,OAAe,EACf,aAAsD,EACtD,EAAE,uBAAuB,GAAG,sCAA8B,KAAwB,EAAE;IAEpF,MAAM,QAAQ,GAAG,MAAM,IAAA,qBAAa,EAAC,OAAO,CAAC,CAAC;IAC9C,MAAM,aAAa,GAAqB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC5D,IAAI,CAAC,QAAQ,IAAI,CAAC,aAAa,IAAI,CAAC,aAAa,CAAC,YAAY,EAAE,CAAC;QAC/D,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,MAAM,IAAA,qBAAO,EACX,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC,cAAc,EAAE,EAAE,CAChE,uBAAuB,CAAC,cAAc,CAAC,CACxC,EACD,KAAK,EAAE,cAAc,EAAE,EAAE;QACvB,MAAM,gBAAgB,GAAG,aAAa,CAAC,YAAa,CAAC,cAAc,CAAC,CAAC;QACrE,IAAI,gBAAgB,IAAI,gBAAgB,CAAC,IAAI,IAAI,OAAO,gBAAgB,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC3F,MAAM,UAAU,GAAG,cAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,gBAAgB,CAAC,IAAI,CAAC,CAAC;YACjE,MAAM,QAAQ,GAAG,MAAM,IAAA,qBAAa,EAAC,UAAU,CAAC,CAAC;YACjD,IAAI,QAAQ,EAAE,CAAC;gBACb,aAAa,CAAC,cAAc,CAAC,GAAG;oBAC9B,MAAM,iDAAyC;oBAC/C,IAAI,EAAE,cAAc;oBACpB,OAAO,EAAE,EAAE;oBACX,IAAI,EAAE,QAAQ;oBACd,UAAU;oBACV,UAAU,EAAE,IAAI;oBAChB,KAAK,EAAE,CAAC;iBACT,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC,CACF,CAAC;IAEF,OAAO,aAAa,CAAC;AACvB,CAAC","sourcesContent":["import path from 'path';\n\nimport { DependencyResolutionSource, type ResolutionResult } from './types';\nimport { defaultShouldIncludeDependency } from './utils';\nimport { taskAll } from '../concurrency';\nimport { RNConfigReactNativeProjectConfig } from '../reactNativeConfig';\nimport { maybeRealpath } from '../utils';\n\ninterface ResolutionOptions {\n shouldIncludeDependency?(name: string): boolean;\n}\n\nexport async function scanDependenciesFromRNProjectConfig(\n rawPath: string,\n projectConfig: RNConfigReactNativeProjectConfig | null,\n { shouldIncludeDependency = defaultShouldIncludeDependency }: ResolutionOptions = {}\n): Promise {\n const rootPath = await maybeRealpath(rawPath);\n const searchResults: ResolutionResult = Object.create(null);\n if (!rootPath || !projectConfig || !projectConfig.dependencies) {\n return searchResults;\n }\n\n await taskAll(\n Object.keys(projectConfig.dependencies).filter((dependencyName) =>\n shouldIncludeDependency(dependencyName)\n ),\n async (dependencyName) => {\n const dependencyConfig = projectConfig.dependencies![dependencyName];\n if (dependencyConfig && dependencyConfig.root && typeof dependencyConfig.root === 'string') {\n const originPath = path.resolve(rootPath, dependencyConfig.root);\n const realPath = await maybeRealpath(originPath);\n if (realPath) {\n searchResults[dependencyName] = {\n source: DependencyResolutionSource.RN_CLI_LOCAL,\n name: dependencyName,\n version: '',\n path: realPath,\n originPath,\n duplicates: null,\n depth: 0,\n };\n }\n }\n }\n );\n\n return searchResults;\n}\n"]} \ No newline at end of file diff --git a/packages/expo-modules-autolinking/build/dependencies/scanning.js b/packages/expo-modules-autolinking/build/dependencies/scanning.js index c983be03f91447..0236515d1b0be5 100644 --- a/packages/expo-modules-autolinking/build/dependencies/scanning.js +++ b/packages/expo-modules-autolinking/build/dependencies/scanning.js @@ -5,18 +5,20 @@ var __importDefault = (this && this.__importDefault) || function (mod) { Object.defineProperty(exports, "__esModule", { value: true }); exports.scanDependenciesInSearchPath = scanDependenciesInSearchPath; const fs_1 = __importDefault(require("fs")); +const concurrency_1 = require("../concurrency"); const utils_1 = require("./utils"); +const utils_2 = require("../utils"); async function resolveDependency(basePath, dependencyName, shouldIncludeDependency) { if (dependencyName && !shouldIncludeDependency(dependencyName)) { return null; } - const originPath = dependencyName ? (0, utils_1.fastJoin)(basePath, dependencyName) : basePath; - const realPath = await (0, utils_1.maybeRealpath)(originPath); - const packageJson = await (0, utils_1.loadPackageJson)((0, utils_1.fastJoin)(realPath || originPath, 'package.json')); + const originPath = dependencyName ? (0, utils_2.fastJoin)(basePath, dependencyName) : basePath; + const realPath = await (0, utils_2.maybeRealpath)(originPath); + const packageJson = await (0, utils_2.loadPackageJson)((0, utils_2.fastJoin)(realPath || originPath, 'package.json')); if (packageJson) { return { source: 1 /* DependencyResolutionSource.SEARCH_PATH */, - name: packageJson.name, + name: packageJson.name || '', version: packageJson.version || '', path: realPath || originPath, originPath, @@ -40,13 +42,13 @@ async function resolveDependency(basePath, dependencyName, shouldIncludeDependen } } async function scanDependenciesInSearchPath(rawPath, { shouldIncludeDependency = utils_1.defaultShouldIncludeDependency } = {}) { - const rootPath = await (0, utils_1.maybeRealpath)(rawPath); + const rootPath = await (0, utils_2.maybeRealpath)(rawPath); const searchResults = Object.create(null); if (!rootPath) { return searchResults; } const resolvedDependencies = []; - const localModuleTarget = await (0, utils_1.maybeRealpath)((0, utils_1.fastJoin)(rootPath, 'package.json')); + const localModuleTarget = await (0, utils_2.maybeRealpath)((0, utils_2.fastJoin)(rootPath, 'package.json')); if (localModuleTarget) { // If we have a `package.json` file in the search path, we're already dealing with a node module // and can skip the rest. This is a special case created by create-expo-module's `nativeModulesDir: ../` @@ -56,7 +58,7 @@ async function scanDependenciesInSearchPath(rawPath, { shouldIncludeDependency = } else { const dirents = await fs_1.default.promises.readdir(rootPath, { withFileTypes: true }); - await Promise.all(dirents.map(async (entry) => { + await (0, concurrency_1.taskAll)(dirents, async (entry) => { if (entry.isSymbolicLink()) { const resolution = await resolveDependency(rootPath, entry.name, shouldIncludeDependency); if (resolution) @@ -71,7 +73,7 @@ async function scanDependenciesInSearchPath(rawPath, { shouldIncludeDependency = } else if (entry.name[0] === '@') { // NOTE: We don't expect @-scope folders to be symlinks - const entryPath = (0, utils_1.fastJoin)(rootPath, entry.name); + const entryPath = (0, utils_2.fastJoin)(rootPath, entry.name); const childEntries = await fs_1.default.promises.readdir(entryPath, { withFileTypes: true }); await Promise.all(childEntries.map(async (child) => { const dependencyName = `${entry.name}/${child.name}`; @@ -88,7 +90,7 @@ async function scanDependenciesInSearchPath(rawPath, { shouldIncludeDependency = resolvedDependencies.push(resolution); } } - })); + }); } for (let idx = 0; idx < resolvedDependencies.length; idx++) { const resolution = resolvedDependencies[idx]; diff --git a/packages/expo-modules-autolinking/build/dependencies/scanning.js.map b/packages/expo-modules-autolinking/build/dependencies/scanning.js.map index fdf9e6bd0d7b50..7e0f8f2a32fcad 100644 --- a/packages/expo-modules-autolinking/build/dependencies/scanning.js.map +++ b/packages/expo-modules-autolinking/build/dependencies/scanning.js.map @@ -1 +1 @@ -{"version":3,"file":"scanning.js","sourceRoot":"","sources":["../../src/dependencies/scanning.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs';\n\nimport {\n type ResolutionResult,\n type DependencyResolution,\n DependencyResolutionSource,\n} from './types';\nimport { defaultShouldIncludeDependency, loadPackageJson, maybeRealpath, fastJoin } from './utils';\n\nasync function resolveDependency(\n basePath: string,\n dependencyName: string | null,\n shouldIncludeDependency: (dependencyName: string) => boolean\n): Promise {\n if (dependencyName && !shouldIncludeDependency(dependencyName)) {\n return null;\n }\n const originPath = dependencyName ? fastJoin(basePath, dependencyName) : basePath;\n const realPath = await maybeRealpath(originPath);\n const packageJson = await loadPackageJson(fastJoin(realPath || originPath, 'package.json'));\n if (packageJson) {\n return {\n source: DependencyResolutionSource.SEARCH_PATH,\n name: packageJson.name,\n version: packageJson.version || '',\n path: realPath || originPath,\n originPath,\n duplicates: null,\n depth: 0,\n };\n } else if (dependencyName && realPath) {\n return {\n source: DependencyResolutionSource.SEARCH_PATH,\n name: dependencyName.toLowerCase(),\n version: '',\n path: realPath,\n originPath,\n duplicates: null,\n depth: 0,\n };\n } else {\n return null;\n }\n}\n\ninterface ResolutionOptions {\n shouldIncludeDependency?(name: string): boolean;\n}\n\nexport async function scanDependenciesInSearchPath(\n rawPath: string,\n { shouldIncludeDependency = defaultShouldIncludeDependency }: ResolutionOptions = {}\n): Promise {\n const rootPath = await maybeRealpath(rawPath);\n const searchResults: ResolutionResult = Object.create(null);\n if (!rootPath) {\n return searchResults;\n }\n\n const resolvedDependencies: DependencyResolution[] = [];\n\n const localModuleTarget = await maybeRealpath(fastJoin(rootPath, 'package.json'));\n if (localModuleTarget) {\n // If we have a `package.json` file in the search path, we're already dealing with a node module\n // and can skip the rest. This is a special case created by create-expo-module's `nativeModulesDir: ../`\n const resolution = await resolveDependency(rootPath, null, shouldIncludeDependency);\n if (resolution) resolvedDependencies.push(resolution);\n } else {\n const dirents = await fs.promises.readdir(rootPath!, { withFileTypes: true });\n await Promise.all(\n dirents.map(async (entry) => {\n if (entry.isSymbolicLink()) {\n const resolution = await resolveDependency(rootPath, entry.name, shouldIncludeDependency);\n if (resolution) resolvedDependencies.push(resolution);\n } else if (entry.isDirectory()) {\n if (entry.name === 'node_modules') {\n // Ignore nested node_modules folder\n }\n if (entry.name[0] === '.') {\n // Ignore hidden folders\n } else if (entry.name[0] === '@') {\n // NOTE: We don't expect @-scope folders to be symlinks\n const entryPath = fastJoin(rootPath, entry.name);\n const childEntries = await fs.promises.readdir(entryPath, { withFileTypes: true });\n await Promise.all(\n childEntries.map(async (child) => {\n const dependencyName = `${entry.name}/${child.name}`;\n if (child.isDirectory() || child.isSymbolicLink()) {\n const resolution = await resolveDependency(\n rootPath,\n dependencyName,\n shouldIncludeDependency\n );\n if (resolution) resolvedDependencies.push(resolution);\n }\n })\n );\n } else {\n const resolution = await resolveDependency(\n rootPath,\n entry.name,\n shouldIncludeDependency\n );\n if (resolution) resolvedDependencies.push(resolution);\n }\n }\n })\n );\n }\n\n for (let idx = 0; idx < resolvedDependencies.length; idx++) {\n const resolution = resolvedDependencies[idx];\n const prevEntry = searchResults[resolution.name];\n if (prevEntry != null && resolution.path !== prevEntry.path) {\n (prevEntry.duplicates ?? (prevEntry.duplicates = [])).push({\n name: resolution.name,\n version: resolution.version,\n path: resolution.path,\n originPath: resolution.originPath,\n });\n } else if (prevEntry == null) {\n searchResults[resolution.name] = resolution;\n }\n }\n\n return searchResults;\n}\n"]} \ No newline at end of file +{"version":3,"file":"scanning.js","sourceRoot":"","sources":["../../src/dependencies/scanning.ts"],"names":[],"mappings":";;;;;AAmDA,oEAuEC;AA1HD,4CAAoB;AAOpB,gDAAyC;AACzC,mCAAyD;AACzD,oCAAoE;AAEpE,KAAK,UAAU,iBAAiB,CAC9B,QAAgB,EAChB,cAA6B,EAC7B,uBAA4D;IAE5D,IAAI,cAAc,IAAI,CAAC,uBAAuB,CAAC,cAAc,CAAC,EAAE,CAAC;QAC/D,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,UAAU,GAAG,cAAc,CAAC,CAAC,CAAC,IAAA,gBAAQ,EAAC,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;IAClF,MAAM,QAAQ,GAAG,MAAM,IAAA,qBAAa,EAAC,UAAU,CAAC,CAAC;IACjD,MAAM,WAAW,GAAG,MAAM,IAAA,uBAAe,EAAC,IAAA,gBAAQ,EAAC,QAAQ,IAAI,UAAU,EAAE,cAAc,CAAC,CAAC,CAAC;IAC5F,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO;YACL,MAAM,gDAAwC;YAC9C,IAAI,EAAE,WAAW,CAAC,IAAI,IAAI,EAAE;YAC5B,OAAO,EAAE,WAAW,CAAC,OAAO,IAAI,EAAE;YAClC,IAAI,EAAE,QAAQ,IAAI,UAAU;YAC5B,UAAU;YACV,UAAU,EAAE,IAAI;YAChB,KAAK,EAAE,CAAC;SACT,CAAC;IACJ,CAAC;SAAM,IAAI,cAAc,IAAI,QAAQ,EAAE,CAAC;QACtC,OAAO;YACL,MAAM,gDAAwC;YAC9C,IAAI,EAAE,cAAc,CAAC,WAAW,EAAE;YAClC,OAAO,EAAE,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU;YACV,UAAU,EAAE,IAAI;YAChB,KAAK,EAAE,CAAC;SACT,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAMM,KAAK,UAAU,4BAA4B,CAChD,OAAe,EACf,EAAE,uBAAuB,GAAG,sCAA8B,KAAwB,EAAE;IAEpF,MAAM,QAAQ,GAAG,MAAM,IAAA,qBAAa,EAAC,OAAO,CAAC,CAAC;IAC9C,MAAM,aAAa,GAAqB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC5D,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,MAAM,oBAAoB,GAA2B,EAAE,CAAC;IAExD,MAAM,iBAAiB,GAAG,MAAM,IAAA,qBAAa,EAAC,IAAA,gBAAQ,EAAC,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC;IAClF,IAAI,iBAAiB,EAAE,CAAC;QACtB,gGAAgG;QAChG,wGAAwG;QACxG,MAAM,UAAU,GAAG,MAAM,iBAAiB,CAAC,QAAQ,EAAE,IAAI,EAAE,uBAAuB,CAAC,CAAC;QACpF,IAAI,UAAU;YAAE,oBAAoB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACxD,CAAC;SAAM,CAAC;QACN,MAAM,OAAO,GAAG,MAAM,YAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAS,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9E,MAAM,IAAA,qBAAO,EAAC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;YACrC,IAAI,KAAK,CAAC,cAAc,EAAE,EAAE,CAAC;gBAC3B,MAAM,UAAU,GAAG,MAAM,iBAAiB,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,EAAE,uBAAuB,CAAC,CAAC;gBAC1F,IAAI,UAAU;oBAAE,oBAAoB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACxD,CAAC;iBAAM,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBAC/B,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;oBAClC,oCAAoC;gBACtC,CAAC;gBACD,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;oBAC1B,wBAAwB;gBAC1B,CAAC;qBAAM,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;oBACjC,uDAAuD;oBACvD,MAAM,SAAS,GAAG,IAAA,gBAAQ,EAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;oBACjD,MAAM,YAAY,GAAG,MAAM,YAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;oBACnF,MAAM,OAAO,CAAC,GAAG,CACf,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;wBAC/B,MAAM,cAAc,GAAG,GAAG,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;wBACrD,IAAI,KAAK,CAAC,WAAW,EAAE,IAAI,KAAK,CAAC,cAAc,EAAE,EAAE,CAAC;4BAClD,MAAM,UAAU,GAAG,MAAM,iBAAiB,CACxC,QAAQ,EACR,cAAc,EACd,uBAAuB,CACxB,CAAC;4BACF,IAAI,UAAU;gCAAE,oBAAoB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;wBACxD,CAAC;oBACH,CAAC,CAAC,CACH,CAAC;gBACJ,CAAC;qBAAM,CAAC;oBACN,MAAM,UAAU,GAAG,MAAM,iBAAiB,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,EAAE,uBAAuB,CAAC,CAAC;oBAC1F,IAAI,UAAU;wBAAE,oBAAoB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBACxD,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,oBAAoB,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC;QAC3D,MAAM,UAAU,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC;QAC7C,MAAM,SAAS,GAAG,aAAa,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACjD,IAAI,SAAS,IAAI,IAAI,IAAI,UAAU,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI,EAAE,CAAC;YAC5D,CAAC,SAAS,CAAC,UAAU,IAAI,CAAC,SAAS,CAAC,UAAU,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;gBACzD,IAAI,EAAE,UAAU,CAAC,IAAI;gBACrB,OAAO,EAAE,UAAU,CAAC,OAAO;gBAC3B,IAAI,EAAE,UAAU,CAAC,IAAI;gBACrB,UAAU,EAAE,UAAU,CAAC,UAAU;aAClC,CAAC,CAAC;QACL,CAAC;aAAM,IAAI,SAAS,IAAI,IAAI,EAAE,CAAC;YAC7B,aAAa,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC;QAC9C,CAAC;IACH,CAAC;IAED,OAAO,aAAa,CAAC;AACvB,CAAC","sourcesContent":["import fs from 'fs';\n\nimport {\n type ResolutionResult,\n type DependencyResolution,\n DependencyResolutionSource,\n} from './types';\nimport { taskAll } from '../concurrency';\nimport { defaultShouldIncludeDependency } from './utils';\nimport { loadPackageJson, maybeRealpath, fastJoin } from '../utils';\n\nasync function resolveDependency(\n basePath: string,\n dependencyName: string | null,\n shouldIncludeDependency: (dependencyName: string) => boolean\n): Promise {\n if (dependencyName && !shouldIncludeDependency(dependencyName)) {\n return null;\n }\n const originPath = dependencyName ? fastJoin(basePath, dependencyName) : basePath;\n const realPath = await maybeRealpath(originPath);\n const packageJson = await loadPackageJson(fastJoin(realPath || originPath, 'package.json'));\n if (packageJson) {\n return {\n source: DependencyResolutionSource.SEARCH_PATH,\n name: packageJson.name || '',\n version: packageJson.version || '',\n path: realPath || originPath,\n originPath,\n duplicates: null,\n depth: 0,\n };\n } else if (dependencyName && realPath) {\n return {\n source: DependencyResolutionSource.SEARCH_PATH,\n name: dependencyName.toLowerCase(),\n version: '',\n path: realPath,\n originPath,\n duplicates: null,\n depth: 0,\n };\n } else {\n return null;\n }\n}\n\ninterface ResolutionOptions {\n shouldIncludeDependency?(name: string): boolean;\n}\n\nexport async function scanDependenciesInSearchPath(\n rawPath: string,\n { shouldIncludeDependency = defaultShouldIncludeDependency }: ResolutionOptions = {}\n): Promise {\n const rootPath = await maybeRealpath(rawPath);\n const searchResults: ResolutionResult = Object.create(null);\n if (!rootPath) {\n return searchResults;\n }\n\n const resolvedDependencies: DependencyResolution[] = [];\n\n const localModuleTarget = await maybeRealpath(fastJoin(rootPath, 'package.json'));\n if (localModuleTarget) {\n // If we have a `package.json` file in the search path, we're already dealing with a node module\n // and can skip the rest. This is a special case created by create-expo-module's `nativeModulesDir: ../`\n const resolution = await resolveDependency(rootPath, null, shouldIncludeDependency);\n if (resolution) resolvedDependencies.push(resolution);\n } else {\n const dirents = await fs.promises.readdir(rootPath!, { withFileTypes: true });\n await taskAll(dirents, async (entry) => {\n if (entry.isSymbolicLink()) {\n const resolution = await resolveDependency(rootPath, entry.name, shouldIncludeDependency);\n if (resolution) resolvedDependencies.push(resolution);\n } else if (entry.isDirectory()) {\n if (entry.name === 'node_modules') {\n // Ignore nested node_modules folder\n }\n if (entry.name[0] === '.') {\n // Ignore hidden folders\n } else if (entry.name[0] === '@') {\n // NOTE: We don't expect @-scope folders to be symlinks\n const entryPath = fastJoin(rootPath, entry.name);\n const childEntries = await fs.promises.readdir(entryPath, { withFileTypes: true });\n await Promise.all(\n childEntries.map(async (child) => {\n const dependencyName = `${entry.name}/${child.name}`;\n if (child.isDirectory() || child.isSymbolicLink()) {\n const resolution = await resolveDependency(\n rootPath,\n dependencyName,\n shouldIncludeDependency\n );\n if (resolution) resolvedDependencies.push(resolution);\n }\n })\n );\n } else {\n const resolution = await resolveDependency(rootPath, entry.name, shouldIncludeDependency);\n if (resolution) resolvedDependencies.push(resolution);\n }\n }\n });\n }\n\n for (let idx = 0; idx < resolvedDependencies.length; idx++) {\n const resolution = resolvedDependencies[idx];\n const prevEntry = searchResults[resolution.name];\n if (prevEntry != null && resolution.path !== prevEntry.path) {\n (prevEntry.duplicates ?? (prevEntry.duplicates = [])).push({\n name: resolution.name,\n version: resolution.version,\n path: resolution.path,\n originPath: resolution.originPath,\n });\n } else if (prevEntry == null) {\n searchResults[resolution.name] = resolution;\n }\n }\n\n return searchResults;\n}\n"]} \ No newline at end of file diff --git a/packages/expo-modules-autolinking/build/dependencies/utils.d.ts b/packages/expo-modules-autolinking/build/dependencies/utils.d.ts index edfa5db779b4c7..cafb74e699f772 100644 --- a/packages/expo-modules-autolinking/build/dependencies/utils.d.ts +++ b/packages/expo-modules-autolinking/build/dependencies/utils.d.ts @@ -1,11 +1,5 @@ import { type DependencyResolution, type ResolutionResult } from './types'; export declare function defaultShouldIncludeDependency(dependencyName: string): boolean; -export declare const fastJoin: (from: string, append: string) => string; -export declare const maybeRealpath: (target: string) => Promise; -export type PackageJson = Record & { - version?: string; -}; -export declare const loadPackageJson: (input: string, ...args: any[]) => Promise; export declare function mergeWithDuplicate(a: DependencyResolution, b: DependencyResolution): DependencyResolution; export declare function filterMapResolutionResult `${from}${path_1.default.sep}${append}` - : (from, append) => `${from}${path_1.default.sep}${append[0] === '@' ? append.replace('/', path_1.default.sep) : append}`; -const maybeRealpath = async (target) => { - try { - return await fs_1.default.promises.realpath(target); - } - catch { - return null; - } -}; -exports.maybeRealpath = maybeRealpath; -exports.loadPackageJson = (0, utils_1.memoize)(async function loadPackageJson(jsonPath) { - try { - const packageJsonText = await fs_1.default.promises.readFile(jsonPath, 'utf8'); - const json = JSON.parse(packageJsonText); - if (typeof json !== 'object' || json == null) { - return null; - } - return json; - } - catch { - return null; - } -}); function mergeWithDuplicate(a, b) { let target; let duplicate; @@ -122,7 +95,7 @@ function mergeWithDuplicate(a, b) { return target; } async function filterMapResolutionResult(results, filterMap) { - const resolutions = await Promise.all(Object.keys(results).map(async (key) => { + const resolutions = await (0, concurrency_1.taskAll)(Object.keys(results), async (key) => { const resolution = results[key]; const result = resolution ? await filterMap(resolution) : null; // If we failed to find a matching resolution from `searchPaths`, also try the other duplicates @@ -137,7 +110,7 @@ async function filterMapResolutionResult(results, filterMap) { } } return result; - })); + }); const output = Object.create(null); for (let idx = 0; idx < resolutions.length; idx++) { const resolution = resolutions[idx]; diff --git a/packages/expo-modules-autolinking/build/dependencies/utils.js.map b/packages/expo-modules-autolinking/build/dependencies/utils.js.map index 8ed26617bb9f3f..d574ea70bcb171 100644 --- a/packages/expo-modules-autolinking/build/dependencies/utils.js.map +++ b/packages/expo-modules-autolinking/build/dependencies/utils.js.map @@ -1 +1 @@ -{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/dependencies/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs';\nimport path from 'path';\n\nimport { memoize } from '../utils';\nimport {\n DependencyResolutionSource,\n type DependencyResolution,\n type ResolutionResult,\n} from './types';\n\nconst NODE_MODULES_PATTERN = `${path.sep}node_modules${path.sep}`;\n\n// The default dependencies we exclude don't contain dependency chains leading to autolinked modules\nexport function defaultShouldIncludeDependency(dependencyName: string): boolean {\n const scopeName =\n dependencyName[0] === '@' ? dependencyName.slice(1, dependencyName.indexOf('/')) : null;\n if (\n scopeName === 'babel' ||\n scopeName === 'types' ||\n scopeName === 'eslint' ||\n scopeName === 'typescript-eslint' ||\n scopeName === 'testing-library' ||\n scopeName === 'aws-crypto' ||\n scopeName === 'aws-sdk'\n ) {\n return false;\n }\n switch (dependencyName) {\n case '@expo/cli':\n case '@expo/config':\n case '@expo/metro-config':\n case '@expo/package-manager':\n case '@expo/prebuild-config':\n case '@expo/webpack-config':\n case '@expo/env':\n case '@react-native/codegen':\n case '@react-native/community-cli-plugin':\n case 'eslint':\n case 'eslint-config-expo':\n case 'eslint-plugin-expo':\n case 'eslint-plugin-import':\n case 'jest-expo':\n case 'jest':\n case 'metro':\n case 'ts-node':\n case 'typescript':\n case 'webpack':\n return false;\n default:\n return true;\n }\n}\n\nexport const fastJoin: (from: string, append: string) => string =\n path.sep === '/'\n ? (from, append) => `${from}${path.sep}${append}`\n : (from, append) =>\n `${from}${path.sep}${append[0] === '@' ? append.replace('/', path.sep) : append}`;\n\nexport const maybeRealpath = async (target: string): Promise => {\n try {\n return await fs.promises.realpath(target);\n } catch {\n return null;\n }\n};\n\nexport type PackageJson = Record & { version?: string };\n\nexport const loadPackageJson = memoize(async function loadPackageJson(\n jsonPath: string\n): Promise {\n try {\n const packageJsonText = await fs.promises.readFile(jsonPath, 'utf8');\n const json = JSON.parse(packageJsonText);\n if (typeof json !== 'object' || json == null) {\n return null;\n }\n return json;\n } catch {\n return null;\n }\n});\n\nexport function mergeWithDuplicate(\n a: DependencyResolution,\n b: DependencyResolution\n): DependencyResolution {\n let target: DependencyResolution;\n let duplicate: DependencyResolution;\n if (a.depth < b.depth) {\n target = a;\n duplicate = b;\n } else if (b.depth < a.depth) {\n target = b;\n duplicate = a;\n } else {\n // If both are equal, then the shallowest path wins\n const pathDepthA = a.originPath.split(NODE_MODULES_PATTERN).length;\n const pathDepthB = b.originPath.split(NODE_MODULES_PATTERN).length;\n if (pathDepthA < pathDepthB) {\n target = a;\n duplicate = b;\n } else if (pathDepthB < pathDepthA) {\n target = b;\n duplicate = a;\n } else {\n target = a;\n duplicate = b;\n }\n }\n const duplicates = target.duplicates || (target.duplicates = []);\n if (target.path !== duplicate.path) {\n if (duplicates.every((parent) => parent.path !== duplicate.path)) {\n duplicates.push({\n name: duplicate.name,\n version: duplicate.version,\n path: duplicate.path,\n originPath: duplicate.originPath,\n });\n }\n } else if (!target.version && duplicate.version) {\n target.version = duplicate.version;\n }\n if (duplicate.duplicates?.length) {\n duplicates.push(\n ...duplicate.duplicates.filter((child) =>\n duplicates.every((parent) => parent.path !== child.path)\n )\n );\n }\n return target;\n}\n\nexport async function filterMapResolutionResult(\n results: ResolutionResult,\n filterMap: (resolution: DependencyResolution) => Promise | T | null\n): Promise> {\n const resolutions = await Promise.all(\n Object.keys(results).map(async (key) => {\n const resolution = results[key];\n const result = resolution ? await filterMap(resolution) : null;\n // If we failed to find a matching resolution from `searchPaths`, also try the other duplicates\n // to see if the `searchPaths` result is not a module but another is\n if (resolution?.source === DependencyResolutionSource.SEARCH_PATH && !result) {\n for (let idx = 0; resolution.duplicates && idx < resolution.duplicates.length; idx++) {\n const duplicate = resolution.duplicates[idx];\n const duplicateResult = await filterMap({ ...resolution, ...duplicate });\n if (duplicateResult != null) {\n return duplicateResult;\n }\n }\n }\n return result;\n })\n );\n const output: Record = Object.create(null);\n for (let idx = 0; idx < resolutions.length; idx++) {\n const resolution = resolutions[idx];\n if (resolution != null) {\n output[resolution.name] = resolution;\n }\n }\n return output;\n}\n\nexport function mergeResolutionResults(\n results: ResolutionResult[],\n base?: ResolutionResult\n): ResolutionResult {\n if (base == null && results.length === 1) {\n return results[0];\n }\n const output: ResolutionResult = base == null ? Object.create(null) : base;\n for (let idx = 0; idx < results.length; idx++) {\n for (const key in results[idx]) {\n const resolution = results[idx][key]!;\n const prevResolution = output[key];\n if (prevResolution != null) {\n output[key] = mergeWithDuplicate(prevResolution, resolution);\n } else {\n output[key] = resolution;\n }\n }\n }\n return output;\n}\n"]} \ No newline at end of file +{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/dependencies/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import path from 'path';\n\nimport { taskAll } from '../concurrency';\nimport {\n DependencyResolutionSource,\n type DependencyResolution,\n type ResolutionResult,\n} from './types';\n\nconst NODE_MODULES_PATTERN = `${path.sep}node_modules${path.sep}`;\n\n// The default dependencies we exclude don't contain dependency chains leading to autolinked modules\nexport function defaultShouldIncludeDependency(dependencyName: string): boolean {\n const scopeName =\n dependencyName[0] === '@' ? dependencyName.slice(1, dependencyName.indexOf('/')) : null;\n if (\n scopeName === 'babel' ||\n scopeName === 'types' ||\n scopeName === 'eslint' ||\n scopeName === 'typescript-eslint' ||\n scopeName === 'testing-library' ||\n scopeName === 'aws-crypto' ||\n scopeName === 'aws-sdk'\n ) {\n return false;\n }\n switch (dependencyName) {\n case '@expo/cli':\n case '@expo/config':\n case '@expo/metro-config':\n case '@expo/package-manager':\n case '@expo/prebuild-config':\n case '@expo/webpack-config':\n case '@expo/env':\n case '@react-native/codegen':\n case '@react-native/community-cli-plugin':\n case 'eslint':\n case 'eslint-config-expo':\n case 'eslint-plugin-expo':\n case 'eslint-plugin-import':\n case 'jest-expo':\n case 'jest':\n case 'metro':\n case 'ts-node':\n case 'typescript':\n case 'webpack':\n return false;\n default:\n return true;\n }\n}\n\nexport function mergeWithDuplicate(\n a: DependencyResolution,\n b: DependencyResolution\n): DependencyResolution {\n let target: DependencyResolution;\n let duplicate: DependencyResolution;\n if (a.depth < b.depth) {\n target = a;\n duplicate = b;\n } else if (b.depth < a.depth) {\n target = b;\n duplicate = a;\n } else {\n // If both are equal, then the shallowest path wins\n const pathDepthA = a.originPath.split(NODE_MODULES_PATTERN).length;\n const pathDepthB = b.originPath.split(NODE_MODULES_PATTERN).length;\n if (pathDepthA < pathDepthB) {\n target = a;\n duplicate = b;\n } else if (pathDepthB < pathDepthA) {\n target = b;\n duplicate = a;\n } else {\n target = a;\n duplicate = b;\n }\n }\n const duplicates = target.duplicates || (target.duplicates = []);\n if (target.path !== duplicate.path) {\n if (duplicates.every((parent) => parent.path !== duplicate.path)) {\n duplicates.push({\n name: duplicate.name,\n version: duplicate.version,\n path: duplicate.path,\n originPath: duplicate.originPath,\n });\n }\n } else if (!target.version && duplicate.version) {\n target.version = duplicate.version;\n }\n if (duplicate.duplicates?.length) {\n duplicates.push(\n ...duplicate.duplicates.filter((child) =>\n duplicates.every((parent) => parent.path !== child.path)\n )\n );\n }\n return target;\n}\n\nexport async function filterMapResolutionResult(\n results: ResolutionResult,\n filterMap: (resolution: DependencyResolution) => Promise | T | null\n): Promise> {\n const resolutions = await taskAll(Object.keys(results), async (key) => {\n const resolution = results[key];\n const result = resolution ? await filterMap(resolution) : null;\n // If we failed to find a matching resolution from `searchPaths`, also try the other duplicates\n // to see if the `searchPaths` result is not a module but another is\n if (resolution?.source === DependencyResolutionSource.SEARCH_PATH && !result) {\n for (let idx = 0; resolution.duplicates && idx < resolution.duplicates.length; idx++) {\n const duplicate = resolution.duplicates[idx];\n const duplicateResult = await filterMap({ ...resolution, ...duplicate });\n if (duplicateResult != null) {\n return duplicateResult;\n }\n }\n }\n return result;\n });\n const output: Record = Object.create(null);\n for (let idx = 0; idx < resolutions.length; idx++) {\n const resolution = resolutions[idx];\n if (resolution != null) {\n output[resolution.name] = resolution;\n }\n }\n return output;\n}\n\nexport function mergeResolutionResults(\n results: ResolutionResult[],\n base?: ResolutionResult\n): ResolutionResult {\n if (base == null && results.length === 1) {\n return results[0];\n }\n const output: ResolutionResult = base == null ? Object.create(null) : base;\n for (let idx = 0; idx < results.length; idx++) {\n for (const key in results[idx]) {\n const resolution = results[idx][key]!;\n const prevResolution = output[key];\n if (prevResolution != null) {\n output[key] = mergeWithDuplicate(prevResolution, resolution);\n } else {\n output[key] = resolution;\n }\n }\n }\n return output;\n}\n"]} \ No newline at end of file diff --git a/packages/expo-modules-autolinking/build/index.js b/packages/expo-modules-autolinking/build/index.js index 8a8d818104734a..48a509414f862e 100644 --- a/packages/expo-modules-autolinking/build/index.js +++ b/packages/expo-modules-autolinking/build/index.js @@ -9,6 +9,7 @@ const reactNativeConfigCommand_1 = require("./commands/reactNativeConfigCommand" const resolveCommand_1 = require("./commands/resolveCommand"); const searchCommand_1 = require("./commands/searchCommand"); const verifyCommand_1 = require("./commands/verifyCommand"); +const memoize_1 = require("./memoize"); async function main(args) { const cli = commander_1.default .version(require('expo-modules-autolinking/package.json').version) @@ -18,7 +19,9 @@ async function main(args) { (0, resolveCommand_1.resolveCommand)(cli); (0, generateModulesProviderCommand_1.generateModulesProviderCommand)(cli); (0, reactNativeConfigCommand_1.reactNativeConfigCommand)(cli); - await cli.parseAsync(args, { from: 'user' }); + await (0, memoize_1.createMemoizer)().withMemoizer(async () => { + await cli.parseAsync(args, { from: 'user' }); + }); } module.exports = main; //# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/packages/expo-modules-autolinking/build/index.js.map b/packages/expo-modules-autolinking/build/index.js.map index 95391bed428376..84b031082b1d71 100644 --- a/packages/expo-modules-autolinking/build/index.js.map +++ b/packages/expo-modules-autolinking/build/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;AAAA,0DAAkC;AAElC,8FAA2F;AAC3F,kFAA+E;AAC/E,8DAA2D;AAC3D,4DAAyD;AACzD,4DAAyD;AAEzD,KAAK,UAAU,IAAI,CAAC,IAAc;IAChC,MAAM,GAAG,GAAG,mBAAS;SAClB,OAAO,CAAC,OAAO,CAAC,uCAAuC,CAAC,CAAC,OAAO,CAAC;SACjE,WAAW,CAAC,gEAAgE,CAAC,CAAC;IAEjF,IAAA,6BAAa,EAAC,GAAG,CAAC,CAAC;IACnB,IAAA,6BAAa,EAAC,GAAG,CAAC,CAAC;IACnB,IAAA,+BAAc,EAAC,GAAG,CAAC,CAAC;IACpB,IAAA,+DAA8B,EAAC,GAAG,CAAC,CAAC;IACpC,IAAA,mDAAwB,EAAC,GAAG,CAAC,CAAC;IAE9B,MAAM,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC","sourcesContent":["import commander from 'commander';\n\nimport { generateModulesProviderCommand } from './commands/generateModulesProviderCommand';\nimport { reactNativeConfigCommand } from './commands/reactNativeConfigCommand';\nimport { resolveCommand } from './commands/resolveCommand';\nimport { searchCommand } from './commands/searchCommand';\nimport { verifyCommand } from './commands/verifyCommand';\n\nasync function main(args: string[]) {\n const cli = commander\n .version(require('expo-modules-autolinking/package.json').version)\n .description('CLI command that searches for native modules to autolink them.');\n\n verifyCommand(cli);\n searchCommand(cli);\n resolveCommand(cli);\n generateModulesProviderCommand(cli);\n reactNativeConfigCommand(cli);\n\n await cli.parseAsync(args, { from: 'user' });\n}\n\nmodule.exports = main;\n"]} \ No newline at end of file +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;AAAA,0DAAkC;AAElC,8FAA2F;AAC3F,kFAA+E;AAC/E,8DAA2D;AAC3D,4DAAyD;AACzD,4DAAyD;AACzD,uCAA2C;AAE3C,KAAK,UAAU,IAAI,CAAC,IAAc;IAChC,MAAM,GAAG,GAAG,mBAAS;SAClB,OAAO,CAAC,OAAO,CAAC,uCAAuC,CAAC,CAAC,OAAO,CAAC;SACjE,WAAW,CAAC,gEAAgE,CAAC,CAAC;IAEjF,IAAA,6BAAa,EAAC,GAAG,CAAC,CAAC;IACnB,IAAA,6BAAa,EAAC,GAAG,CAAC,CAAC;IACnB,IAAA,+BAAc,EAAC,GAAG,CAAC,CAAC;IACpB,IAAA,+DAA8B,EAAC,GAAG,CAAC,CAAC;IACpC,IAAA,mDAAwB,EAAC,GAAG,CAAC,CAAC;IAE9B,MAAM,IAAA,wBAAc,GAAE,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE;QAC7C,MAAM,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC","sourcesContent":["import commander from 'commander';\n\nimport { generateModulesProviderCommand } from './commands/generateModulesProviderCommand';\nimport { reactNativeConfigCommand } from './commands/reactNativeConfigCommand';\nimport { resolveCommand } from './commands/resolveCommand';\nimport { searchCommand } from './commands/searchCommand';\nimport { verifyCommand } from './commands/verifyCommand';\nimport { createMemoizer } from './memoize';\n\nasync function main(args: string[]) {\n const cli = commander\n .version(require('expo-modules-autolinking/package.json').version)\n .description('CLI command that searches for native modules to autolink them.');\n\n verifyCommand(cli);\n searchCommand(cli);\n resolveCommand(cli);\n generateModulesProviderCommand(cli);\n reactNativeConfigCommand(cli);\n\n await createMemoizer().withMemoizer(async () => {\n await cli.parseAsync(args, { from: 'user' });\n });\n}\n\nmodule.exports = main;\n"]} \ No newline at end of file diff --git a/packages/expo-modules-autolinking/build/memoize.d.ts b/packages/expo-modules-autolinking/build/memoize.d.ts new file mode 100644 index 00000000000000..e599ac0348d029 --- /dev/null +++ b/packages/expo-modules-autolinking/build/memoize.d.ts @@ -0,0 +1,16 @@ +export interface Memoizer { + /** Calls a function with a memoizer cache, caching its return value */ + call>(fn: Fn, input: string, ...args: Args): Promise; + /** Invokes an async context with a memoizer cache */ + withMemoizer(callback: () => R): R; + withMemoizer(callback: (...args: TArgs) => R, ...args: TArgs): R; +} +export interface MemoizableAsyncFn { + (input: string, ...args: Args): Promise; +} +/** Wraps a function in a memoizer, using the memoizer async local storage */ +export declare function memoize>(fn: Fn): MemoizableAsyncFn; +/** Creates a memoizer that can provide a cache to memoized functions */ +export declare function createMemoizer(): Memoizer; +/** @internal Used in tests to verify the memoizer was freed */ +export declare function _verifyMemoizerFreed(): boolean; diff --git a/packages/expo-modules-autolinking/build/memoize.js b/packages/expo-modules-autolinking/build/memoize.js new file mode 100644 index 00000000000000..f3232d6f0547fc --- /dev/null +++ b/packages/expo-modules-autolinking/build/memoize.js @@ -0,0 +1,84 @@ +"use strict"; +// expo-modules-autolinking has a few memoizable operations that we don't want to repeat. +// However, memoizing them naively means that we may hold on to the cached values for too long. +// Instead, we wrap all calls with a `Memoizer`. +// +// This could use AsyncLocalStorage, but those are expensive. Instead, we only share one +// cache for all calls, and assume that all memoizable return values may be memoized and +// shared globally. +// +// Memoizers are created once per run, and then shared between all subsequent calls. They +// are freed when their usage count to zero, after one tick. +// +// NOTE: If you need to debug whether the memoizer is properly used, change when the +// `console.warn` appears to see if you have any uncached calls. We allow uncached calls +// for backwards-compatibility, since, at worst, we have an uncached call, if the +// Memoizer is missing. +Object.defineProperty(exports, "__esModule", { value: true }); +exports.memoize = memoize; +exports.createMemoizer = createMemoizer; +exports._verifyMemoizerFreed = _verifyMemoizerFreed; +const MAX_SIZE = 5_000; +let currentMemoizer; +let currentContexts = 0; +/** Wraps a function in a memoizer, using the memoizer async local storage */ +function memoize(fn) { + return (input, ...args) => { + // We either use the current memoizer (sync) or the memoize context (async) + if (!currentMemoizer) { + if (process.env.NODE_ENV === 'test') { + console.warn(`expo-modules-autolinking: Memoized function called without memoize context (${fn.name})\n` + + new Error().stack); + } + return fn(input, ...args); + } + return currentMemoizer.call(fn, input, ...args); + }; +} +/** Creates a memoizer that can provide a cache to memoized functions */ +function createMemoizer() { + // If we already have a memoizer, reuse it, since we can share them globally + if (currentMemoizer) { + return currentMemoizer; + } + const cacheByFn = new Map(); + const memoizer = { + async call(fn, input, ...args) { + let cache = cacheByFn.get(fn); + if (!cache) { + cache = new Map(); + cacheByFn.set(fn, cache); + } + if (!cache.has(input)) { + const value = await memoizer.withMemoizer(fn, input, ...args); + if (cache.size > MAX_SIZE) { + cache.clear(); + } + cache.set(input, value); + return value; + } + return cache.get(input); + }, + async withMemoizer(fn, ...args) { + currentMemoizer = memoizer; + currentContexts++; + try { + return await fn(...args); + } + finally { + if (currentContexts > 0) { + currentContexts--; + } + if (currentContexts === 0) { + currentMemoizer = undefined; + } + } + }, + }; + return memoizer; +} +/** @internal Used in tests to verify the memoizer was freed */ +function _verifyMemoizerFreed() { + return currentMemoizer === undefined && currentContexts === 0; +} +//# sourceMappingURL=memoize.js.map \ No newline at end of file diff --git a/packages/expo-modules-autolinking/build/memoize.js.map b/packages/expo-modules-autolinking/build/memoize.js.map new file mode 100644 index 00000000000000..ebc365a15fc7a9 --- /dev/null +++ b/packages/expo-modules-autolinking/build/memoize.js.map @@ -0,0 +1 @@ +{"version":3,"file":"memoize.js","sourceRoot":"","sources":["../src/memoize.ts"],"names":[],"mappings":"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","sourcesContent":["// expo-modules-autolinking has a few memoizable operations that we don't want to repeat.\n// However, memoizing them naively means that we may hold on to the cached values for too long.\n// Instead, we wrap all calls with a `Memoizer`.\n//\n// This could use AsyncLocalStorage, but those are expensive. Instead, we only share one\n// cache for all calls, and assume that all memoizable return values may be memoized and\n// shared globally.\n//\n// Memoizers are created once per run, and then shared between all subsequent calls. They\n// are freed when their usage count to zero, after one tick.\n//\n// NOTE: If you need to debug whether the memoizer is properly used, change when the\n// `console.warn` appears to see if you have any uncached calls. We allow uncached calls\n// for backwards-compatibility, since, at worst, we have an uncached call, if the\n// Memoizer is missing.\n\nconst MAX_SIZE = 5_000;\n\nexport interface Memoizer {\n /** Calls a function with a memoizer cache, caching its return value */\n call>(\n fn: Fn,\n input: string,\n ...args: Args\n ): Promise;\n\n /** Invokes an async context with a memoizer cache */\n withMemoizer(callback: () => R): R;\n withMemoizer(callback: (...args: TArgs) => R, ...args: TArgs): R;\n}\n\nexport interface MemoizableAsyncFn {\n (input: string, ...args: Args): Promise;\n}\n\nlet currentMemoizer: Memoizer | undefined;\nlet currentContexts = 0;\n\n/** Wraps a function in a memoizer, using the memoizer async local storage */\nexport function memoize>(\n fn: Fn\n): MemoizableAsyncFn {\n return (input: string, ...args: Args) => {\n // We either use the current memoizer (sync) or the memoize context (async)\n if (!currentMemoizer) {\n if (process.env.NODE_ENV === 'test') {\n console.warn(\n `expo-modules-autolinking: Memoized function called without memoize context (${fn.name})\\n` +\n new Error().stack\n );\n }\n return fn(input, ...args);\n }\n return currentMemoizer.call(fn, input, ...args);\n };\n}\n\n/** Creates a memoizer that can provide a cache to memoized functions */\nexport function createMemoizer(): Memoizer {\n // If we already have a memoizer, reuse it, since we can share them globally\n if (currentMemoizer) {\n return currentMemoizer;\n }\n\n const cacheByFn = new Map>();\n const memoizer: Memoizer = {\n async call(fn, input, ...args) {\n let cache = cacheByFn.get(fn);\n if (!cache) {\n cache = new Map();\n cacheByFn.set(fn, cache);\n }\n if (!cache.has(input)) {\n const value = await memoizer.withMemoizer(fn, input, ...args);\n if (cache.size > MAX_SIZE) {\n cache.clear();\n }\n cache.set(input, value);\n return value;\n }\n return cache.get(input);\n },\n async withMemoizer(fn: (...args: TArgs) => R, ...args: TArgs) {\n currentMemoizer = memoizer;\n currentContexts++;\n try {\n return await fn(...args);\n } finally {\n if (currentContexts > 0) {\n currentContexts--;\n }\n if (currentContexts === 0) {\n currentMemoizer = undefined;\n }\n }\n },\n };\n return memoizer;\n}\n\n/** @internal Used in tests to verify the memoizer was freed */\nexport function _verifyMemoizerFreed() {\n return currentMemoizer === undefined && currentContexts === 0;\n}\n"]} \ No newline at end of file diff --git a/packages/expo-modules-autolinking/build/platforms/android/android.js b/packages/expo-modules-autolinking/build/platforms/android/android.js index 881f676308b45e..8efcbfae30b6a3 100644 --- a/packages/expo-modules-autolinking/build/platforms/android/android.js +++ b/packages/expo-modules-autolinking/build/platforms/android/android.js @@ -13,6 +13,7 @@ exports.convertPackageWithGradleToProjectName = convertPackageWithGradleToProjec exports.searchGradlePropertyFirst = searchGradlePropertyFirst; const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); +const concurrency_1 = require("../../concurrency"); const utils_1 = require("../../utils"); const ANDROID_PROPERTIES_FILE = 'gradle.properties'; const ANDROID_EXTRA_BUILD_DEPS_KEY = 'android.extraMavenRepos'; @@ -51,7 +52,7 @@ async function resolveModuleAsync(packageName, revision) { plugins, }; } - const projects = await Promise.all(androidProjects.map(async (project) => { + const projects = await (0, concurrency_1.taskAll)(androidProjects, async (project) => { const projectPath = path_1.default.join(revision.path, project.path); const aarProjects = (project.gradleAarProjects ?? [])?.map((aarProject) => { const projectName = `${defaultProjectName}$${aarProject.name}`; @@ -92,7 +93,7 @@ async function resolveModuleAsync(packageName, revision) { ...(publication ? { publication } : {}), ...(aarProjects?.length > 0 ? { aarProjects } : {}), }; - })); + }); const coreFeatures = revision.config?.coreFeatures() ?? []; return { packageName, diff --git a/packages/expo-modules-autolinking/build/platforms/android/android.js.map b/packages/expo-modules-autolinking/build/platforms/android/android.js.map index 259ecd15a70e73..c27b58a5a05966 100644 --- a/packages/expo-modules-autolinking/build/platforms/android/android.js.map +++ b/packages/expo-modules-autolinking/build/platforms/android/android.js.map @@ -1 +1 @@ -{"version":3,"file":"android.js","sourceRoot":"","sources":["../../../src/platforms/android/android.ts"],"names":[],"mappings":";;;;;AAcA,4CAIC;AAED,4CAKC;AAED,gDAsGC;AAED,gFAaC;AAED,gEAaC;AAQD,kEAEC;AAaD,sFAOC;AAUD,8DAcC;AArND,4CAAoB;AACpB,gDAAwB;AAIxB,uCAAmD;AAEnD,MAAM,uBAAuB,GAAG,mBAAmB,CAAC;AACpD,MAAM,4BAA4B,GAAG,yBAAyB,CAAC;AAM/D,SAAgB,gBAAgB,CAC9B,OAA2B;IAE3B,OAAO,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAC5F,CAAC;AAED,SAAgB,gBAAgB,CAAC,WAAmB;IAClD,OAAO,CACL,YAAE,CAAC,UAAU,CAAC,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;QACrD,YAAE,CAAC,UAAU,CAAC,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAC,CAC1D,CAAC;AACJ,CAAC;AAEM,KAAK,UAAU,kBAAkB,CACtC,WAAmB,EACnB,QAAyB;IAEzB,8EAA8E;IAE9E,0BAA0B;IAC1B,IAAI,WAAW,KAAK,kCAAkC,EAAE,CAAC;QACvD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,OAAO,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,oBAAoB,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,CACjE,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,kBAAkB,EAAE,EAAE,EAAE,CAAC,CAAC;QACjD,EAAE;QACF,KAAK;QACL,SAAS,EAAE,cAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;QAC9C,kBAAkB,EAAE,kBAAkB,IAAI,IAAI;KAC/C,CAAC,CACH,CAAC;IAEF,MAAM,kBAAkB,GAAG,2BAA2B,CAAC,WAAW,CAAC,CAAC;IAEpE,MAAM,eAAe,GAAG,QAAQ,CAAC,MAAM;QACrC,EAAE,eAAe,CAAC,kBAAkB,CAAC;QACrC,EAAE,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE;QACnB,OAAO,CAAC,OAAO,CAAC,SAAS,IAAI,gBAAgB,CAAC,cAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACxF,CAAC,CAAC,CAAC;IAEL,uFAAuF;IACvF,IAAI,CAAC,eAAe,EAAE,MAAM,EAAE,CAAC;QAC7B,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO;YACL,WAAW;YACX,OAAO;SACR,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAChC,eAAe,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;QACpC,MAAM,WAAW,GAAG,cAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QAE3D,MAAM,WAAW,GAAG,CAAC,OAAO,CAAC,iBAAiB,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE;YACxE,MAAM,WAAW,GAAG,GAAG,kBAAkB,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC;YAC/D,MAAM,UAAU,GAAG,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;YAChE,OAAO;gBACL,IAAI,EAAE,WAAW;gBACjB,WAAW,EAAE,cAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC,WAAW,CAAC;gBAC7D,UAAU;aACX,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;QAChC,MAAM,8BAA8B,GAAG,OAAO,CAAC,8BAA8B;YAC3E,CAAC,CAAC,cAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,8BAA8B,CAAC;YAClE,CAAC,CAAC,SAAS,CAAC;QAEd,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;QACnC,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,IAAA,4BAAoB,EAAC,WAAW,CAAC,EAAE,CAAC;YAC3D,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;gBAC7E,SAAS;YACX,CAAC;YACD,MAAM,WAAW,GAAG,MAAM,YAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAElE,6CAA6C;YAC7C,IACE,CAAC,qEAAqE,CAAC,IAAI,CAAC,WAAW,CAAC,EACxF,CAAC;gBACD,SAAS;YACX,CAAC;YAED,MAAM,gBAAgB,GAAG,WAAW,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;YAEnE,IAAI,gBAAgB,EAAE,CAAC;gBACrB,MAAM,QAAQ,GAAG,cAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,cAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;gBACnE,QAAQ,CAAC,GAAG,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,IAAI,QAAQ,EAAE,CAAC,CAAC;YACrD,CAAC;QACH,CAAC;QAED,OAAO;YACL,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,SAAS,EAAE,WAAW;YACtB,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE;YAC9B,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,EAAE;YAChC,QAAQ,EAAE,CAAC,GAAG,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;YAC1D,GAAG,CAAC,8BAA8B,CAAC,CAAC,CAAC,EAAE,8BAA8B,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7E,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvC,GAAG,CAAC,WAAW,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACpD,CAAC;IACJ,CAAC,CAAC,CACH,CAAC;IAEF,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;IAE3D,OAAO;QACL,WAAW;QACX,QAAQ;QACR,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3C,GAAG,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACrD,CAAC;AACJ,CAAC;AAEM,KAAK,UAAU,kCAAkC,CACtD,iBAAyB;IAEzB,MAAM,qBAAqB,GAAG,MAAM,0BAA0B,CAC5D,iBAAiB,EACjB,4BAA4B,CAC7B,CAAC;IACF,IAAI,qBAAqB,EAAE,CAAC;QAC1B,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;QAC3C,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAEM,KAAK,UAAU,0BAA0B,CAC9C,iBAAyB,EACzB,WAAmB;IAEnB,MAAM,SAAS,GAAG,cAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,uBAAuB,CAAC,CAAC;IACxE,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,YAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAC/D,MAAM,aAAa,GAAG,yBAAyB,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;QACvE,IAAI,aAAa,EAAE,CAAC;YAClB,OAAO,aAAa,CAAC;QACvB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IACV,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,SAAgB,2BAA2B,CAAC,WAAmB;IAC7D,OAAO,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAC7D,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAgB,qCAAqC,CACnD,WAAmB,EACnB,eAAuB;IAEvB,MAAM,IAAI,GAAG,2BAA2B,CAAC,WAAW,CAAC,CAAC;IACtD,MAAM,OAAO,GAAG,cAAI,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAClE,OAAO,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,OAAO,EAAE,CAAC;AAC7D,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,yBAAyB,CAAC,QAAgB,EAAE,YAAoB;IAC9E,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAClC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YAC/B,IAAI,GAAG,KAAK,YAAY,EAAE,CAAC;gBACzB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;gBAC/C,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["import fs from 'fs';\nimport path from 'path';\n\nimport { AutolinkingOptions } from '../../commands/autolinkingOptions';\nimport type { ExtraDependencies, ModuleDescriptorAndroid, PackageRevision } from '../../types';\nimport { scanFilesRecursively } from '../../utils';\n\nconst ANDROID_PROPERTIES_FILE = 'gradle.properties';\nconst ANDROID_EXTRA_BUILD_DEPS_KEY = 'android.extraMavenRepos';\n\ninterface AndroidConfigurationOutput {\n buildFromSource: string[];\n}\n\nexport function getConfiguration(\n options: AutolinkingOptions\n): AndroidConfigurationOutput | undefined {\n return options.buildFromSource ? { buildFromSource: options.buildFromSource } : undefined;\n}\n\nexport function isAndroidProject(projectRoot: string): boolean {\n return (\n fs.existsSync(path.join(projectRoot, 'build.gradle')) ||\n fs.existsSync(path.join(projectRoot, 'build.gradle.kts'))\n );\n}\n\nexport async function resolveModuleAsync(\n packageName: string,\n revision: PackageRevision\n): Promise {\n // TODO: Relative source dir should be configurable through the module config.\n\n // Don't link itself... :D\n if (packageName === '@unimodules/react-native-adapter') {\n return null;\n }\n\n const plugins = (revision.config?.androidGradlePlugins() ?? []).map(\n ({ id, group, sourceDir, applyToRootProject }) => ({\n id,\n group,\n sourceDir: path.join(revision.path, sourceDir),\n applyToRootProject: applyToRootProject ?? true,\n })\n );\n\n const defaultProjectName = convertPackageToProjectName(packageName);\n\n const androidProjects = revision.config\n ?.androidProjects(defaultProjectName)\n ?.filter((project) => {\n return !project.isDefault || isAndroidProject(path.join(revision.path, project.path));\n });\n\n // Just in case where the module doesn't have its own `build.gradle`/`settings.gradle`.\n if (!androidProjects?.length) {\n if (!plugins.length) {\n return null;\n }\n\n return {\n packageName,\n plugins,\n };\n }\n\n const projects = await Promise.all(\n androidProjects.map(async (project) => {\n const projectPath = path.join(revision.path, project.path);\n\n const aarProjects = (project.gradleAarProjects ?? [])?.map((aarProject) => {\n const projectName = `${defaultProjectName}$${aarProject.name}`;\n const projectDir = path.join(projectPath, 'build', projectName);\n return {\n name: projectName,\n aarFilePath: path.join(revision.path, aarProject.aarFilePath),\n projectDir,\n };\n });\n\n const { publication } = project;\n const shouldUsePublicationScriptPath = project.shouldUsePublicationScriptPath\n ? path.join(revision.path, project.shouldUsePublicationScriptPath)\n : undefined;\n\n const packages = new Set();\n for await (const file of scanFilesRecursively(projectPath)) {\n if (!file.name.endsWith('Package.java') && !file.name.endsWith('Package.kt')) {\n continue;\n }\n const fileContent = await fs.promises.readFile(file.path, 'utf8');\n\n // Very naive check to skip non-expo packages\n if (\n !/\\bimport\\s+expo\\.modules\\.core\\.(interfaces\\.Package|BasePackage)\\b/.test(fileContent)\n ) {\n continue;\n }\n\n const classPathMatches = fileContent.match(/^package ([\\w.]+)\\b/m);\n\n if (classPathMatches) {\n const basename = path.basename(file.name, path.extname(file.name));\n packages.add(`${classPathMatches[1]}.${basename}`);\n }\n }\n\n return {\n name: project.name,\n sourceDir: projectPath,\n modules: project.modules ?? [],\n services: project.services ?? [],\n packages: [...packages].sort((a, b) => a.localeCompare(b)),\n ...(shouldUsePublicationScriptPath ? { shouldUsePublicationScriptPath } : {}),\n ...(publication ? { publication } : {}),\n ...(aarProjects?.length > 0 ? { aarProjects } : {}),\n };\n })\n );\n\n const coreFeatures = revision.config?.coreFeatures() ?? [];\n\n return {\n packageName,\n projects,\n ...(plugins?.length > 0 ? { plugins } : {}),\n ...(coreFeatures.length > 0 ? { coreFeatures } : {}),\n };\n}\n\nexport async function resolveExtraBuildDependenciesAsync(\n projectNativeRoot: string\n): Promise {\n const extraMavenReposString = await resolveGradlePropertyAsync(\n projectNativeRoot,\n ANDROID_EXTRA_BUILD_DEPS_KEY\n );\n if (extraMavenReposString) {\n try {\n return JSON.parse(extraMavenReposString);\n } catch {}\n }\n return null;\n}\n\nexport async function resolveGradlePropertyAsync(\n projectNativeRoot: string,\n propertyKey: string\n): Promise {\n const propsFile = path.join(projectNativeRoot, ANDROID_PROPERTIES_FILE);\n try {\n const contents = await fs.promises.readFile(propsFile, 'utf8');\n const propertyValue = searchGradlePropertyFirst(contents, propertyKey);\n if (propertyValue) {\n return propertyValue;\n }\n } catch {}\n return null;\n}\n\n/**\n * Converts the package name to Android's project name.\n * `/` path will transform as `-`\n *\n * Example: `@expo/example` + `android/build.gradle` → `expo-example`\n */\nexport function convertPackageToProjectName(packageName: string): string {\n return packageName.replace(/^@/g, '').replace(/\\W+/g, '-');\n}\n\n/**\n * Converts the package name and gradle file path to Android's project name.\n * `$` to indicate subprojects\n * `/` path will transform as `-`\n *\n * Example: `@expo/example` + `android/build.gradle` → `expo-example`\n *\n * Example: multiple projects\n * - `expo-test` + `android/build.gradle` → `react-native-third-party`\n * - `expo-test` + `subproject/build.gradle` → `react-native-third-party$subproject`\n */\nexport function convertPackageWithGradleToProjectName(\n packageName: string,\n buildGradleFile: string\n): string {\n const name = convertPackageToProjectName(packageName);\n const baseDir = path.dirname(buildGradleFile).replace(/\\//g, '-');\n return baseDir === 'android' ? name : `${name}$${baseDir}`;\n}\n\n/**\n * Given the contents of a `gradle.properties` file,\n * searches for a property with the given name.\n *\n * This function will return the first property found with the given name.\n * The implementation follows config-plugins and\n * tries to align the behavior with the `withGradleProperties` plugin.\n */\nexport function searchGradlePropertyFirst(contents: string, propertyName: string): string | null {\n const lines = contents.split('\\n');\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (line && !line.startsWith('#')) {\n const eok = line.indexOf('=');\n const key = line.slice(0, eok);\n if (key === propertyName) {\n const value = line.slice(eok + 1, line.length);\n return value;\n }\n }\n }\n return null;\n}\n"]} \ No newline at end of file +{"version":3,"file":"android.js","sourceRoot":"","sources":["../../../src/platforms/android/android.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs';\nimport path from 'path';\n\nimport { AutolinkingOptions } from '../../commands/autolinkingOptions';\nimport { taskAll } from '../../concurrency';\nimport type { ExtraDependencies, ModuleDescriptorAndroid, PackageRevision } from '../../types';\nimport { scanFilesRecursively } from '../../utils';\n\nconst ANDROID_PROPERTIES_FILE = 'gradle.properties';\nconst ANDROID_EXTRA_BUILD_DEPS_KEY = 'android.extraMavenRepos';\n\ninterface AndroidConfigurationOutput {\n buildFromSource: string[];\n}\n\nexport function getConfiguration(\n options: AutolinkingOptions\n): AndroidConfigurationOutput | undefined {\n return options.buildFromSource ? { buildFromSource: options.buildFromSource } : undefined;\n}\n\nexport function isAndroidProject(projectRoot: string): boolean {\n return (\n fs.existsSync(path.join(projectRoot, 'build.gradle')) ||\n fs.existsSync(path.join(projectRoot, 'build.gradle.kts'))\n );\n}\n\nexport async function resolveModuleAsync(\n packageName: string,\n revision: PackageRevision\n): Promise {\n // TODO: Relative source dir should be configurable through the module config.\n\n // Don't link itself... :D\n if (packageName === '@unimodules/react-native-adapter') {\n return null;\n }\n\n const plugins = (revision.config?.androidGradlePlugins() ?? []).map(\n ({ id, group, sourceDir, applyToRootProject }) => ({\n id,\n group,\n sourceDir: path.join(revision.path, sourceDir),\n applyToRootProject: applyToRootProject ?? true,\n })\n );\n\n const defaultProjectName = convertPackageToProjectName(packageName);\n\n const androidProjects = revision.config\n ?.androidProjects(defaultProjectName)\n ?.filter((project) => {\n return !project.isDefault || isAndroidProject(path.join(revision.path, project.path));\n });\n\n // Just in case where the module doesn't have its own `build.gradle`/`settings.gradle`.\n if (!androidProjects?.length) {\n if (!plugins.length) {\n return null;\n }\n\n return {\n packageName,\n plugins,\n };\n }\n\n const projects = await taskAll(androidProjects, async (project) => {\n const projectPath = path.join(revision.path, project.path);\n\n const aarProjects = (project.gradleAarProjects ?? [])?.map((aarProject) => {\n const projectName = `${defaultProjectName}$${aarProject.name}`;\n const projectDir = path.join(projectPath, 'build', projectName);\n return {\n name: projectName,\n aarFilePath: path.join(revision.path, aarProject.aarFilePath),\n projectDir,\n };\n });\n\n const { publication } = project;\n const shouldUsePublicationScriptPath = project.shouldUsePublicationScriptPath\n ? path.join(revision.path, project.shouldUsePublicationScriptPath)\n : undefined;\n\n const packages = new Set();\n for await (const file of scanFilesRecursively(projectPath)) {\n if (!file.name.endsWith('Package.java') && !file.name.endsWith('Package.kt')) {\n continue;\n }\n const fileContent = await fs.promises.readFile(file.path, 'utf8');\n\n // Very naive check to skip non-expo packages\n if (\n !/\\bimport\\s+expo\\.modules\\.core\\.(interfaces\\.Package|BasePackage)\\b/.test(fileContent)\n ) {\n continue;\n }\n\n const classPathMatches = fileContent.match(/^package ([\\w.]+)\\b/m);\n\n if (classPathMatches) {\n const basename = path.basename(file.name, path.extname(file.name));\n packages.add(`${classPathMatches[1]}.${basename}`);\n }\n }\n\n return {\n name: project.name,\n sourceDir: projectPath,\n modules: project.modules ?? [],\n services: project.services ?? [],\n packages: [...packages].sort((a, b) => a.localeCompare(b)),\n ...(shouldUsePublicationScriptPath ? { shouldUsePublicationScriptPath } : {}),\n ...(publication ? { publication } : {}),\n ...(aarProjects?.length > 0 ? { aarProjects } : {}),\n };\n });\n\n const coreFeatures = revision.config?.coreFeatures() ?? [];\n\n return {\n packageName,\n projects,\n ...(plugins?.length > 0 ? { plugins } : {}),\n ...(coreFeatures.length > 0 ? { coreFeatures } : {}),\n };\n}\n\nexport async function resolveExtraBuildDependenciesAsync(\n projectNativeRoot: string\n): Promise {\n const extraMavenReposString = await resolveGradlePropertyAsync(\n projectNativeRoot,\n ANDROID_EXTRA_BUILD_DEPS_KEY\n );\n if (extraMavenReposString) {\n try {\n return JSON.parse(extraMavenReposString);\n } catch {}\n }\n return null;\n}\n\nexport async function resolveGradlePropertyAsync(\n projectNativeRoot: string,\n propertyKey: string\n): Promise {\n const propsFile = path.join(projectNativeRoot, ANDROID_PROPERTIES_FILE);\n try {\n const contents = await fs.promises.readFile(propsFile, 'utf8');\n const propertyValue = searchGradlePropertyFirst(contents, propertyKey);\n if (propertyValue) {\n return propertyValue;\n }\n } catch {}\n return null;\n}\n\n/**\n * Converts the package name to Android's project name.\n * `/` path will transform as `-`\n *\n * Example: `@expo/example` + `android/build.gradle` → `expo-example`\n */\nexport function convertPackageToProjectName(packageName: string): string {\n return packageName.replace(/^@/g, '').replace(/\\W+/g, '-');\n}\n\n/**\n * Converts the package name and gradle file path to Android's project name.\n * `$` to indicate subprojects\n * `/` path will transform as `-`\n *\n * Example: `@expo/example` + `android/build.gradle` → `expo-example`\n *\n * Example: multiple projects\n * - `expo-test` + `android/build.gradle` → `react-native-third-party`\n * - `expo-test` + `subproject/build.gradle` → `react-native-third-party$subproject`\n */\nexport function convertPackageWithGradleToProjectName(\n packageName: string,\n buildGradleFile: string\n): string {\n const name = convertPackageToProjectName(packageName);\n const baseDir = path.dirname(buildGradleFile).replace(/\\//g, '-');\n return baseDir === 'android' ? name : `${name}$${baseDir}`;\n}\n\n/**\n * Given the contents of a `gradle.properties` file,\n * searches for a property with the given name.\n *\n * This function will return the first property found with the given name.\n * The implementation follows config-plugins and\n * tries to align the behavior with the `withGradleProperties` plugin.\n */\nexport function searchGradlePropertyFirst(contents: string, propertyName: string): string | null {\n const lines = contents.split('\\n');\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (line && !line.startsWith('#')) {\n const eok = line.indexOf('=');\n const key = line.slice(0, eok);\n if (key === propertyName) {\n const value = line.slice(eok + 1, line.length);\n return value;\n }\n }\n }\n return null;\n}\n"]} \ No newline at end of file diff --git a/packages/expo-modules-autolinking/build/reactNativeConfig/androidResolver.js b/packages/expo-modules-autolinking/build/reactNativeConfig/androidResolver.js index 104c5ee82a7ddb..a46f4f0d00493c 100644 --- a/packages/expo-modules-autolinking/build/reactNativeConfig/androidResolver.js +++ b/packages/expo-modules-autolinking/build/reactNativeConfig/androidResolver.js @@ -12,6 +12,7 @@ exports.parseComponentDescriptorsAsync = parseComponentDescriptorsAsync; exports.findGradleAndManifestAsync = findGradleAndManifestAsync; const promises_1 = __importDefault(require("fs/promises")); const path_1 = __importDefault(require("path")); +const concurrency_1 = require("../concurrency"); const utils_1 = require("../utils"); async function resolveDependencyConfigImplAndroidAsync(packageRoot, reactNativeConfig, expoModuleConfig) { if (reactNativeConfig === null) { @@ -53,7 +54,7 @@ async function resolveDependencyConfigImplAndroidAsync(packageRoot, reactNativeC reactNativeConfig?.packageImportPath || `import ${packageName}.${nativePackageClassName};`; packageInstance = reactNativeConfig?.packageInstance || `new ${nativePackageClassName}()`; } - const packageJson = JSON.parse(await promises_1.default.readFile(path_1.default.join(packageRoot, 'package.json'), 'utf8')); + const packageJson = await (0, utils_1.loadPackageJson)((0, utils_1.fastJoin)(packageRoot, 'package.json')); const buildTypes = reactNativeConfig?.buildTypes || []; const dependencyConfiguration = reactNativeConfig?.dependencyConfiguration; const libraryName = reactNativeConfig?.libraryName || (await parseLibraryNameAsync(androidDir, packageJson)); @@ -208,7 +209,7 @@ async function parseComponentDescriptorsAsync(packageRoot, packageJson) { const results = new Set(); for await (const entry of (0, utils_1.scanFilesRecursively)(jsRoot)) { if (extRe.test(entry.name)) { - const contents = await promises_1.default.readFile(entry.path); + const contents = await promises_1.default.readFile(entry.path, 'utf8'); const matched = matchComponentDescriptors(entry.path, contents); if (matched) { results.add(matched); @@ -219,12 +220,11 @@ async function parseComponentDescriptorsAsync(packageRoot, packageJson) { } let lazyCodegenComponentRegex = null; function matchComponentDescriptors(_filePath, contents) { - const fileContents = contents.toString(); if (!lazyCodegenComponentRegex) { lazyCodegenComponentRegex = /codegenNativeComponent(<.*>)?\s*\(\s*["'`](\w+)["'`](,?[\s\S]+interfaceOnly:\s*(\w+))?/m; } - const match = fileContents.match(lazyCodegenComponentRegex); + const match = contents.match(lazyCodegenComponentRegex); if (!(match?.[4] === 'true') && match?.[2]) { return `${match[2]}ComponentDescriptor`; } @@ -259,7 +259,7 @@ const findAndroidManifestsAsync = async (targetPath) => { return manifestPaths.sort((a, b) => a.localeCompare(b)); }; const getFileCandidatesAsync = async (targetPath, fileNames) => { - const gradlePaths = await Promise.all(fileNames.map((fileName) => (0, utils_1.fileExistsAsync)(path_1.default.join(targetPath, fileName)))); + const gradlePaths = await (0, concurrency_1.taskAll)(fileNames, (fileName) => (0, utils_1.fileExistsAsync)(path_1.default.join(targetPath, fileName))); return gradlePaths.filter((file) => file != null).sort((a, b) => a.localeCompare(b)); }; async function findGradleAndManifestAsync({ androidDir, isLibrary, }) { diff --git a/packages/expo-modules-autolinking/build/reactNativeConfig/androidResolver.js.map b/packages/expo-modules-autolinking/build/reactNativeConfig/androidResolver.js.map index 3f06cff35b5aeb..282411e008025d 100644 --- a/packages/expo-modules-autolinking/build/reactNativeConfig/androidResolver.js.map +++ b/packages/expo-modules-autolinking/build/reactNativeConfig/androidResolver.js.map @@ -1 +1 @@ -{"version":3,"file":"androidResolver.js","sourceRoot":"","sources":["../../src/reactNativeConfig/androidResolver.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs/promises';\nimport path from 'path';\n\nimport type {\n RNConfigDependencyAndroid,\n RNConfigReactNativePlatformsConfigAndroid,\n} from './reactNativeConfig.types';\nimport type { ExpoModuleConfig } from '../ExpoModuleConfig';\nimport { scanFilesRecursively, fileExistsAsync } from '../utils';\n\nexport async function resolveDependencyConfigImplAndroidAsync(\n packageRoot: string,\n reactNativeConfig: RNConfigReactNativePlatformsConfigAndroid | null | undefined,\n expoModuleConfig?: ExpoModuleConfig | null\n): Promise {\n if (reactNativeConfig === null) {\n // Skip autolinking for this package.\n return null;\n }\n\n // NOTE(@kitten): We allow `reactNativeConfig === undefined` here. That indicates a missing config file\n // However, React Native modules with left out config files are explicitly supported and valid\n\n const sourceDir = reactNativeConfig?.sourceDir || 'android';\n const androidDir = path.join(packageRoot, sourceDir);\n const { gradle, manifest } = await findGradleAndManifestAsync({ androidDir, isLibrary: true });\n\n const isPureCxxDependency =\n reactNativeConfig?.cxxModuleCMakeListsModuleName != null &&\n reactNativeConfig?.cxxModuleCMakeListsPath != null &&\n reactNativeConfig?.cxxModuleHeaderName != null &&\n !manifest &&\n !gradle;\n\n if (!manifest && !gradle && !isPureCxxDependency) {\n return null;\n }\n\n if (reactNativeConfig === undefined && expoModuleConfig?.supportsPlatform('android')) {\n if (!!gradle && !expoModuleConfig?.rawConfig.android?.gradlePath) {\n // If the React Native module has a gradle file and the Expo module doesn't redirect it,\n // they will conflict and we can't link both at the same time\n return null;\n }\n }\n\n let packageInstance: string | null = null;\n let packageImportPath: string | null = null;\n if (!isPureCxxDependency) {\n const packageName =\n reactNativeConfig?.packageName || (await parsePackageNameAsync(manifest, gradle));\n if (!packageName) {\n return null;\n }\n const nativePackageClassName = await parseNativePackageClassNameAsync(packageRoot, androidDir);\n if (!nativePackageClassName) {\n return null;\n }\n packageImportPath =\n reactNativeConfig?.packageImportPath || `import ${packageName}.${nativePackageClassName};`;\n packageInstance = reactNativeConfig?.packageInstance || `new ${nativePackageClassName}()`;\n }\n\n const packageJson = JSON.parse(await fs.readFile(path.join(packageRoot, 'package.json'), 'utf8'));\n const buildTypes = reactNativeConfig?.buildTypes || [];\n const dependencyConfiguration = reactNativeConfig?.dependencyConfiguration;\n const libraryName =\n reactNativeConfig?.libraryName || (await parseLibraryNameAsync(androidDir, packageJson));\n const componentDescriptors =\n reactNativeConfig?.componentDescriptors ||\n (await parseComponentDescriptorsAsync(packageRoot, packageJson));\n let cmakeListsPath = reactNativeConfig?.cmakeListsPath\n ? path.join(androidDir, reactNativeConfig?.cmakeListsPath)\n : path.join(androidDir, 'build/generated/source/codegen/jni/CMakeLists.txt');\n const cxxModuleCMakeListsModuleName = reactNativeConfig?.cxxModuleCMakeListsModuleName || null;\n const cxxModuleHeaderName = reactNativeConfig?.cxxModuleHeaderName || null;\n let cxxModuleCMakeListsPath = reactNativeConfig?.cxxModuleCMakeListsPath\n ? path.join(androidDir, reactNativeConfig?.cxxModuleCMakeListsPath)\n : null;\n if (process.platform === 'win32') {\n cmakeListsPath = cmakeListsPath.replace(/\\\\/g, '/');\n if (cxxModuleCMakeListsPath) {\n cxxModuleCMakeListsPath = cxxModuleCMakeListsPath.replace(/\\\\/g, '/');\n }\n }\n\n const result: RNConfigDependencyAndroid = {\n sourceDir: androidDir,\n packageImportPath,\n packageInstance,\n dependencyConfiguration,\n buildTypes,\n libraryName,\n componentDescriptors,\n cmakeListsPath,\n cxxModuleCMakeListsModuleName,\n cxxModuleCMakeListsPath,\n cxxModuleHeaderName,\n isPureCxxDependency,\n };\n if (!result.libraryName) {\n delete result.libraryName;\n }\n if (!result.dependencyConfiguration) {\n delete result.dependencyConfiguration;\n }\n return result;\n}\n\n/**\n * Parse the `RNConfigDependencyAndroid.packageName`\n */\nexport async function parsePackageNameAsync(\n manifestPath: string | null,\n gradlePath: string | null\n): Promise {\n if (gradlePath) {\n const gradleContents = await fs.readFile(gradlePath, 'utf8');\n const match = gradleContents.match(/namespace\\s*[=]*\\s*[\"'](.+?)[\"']/);\n if (match) {\n return match[1];\n }\n }\n if (manifestPath) {\n const manifestContents = await fs.readFile(manifestPath, 'utf8');\n const match = manifestContents.match(/package=\"(.+?)\"/);\n if (match) {\n return match[1];\n }\n }\n return null;\n}\n\n/**\n * Parse the Java or Kotlin class name to for `ReactPackage` or `(Base|Turbo)ReactPackage`.\n */\nexport async function parseNativePackageClassNameAsync(\n packageRoot: string,\n androidDir: string\n): Promise {\n // Search for **/*Package.{java,kt} files first\n for await (const entry of scanFilesRecursively(androidDir, undefined, true)) {\n if (entry.name.endsWith('Package.java') || entry.name.endsWith('Package.kt')) {\n try {\n const contents = await fs.readFile(entry.path);\n const matched = matchNativePackageClassName(entry.path, contents);\n if (matched) {\n return matched;\n }\n } catch {\n continue;\n }\n }\n }\n\n // Early return if the module is an Expo module\n if (await fileExistsAsync(path.join(packageRoot, 'expo-module.config.json'))) {\n return null;\n }\n\n // Search all **/*.{java,kt} files\n for await (const entry of scanFilesRecursively(androidDir, undefined, true)) {\n if (entry.name.endsWith('.java') || entry.name.endsWith('.kt')) {\n const contents = await fs.readFile(entry.path);\n const matched = matchNativePackageClassName(entry.path, contents);\n if (matched) {\n return matched;\n }\n }\n }\n return null;\n}\n\nlet lazyReactPackageRegex: RegExp | null = null;\nlet lazyTurboReactPackageRegex: RegExp | null = null;\nexport function matchNativePackageClassName(_filePath: string, contents: Buffer): string | null {\n const fileContents = contents.toString();\n\n // [0] Match ReactPackage\n if (!lazyReactPackageRegex) {\n lazyReactPackageRegex =\n /class\\s+(\\w+[^(\\s]*)[\\s\\w():]*(\\s+implements\\s+|:)[\\s\\w():,]*[^{]*ReactPackage/;\n }\n const matchReactPackage = fileContents.match(lazyReactPackageRegex);\n if (matchReactPackage) {\n return matchReactPackage[1];\n }\n\n // [1] Match (Base|Turbo)ReactPackage\n if (!lazyTurboReactPackageRegex) {\n lazyTurboReactPackageRegex =\n /class\\s+(\\w+[^(\\s]*)[\\s\\w():]*(\\s+extends\\s+|:)[\\s\\w():,]*[^{]*(Base|Turbo)ReactPackage/;\n }\n const matchTurboReactPackage = fileContents.match(lazyTurboReactPackageRegex);\n if (matchTurboReactPackage) {\n return matchTurboReactPackage[1];\n }\n\n return null;\n}\n\nexport async function parseLibraryNameAsync(\n androidDir: string,\n packageJson: any\n): Promise {\n // [0] `codegenConfig.name` from package.json\n if (packageJson.codegenConfig?.name) {\n return packageJson.codegenConfig.name;\n }\n\n const libraryNameRegExp = /libraryName = [\"'](.+)[\"']/;\n const gradlePath = path.join(androidDir, 'build.gradle');\n // [1] `libraryName` from build.gradle\n if (await fileExistsAsync(gradlePath)) {\n const buildGradleContents = await fs.readFile(gradlePath, 'utf8');\n const match = buildGradleContents.match(libraryNameRegExp);\n if (match) {\n return match[1];\n }\n }\n\n // [2] `libraryName` from build.gradle.kts\n const gradleKtsPath = path.join(androidDir, 'build.gradle.kts');\n if (await fileExistsAsync(gradleKtsPath)) {\n const buildGradleContents = await fs.readFile(gradleKtsPath, 'utf8');\n const match = buildGradleContents.match(libraryNameRegExp);\n if (match) {\n return match[1];\n }\n }\n\n return null;\n}\n\nexport async function parseComponentDescriptorsAsync(\n packageRoot: string,\n packageJson: any\n): Promise {\n const jsRoot = packageJson?.codegenConfig?.jsSrcsDir\n ? path.join(packageRoot, packageJson.codegenConfig.jsSrcsDir)\n : packageRoot;\n const extRe = /\\.[tj]sx?$/;\n const results = new Set();\n for await (const entry of scanFilesRecursively(jsRoot)) {\n if (extRe.test(entry.name)) {\n const contents = await fs.readFile(entry.path);\n const matched = matchComponentDescriptors(entry.path, contents);\n if (matched) {\n results.add(matched);\n }\n }\n }\n return [...results].sort((a, b) => a.localeCompare(b));\n}\n\nlet lazyCodegenComponentRegex: RegExp | null = null;\nfunction matchComponentDescriptors(_filePath: string, contents: Buffer): string | null {\n const fileContents = contents.toString();\n\n if (!lazyCodegenComponentRegex) {\n lazyCodegenComponentRegex =\n /codegenNativeComponent(<.*>)?\\s*\\(\\s*[\"'`](\\w+)[\"'`](,?[\\s\\S]+interfaceOnly:\\s*(\\w+))?/m;\n }\n const match = fileContents.match(lazyCodegenComponentRegex);\n if (!(match?.[4] === 'true') && match?.[2]) {\n return `${match[2]}ComponentDescriptor`;\n }\n return null;\n}\n\nconst findAndroidManifestsAsync = async (targetPath: string) => {\n const files = scanFilesRecursively(targetPath, (parentPath, name) => {\n switch (name) {\n case 'build':\n case 'debug':\n case 'Pods':\n return false;\n case 'Examples':\n case 'examples':\n // Only ignore top-level examples directories in `targetPath` but not nested ones\n return parentPath !== targetPath;\n case 'android':\n return !/[\\\\/]sdks[\\\\/]hermes$/.test(parentPath);\n case 'androidTest':\n case 'test':\n return !/[\\\\/]src$/.test(parentPath);\n default:\n return true;\n }\n });\n const manifestPaths: string[] = [];\n for await (const entry of files) {\n if (entry.name === 'AndroidManifest.xml') {\n manifestPaths.push(entry.path);\n }\n }\n return manifestPaths.sort((a, b) => a.localeCompare(b));\n};\n\nconst getFileCandidatesAsync = async (targetPath: string, fileNames: string[]) => {\n const gradlePaths = await Promise.all(\n fileNames.map((fileName) => fileExistsAsync(path.join(targetPath, fileName)))\n );\n return gradlePaths.filter((file) => file != null).sort((a, b) => a.localeCompare(b));\n};\n\nexport async function findGradleAndManifestAsync({\n androidDir,\n isLibrary,\n}: {\n androidDir: string;\n isLibrary: boolean;\n}): Promise<{ gradle: string | null; manifest: string | null }> {\n const [manifests, gradles] = await Promise.all([\n findAndroidManifestsAsync(androidDir),\n getFileCandidatesAsync(isLibrary ? androidDir : path.join(androidDir, 'app'), [\n 'build.gradle',\n 'build.gradle.kts',\n ]),\n ]);\n // TODO(@kitten): We can't optimise this because of the prior `includes()` pattern. Is this meant to be startsWith?\n const manifest =\n manifests.find((manifest) => manifest.includes('src/main/')) ??\n manifests.sort((a, b) => a.localeCompare(b))[0];\n const gradle = gradles.sort((a, b) => a.localeCompare(b))[0];\n return { gradle: gradle || null, manifest: manifest || null };\n}\n"]} \ No newline at end of file +{"version":3,"file":"androidResolver.js","sourceRoot":"","sources":["../../src/reactNativeConfig/androidResolver.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs/promises';\nimport path from 'path';\n\nimport type {\n RNConfigDependencyAndroid,\n RNConfigReactNativePlatformsConfigAndroid,\n} from './reactNativeConfig.types';\nimport type { ExpoModuleConfig } from '../ExpoModuleConfig';\nimport { taskAll } from '../concurrency';\nimport { scanFilesRecursively, fileExistsAsync, fastJoin, loadPackageJson } from '../utils';\n\nexport async function resolveDependencyConfigImplAndroidAsync(\n packageRoot: string,\n reactNativeConfig: RNConfigReactNativePlatformsConfigAndroid | null | undefined,\n expoModuleConfig?: ExpoModuleConfig | null\n): Promise {\n if (reactNativeConfig === null) {\n // Skip autolinking for this package.\n return null;\n }\n\n // NOTE(@kitten): We allow `reactNativeConfig === undefined` here. That indicates a missing config file\n // However, React Native modules with left out config files are explicitly supported and valid\n\n const sourceDir = reactNativeConfig?.sourceDir || 'android';\n const androidDir = path.join(packageRoot, sourceDir);\n const { gradle, manifest } = await findGradleAndManifestAsync({ androidDir, isLibrary: true });\n\n const isPureCxxDependency =\n reactNativeConfig?.cxxModuleCMakeListsModuleName != null &&\n reactNativeConfig?.cxxModuleCMakeListsPath != null &&\n reactNativeConfig?.cxxModuleHeaderName != null &&\n !manifest &&\n !gradle;\n\n if (!manifest && !gradle && !isPureCxxDependency) {\n return null;\n }\n\n if (reactNativeConfig === undefined && expoModuleConfig?.supportsPlatform('android')) {\n if (!!gradle && !expoModuleConfig?.rawConfig.android?.gradlePath) {\n // If the React Native module has a gradle file and the Expo module doesn't redirect it,\n // they will conflict and we can't link both at the same time\n return null;\n }\n }\n\n let packageInstance: string | null = null;\n let packageImportPath: string | null = null;\n if (!isPureCxxDependency) {\n const packageName =\n reactNativeConfig?.packageName || (await parsePackageNameAsync(manifest, gradle));\n if (!packageName) {\n return null;\n }\n const nativePackageClassName = await parseNativePackageClassNameAsync(packageRoot, androidDir);\n if (!nativePackageClassName) {\n return null;\n }\n packageImportPath =\n reactNativeConfig?.packageImportPath || `import ${packageName}.${nativePackageClassName};`;\n packageInstance = reactNativeConfig?.packageInstance || `new ${nativePackageClassName}()`;\n }\n\n const packageJson = await loadPackageJson(fastJoin(packageRoot, 'package.json'));\n const buildTypes = reactNativeConfig?.buildTypes || [];\n const dependencyConfiguration = reactNativeConfig?.dependencyConfiguration;\n const libraryName =\n reactNativeConfig?.libraryName || (await parseLibraryNameAsync(androidDir, packageJson));\n const componentDescriptors =\n reactNativeConfig?.componentDescriptors ||\n (await parseComponentDescriptorsAsync(packageRoot, packageJson));\n let cmakeListsPath = reactNativeConfig?.cmakeListsPath\n ? path.join(androidDir, reactNativeConfig?.cmakeListsPath)\n : path.join(androidDir, 'build/generated/source/codegen/jni/CMakeLists.txt');\n const cxxModuleCMakeListsModuleName = reactNativeConfig?.cxxModuleCMakeListsModuleName || null;\n const cxxModuleHeaderName = reactNativeConfig?.cxxModuleHeaderName || null;\n let cxxModuleCMakeListsPath = reactNativeConfig?.cxxModuleCMakeListsPath\n ? path.join(androidDir, reactNativeConfig?.cxxModuleCMakeListsPath)\n : null;\n if (process.platform === 'win32') {\n cmakeListsPath = cmakeListsPath.replace(/\\\\/g, '/');\n if (cxxModuleCMakeListsPath) {\n cxxModuleCMakeListsPath = cxxModuleCMakeListsPath.replace(/\\\\/g, '/');\n }\n }\n\n const result: RNConfigDependencyAndroid = {\n sourceDir: androidDir,\n packageImportPath,\n packageInstance,\n dependencyConfiguration,\n buildTypes,\n libraryName,\n componentDescriptors,\n cmakeListsPath,\n cxxModuleCMakeListsModuleName,\n cxxModuleCMakeListsPath,\n cxxModuleHeaderName,\n isPureCxxDependency,\n };\n if (!result.libraryName) {\n delete result.libraryName;\n }\n if (!result.dependencyConfiguration) {\n delete result.dependencyConfiguration;\n }\n return result;\n}\n\n/**\n * Parse the `RNConfigDependencyAndroid.packageName`\n */\nexport async function parsePackageNameAsync(\n manifestPath: string | null,\n gradlePath: string | null\n): Promise {\n if (gradlePath) {\n const gradleContents = await fs.readFile(gradlePath, 'utf8');\n const match = gradleContents.match(/namespace\\s*[=]*\\s*[\"'](.+?)[\"']/);\n if (match) {\n return match[1];\n }\n }\n if (manifestPath) {\n const manifestContents = await fs.readFile(manifestPath, 'utf8');\n const match = manifestContents.match(/package=\"(.+?)\"/);\n if (match) {\n return match[1];\n }\n }\n return null;\n}\n\n/**\n * Parse the Java or Kotlin class name to for `ReactPackage` or `(Base|Turbo)ReactPackage`.\n */\nexport async function parseNativePackageClassNameAsync(\n packageRoot: string,\n androidDir: string\n): Promise {\n // Search for **/*Package.{java,kt} files first\n for await (const entry of scanFilesRecursively(androidDir, undefined, true)) {\n if (entry.name.endsWith('Package.java') || entry.name.endsWith('Package.kt')) {\n try {\n const contents = await fs.readFile(entry.path);\n const matched = matchNativePackageClassName(entry.path, contents);\n if (matched) {\n return matched;\n }\n } catch {\n continue;\n }\n }\n }\n\n // Early return if the module is an Expo module\n if (await fileExistsAsync(path.join(packageRoot, 'expo-module.config.json'))) {\n return null;\n }\n\n // Search all **/*.{java,kt} files\n for await (const entry of scanFilesRecursively(androidDir, undefined, true)) {\n if (entry.name.endsWith('.java') || entry.name.endsWith('.kt')) {\n const contents = await fs.readFile(entry.path);\n const matched = matchNativePackageClassName(entry.path, contents);\n if (matched) {\n return matched;\n }\n }\n }\n return null;\n}\n\nlet lazyReactPackageRegex: RegExp | null = null;\nlet lazyTurboReactPackageRegex: RegExp | null = null;\nexport function matchNativePackageClassName(_filePath: string, contents: Buffer): string | null {\n const fileContents = contents.toString();\n\n // [0] Match ReactPackage\n if (!lazyReactPackageRegex) {\n lazyReactPackageRegex =\n /class\\s+(\\w+[^(\\s]*)[\\s\\w():]*(\\s+implements\\s+|:)[\\s\\w():,]*[^{]*ReactPackage/;\n }\n const matchReactPackage = fileContents.match(lazyReactPackageRegex);\n if (matchReactPackage) {\n return matchReactPackage[1];\n }\n\n // [1] Match (Base|Turbo)ReactPackage\n if (!lazyTurboReactPackageRegex) {\n lazyTurboReactPackageRegex =\n /class\\s+(\\w+[^(\\s]*)[\\s\\w():]*(\\s+extends\\s+|:)[\\s\\w():,]*[^{]*(Base|Turbo)ReactPackage/;\n }\n const matchTurboReactPackage = fileContents.match(lazyTurboReactPackageRegex);\n if (matchTurboReactPackage) {\n return matchTurboReactPackage[1];\n }\n\n return null;\n}\n\nexport async function parseLibraryNameAsync(\n androidDir: string,\n packageJson: any\n): Promise {\n // [0] `codegenConfig.name` from package.json\n if (packageJson.codegenConfig?.name) {\n return packageJson.codegenConfig.name;\n }\n\n const libraryNameRegExp = /libraryName = [\"'](.+)[\"']/;\n const gradlePath = path.join(androidDir, 'build.gradle');\n // [1] `libraryName` from build.gradle\n if (await fileExistsAsync(gradlePath)) {\n const buildGradleContents = await fs.readFile(gradlePath, 'utf8');\n const match = buildGradleContents.match(libraryNameRegExp);\n if (match) {\n return match[1];\n }\n }\n\n // [2] `libraryName` from build.gradle.kts\n const gradleKtsPath = path.join(androidDir, 'build.gradle.kts');\n if (await fileExistsAsync(gradleKtsPath)) {\n const buildGradleContents = await fs.readFile(gradleKtsPath, 'utf8');\n const match = buildGradleContents.match(libraryNameRegExp);\n if (match) {\n return match[1];\n }\n }\n\n return null;\n}\n\nexport async function parseComponentDescriptorsAsync(\n packageRoot: string,\n packageJson: any\n): Promise {\n const jsRoot = packageJson?.codegenConfig?.jsSrcsDir\n ? path.join(packageRoot, packageJson.codegenConfig.jsSrcsDir)\n : packageRoot;\n const extRe = /\\.[tj]sx?$/;\n const results = new Set();\n for await (const entry of scanFilesRecursively(jsRoot)) {\n if (extRe.test(entry.name)) {\n const contents = await fs.readFile(entry.path, 'utf8');\n const matched = matchComponentDescriptors(entry.path, contents);\n if (matched) {\n results.add(matched);\n }\n }\n }\n return [...results].sort((a, b) => a.localeCompare(b));\n}\n\nlet lazyCodegenComponentRegex: RegExp | null = null;\nfunction matchComponentDescriptors(_filePath: string, contents: string): string | null {\n if (!lazyCodegenComponentRegex) {\n lazyCodegenComponentRegex =\n /codegenNativeComponent(<.*>)?\\s*\\(\\s*[\"'`](\\w+)[\"'`](,?[\\s\\S]+interfaceOnly:\\s*(\\w+))?/m;\n }\n const match = contents.match(lazyCodegenComponentRegex);\n if (!(match?.[4] === 'true') && match?.[2]) {\n return `${match[2]}ComponentDescriptor`;\n }\n return null;\n}\n\nconst findAndroidManifestsAsync = async (targetPath: string) => {\n const files = scanFilesRecursively(targetPath, (parentPath, name) => {\n switch (name) {\n case 'build':\n case 'debug':\n case 'Pods':\n return false;\n case 'Examples':\n case 'examples':\n // Only ignore top-level examples directories in `targetPath` but not nested ones\n return parentPath !== targetPath;\n case 'android':\n return !/[\\\\/]sdks[\\\\/]hermes$/.test(parentPath);\n case 'androidTest':\n case 'test':\n return !/[\\\\/]src$/.test(parentPath);\n default:\n return true;\n }\n });\n const manifestPaths: string[] = [];\n for await (const entry of files) {\n if (entry.name === 'AndroidManifest.xml') {\n manifestPaths.push(entry.path);\n }\n }\n return manifestPaths.sort((a, b) => a.localeCompare(b));\n};\n\nconst getFileCandidatesAsync = async (targetPath: string, fileNames: string[]) => {\n const gradlePaths = await taskAll(fileNames, (fileName) =>\n fileExistsAsync(path.join(targetPath, fileName))\n );\n return gradlePaths.filter((file) => file != null).sort((a, b) => a.localeCompare(b));\n};\n\nexport async function findGradleAndManifestAsync({\n androidDir,\n isLibrary,\n}: {\n androidDir: string;\n isLibrary: boolean;\n}): Promise<{ gradle: string | null; manifest: string | null }> {\n const [manifests, gradles] = await Promise.all([\n findAndroidManifestsAsync(androidDir),\n getFileCandidatesAsync(isLibrary ? androidDir : path.join(androidDir, 'app'), [\n 'build.gradle',\n 'build.gradle.kts',\n ]),\n ]);\n // TODO(@kitten): We can't optimise this because of the prior `includes()` pattern. Is this meant to be startsWith?\n const manifest =\n manifests.find((manifest) => manifest.includes('src/main/')) ??\n manifests.sort((a, b) => a.localeCompare(b))[0];\n const gradle = gradles.sort((a, b) => a.localeCompare(b))[0];\n return { gradle: gradle || null, manifest: manifest || null };\n}\n"]} \ No newline at end of file diff --git a/packages/expo-modules-autolinking/build/reactNativeConfig/config.d.ts b/packages/expo-modules-autolinking/build/reactNativeConfig/config.d.ts index 5ef920a0f32bcc..bc6c933eeabc1d 100644 --- a/packages/expo-modules-autolinking/build/reactNativeConfig/config.d.ts +++ b/packages/expo-modules-autolinking/build/reactNativeConfig/config.d.ts @@ -1,4 +1,7 @@ +import type { RNConfigReactNativeConfig } from './reactNativeConfig.types'; +type LoadConfigAsync = (packageRoot: string) => Promise; /** * Load the `react-native.config.js` or `react-native.config.ts` from the package. */ -export declare const loadConfigAsync: (input: string, ...args: any[]) => Promise; +export declare const loadConfigAsync: LoadConfigAsync; +export {}; diff --git a/packages/expo-modules-autolinking/build/reactNativeConfig/config.js b/packages/expo-modules-autolinking/build/reactNativeConfig/config.js index 42df826fff8436..b6015c16d2be78 100644 --- a/packages/expo-modules-autolinking/build/reactNativeConfig/config.js +++ b/packages/expo-modules-autolinking/build/reactNativeConfig/config.js @@ -7,12 +7,13 @@ exports.loadConfigAsync = void 0; const require_utils_1 = require("@expo/require-utils"); const promises_1 = __importDefault(require("fs/promises")); const path_1 = __importDefault(require("path")); +const memoize_1 = require("../memoize"); const utils_1 = require("../utils"); const mockedNativeModules = path_1.default.join(__dirname, '..', '..', 'node_modules_mock'); /** * Load the `react-native.config.js` or `react-native.config.ts` from the package. */ -exports.loadConfigAsync = (0, utils_1.memoize)(async function loadConfigAsync(packageRoot) { +exports.loadConfigAsync = (0, memoize_1.memoize)(async function loadConfigAsync(packageRoot) { const configPath = (await Promise.all(['react-native.config.js', 'react-native.config.ts'].map(async (fileName) => { const file = path_1.default.join(packageRoot, fileName); return (await (0, utils_1.fileExistsAsync)(file)) ? file : null; diff --git a/packages/expo-modules-autolinking/build/reactNativeConfig/config.js.map b/packages/expo-modules-autolinking/build/reactNativeConfig/config.js.map index df95c8dd57d7ba..204b761fa778fa 100644 --- a/packages/expo-modules-autolinking/build/reactNativeConfig/config.js.map +++ b/packages/expo-modules-autolinking/build/reactNativeConfig/config.js.map @@ -1 +1 @@ -{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/reactNativeConfig/config.ts"],"names":[],"mappings":";;;;;;AAAA,uDAAiD;AACjD,2DAA6B;AAC7B,gDAAwB;AAExB,oCAAoD;AAGpD,MAAM,mBAAmB,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,mBAAmB,CAAC,CAAC;AAElF;;GAEG;AACU,QAAA,eAAe,GAAG,IAAA,eAAO,EAAC,KAAK,UAAU,eAAe,CAEnE,WAAmB;IACnB,MAAM,UAAU,GAAG,CACjB,MAAM,OAAO,CAAC,GAAG,CACf,CAAC,wBAAwB,EAAE,wBAAwB,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;QAC1E,MAAM,IAAI,GAAG,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;QAC9C,OAAO,CAAC,MAAM,IAAA,uBAAe,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IACrD,CAAC,CAAC,CACH,CACF,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC;IAC/B,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,GAAG,GAAG,IAAA,0BAAU,EACpB,MAAM,kBAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,EACrC,UAAU;QACV,+DAA+D;QAC/D,0FAA0F;QAC1F,8DAA8D;QAC9D,EAAE,KAAK,EAAE,CAAC,mBAAmB,CAAC,EAAE,CACjC,CAAC;QACF,OAAO,GAAG,CAAC,OAAO,IAAI,GAAG,IAAI,IAAI,CAAC;IACpC,CAAC;SAAM,CAAC;QACN,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC,CAAC,CAAC","sourcesContent":["import { evalModule } from '@expo/require-utils';\nimport fs from 'fs/promises';\nimport path from 'path';\n\nimport { memoize, fileExistsAsync } from '../utils';\nimport type { RNConfigReactNativeConfig } from './reactNativeConfig.types';\n\nconst mockedNativeModules = path.join(__dirname, '..', '..', 'node_modules_mock');\n\n/**\n * Load the `react-native.config.js` or `react-native.config.ts` from the package.\n */\nexport const loadConfigAsync = memoize(async function loadConfigAsync<\n T extends RNConfigReactNativeConfig,\n>(packageRoot: string): Promise {\n const configPath = (\n await Promise.all(\n ['react-native.config.js', 'react-native.config.ts'].map(async (fileName) => {\n const file = path.join(packageRoot, fileName);\n return (await fileExistsAsync(file)) ? file : null;\n })\n )\n ).find((path) => path != null);\n if (configPath) {\n const mod = evalModule(\n await fs.readFile(configPath, 'utf8'),\n configPath,\n // NOTE: We need to mock the Community CLI temporarily, because\n // some packages are checking the version of the CLI in the `react-native.config.js` file.\n // We can remove this once we remove this check from packages.\n { paths: [mockedNativeModules] }\n );\n return mod.default ?? mod ?? null;\n } else {\n return null;\n }\n});\n"]} \ No newline at end of file +{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/reactNativeConfig/config.ts"],"names":[],"mappings":";;;;;;AAAA,uDAAiD;AACjD,2DAA6B;AAC7B,gDAAwB;AAExB,wCAAqC;AACrC,oCAA2C;AAM3C,MAAM,mBAAmB,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,mBAAmB,CAAC,CAAC;AAMlF;;GAEG;AACU,QAAA,eAAe,GAAoB,IAAA,iBAAO,EAAC,KAAK,UAAU,eAAe,CAEpF,WAAmB;IACnB,MAAM,UAAU,GAAG,CACjB,MAAM,OAAO,CAAC,GAAG,CACf,CAAC,wBAAwB,EAAE,wBAAwB,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;QAC1E,MAAM,IAAI,GAAG,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;QAC9C,OAAO,CAAC,MAAM,IAAA,uBAAe,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IACrD,CAAC,CAAC,CACH,CACF,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC;IAC/B,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,GAAG,GAAG,IAAA,0BAAU,EACpB,MAAM,kBAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,EACrC,UAAU;QACV,+DAA+D;QAC/D,0FAA0F;QAC1F,8DAA8D;QAC9D,EAAE,KAAK,EAAE,CAAC,mBAAmB,CAAC,EAAE,CACjC,CAAC;QACF,OAAO,GAAG,CAAC,OAAO,IAAI,GAAG,IAAI,IAAI,CAAC;IACpC,CAAC;SAAM,CAAC;QACN,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC,CAAC,CAAC","sourcesContent":["import { evalModule } from '@expo/require-utils';\nimport fs from 'fs/promises';\nimport path from 'path';\n\nimport { memoize } from '../memoize';\nimport { fileExistsAsync } from '../utils';\nimport type {\n RNConfigReactNativeConfig,\n RNConfigReactNativeProjectConfig,\n} from './reactNativeConfig.types';\n\nconst mockedNativeModules = path.join(__dirname, '..', '..', 'node_modules_mock');\n\ntype LoadConfigAsync = (\n packageRoot: string\n) => Promise;\n\n/**\n * Load the `react-native.config.js` or `react-native.config.ts` from the package.\n */\nexport const loadConfigAsync: LoadConfigAsync = memoize(async function loadConfigAsync<\n T extends RNConfigReactNativeConfig,\n>(packageRoot: string): Promise {\n const configPath = (\n await Promise.all(\n ['react-native.config.js', 'react-native.config.ts'].map(async (fileName) => {\n const file = path.join(packageRoot, fileName);\n return (await fileExistsAsync(file)) ? file : null;\n })\n )\n ).find((path) => path != null);\n if (configPath) {\n const mod = evalModule(\n await fs.readFile(configPath, 'utf8'),\n configPath,\n // NOTE: We need to mock the Community CLI temporarily, because\n // some packages are checking the version of the CLI in the `react-native.config.js` file.\n // We can remove this once we remove this check from packages.\n { paths: [mockedNativeModules] }\n );\n return mod.default ?? mod ?? null;\n } else {\n return null;\n }\n});\n"]} \ No newline at end of file diff --git a/packages/expo-modules-autolinking/build/utils.d.ts b/packages/expo-modules-autolinking/build/utils.d.ts index 9ad423416f01cc..1a58b78bbf8e71 100644 --- a/packages/expo-modules-autolinking/build/utils.d.ts +++ b/packages/expo-modules-autolinking/build/utils.d.ts @@ -1,4 +1,3 @@ -export declare function memoize Promise>(fn: Fn): (input: string, ...args: any[]) => Promise; /** List filtered top-level files in `targetPath` (returns absolute paths) */ export declare function listFilesSorted(targetPath: string, filter: (basename: string) => boolean): Promise; /** List nested files in top-level directories in `targetPath` (returns relative paths) */ @@ -10,3 +9,10 @@ export declare function scanFilesRecursively(parentPath: string, includeDirector readonly name: string; }, void, unknown>; export declare const fileExistsAsync: (file: string) => Promise; +export declare const fastJoin: (from: string, append: string) => string; +export declare const maybeRealpath: (target: string) => Promise; +export type PackageJson = Record & { + name?: string; + version?: string; +}; +export declare const loadPackageJson: import("./memoize").MemoizableAsyncFn; diff --git a/packages/expo-modules-autolinking/build/utils.js b/packages/expo-modules-autolinking/build/utils.js index ce5604be7f741b..3cc18272d828af 100644 --- a/packages/expo-modules-autolinking/build/utils.js +++ b/packages/expo-modules-autolinking/build/utils.js @@ -3,30 +3,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -exports.fileExistsAsync = void 0; -exports.memoize = memoize; +exports.loadPackageJson = exports.maybeRealpath = exports.fastJoin = exports.fileExistsAsync = void 0; exports.listFilesSorted = listFilesSorted; exports.listFilesInDirectories = listFilesInDirectories; exports.scanFilesRecursively = scanFilesRecursively; const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); -const MAX_SIZE = 5_000; -function memoize(fn) { - const cache = new Map(); - return async (input, ...args) => { - if (!cache.has(input)) { - const result = await fn(input, ...args); - if (cache.size > MAX_SIZE) { - cache.clear(); - } - cache.set(input, result); - return result; - } - else { - return cache.get(input); - } - }; -} +const memoize_1 = require("./memoize"); /** List filtered top-level files in `targetPath` (returns absolute paths) */ async function listFilesSorted(targetPath, filter) { try { @@ -89,4 +72,29 @@ const fileExistsAsync = async (file) => { return stat?.isFile() ? file : null; }; exports.fileExistsAsync = fileExistsAsync; +exports.fastJoin = path_1.default.sep === '/' + ? (from, append) => `${from}${path_1.default.sep}${append}` + : (from, append) => `${from}${path_1.default.sep}${append[0] === '@' ? append.replace('/', path_1.default.sep) : append}`; +const maybeRealpath = async (target) => { + try { + return await fs_1.default.promises.realpath(target); + } + catch { + return null; + } +}; +exports.maybeRealpath = maybeRealpath; +exports.loadPackageJson = (0, memoize_1.memoize)(async function loadPackageJson(jsonPath) { + try { + const packageJsonText = await fs_1.default.promises.readFile(jsonPath, 'utf8'); + const json = JSON.parse(packageJsonText); + if (typeof json !== 'object' || json == null) { + return null; + } + return json; + } + catch { + return null; + } +}); //# sourceMappingURL=utils.js.map \ No newline at end of file diff --git a/packages/expo-modules-autolinking/build/utils.js.map b/packages/expo-modules-autolinking/build/utils.js.map index f213bd572dd513..5f7520c1ec8762 100644 --- a/packages/expo-modules-autolinking/build/utils.js.map +++ b/packages/expo-modules-autolinking/build/utils.js.map @@ -1 +1 @@ -{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs';\nimport path from 'path';\n\nconst MAX_SIZE = 5_000;\n\nexport function memoize Promise>(fn: Fn) {\n const cache = new Map>();\n return async (input: string, ...args: any[]) => {\n if (!cache.has(input)) {\n const result = await fn(input, ...args);\n if (cache.size > MAX_SIZE) {\n cache.clear();\n }\n cache.set(input, result);\n return result;\n } else {\n return cache.get(input);\n }\n };\n}\n\n/** List filtered top-level files in `targetPath` (returns absolute paths) */\nexport async function listFilesSorted(\n targetPath: string,\n filter: (basename: string) => boolean\n): Promise {\n try {\n // `readdir` isn't guaranteed to be sorted on Windows\n return (await fs.promises.readdir(targetPath, { withFileTypes: true }))\n .filter((entry) => entry.isFile() && filter(entry.name))\n .sort((a, b) => a.name.localeCompare(b.name))\n .map((entry) => path.join(targetPath, entry.name));\n } catch {\n return [];\n }\n}\n\n/** List nested files in top-level directories in `targetPath` (returns relative paths) */\nexport async function listFilesInDirectories(\n targetPath: string,\n filter: (basename: string) => boolean\n): Promise {\n return (\n await Promise.all(\n (await fs.promises.readdir(targetPath, { withFileTypes: true }))\n .filter((entry) => entry.isDirectory() && entry.name !== 'node_modules')\n .sort((a, b) => a.name.localeCompare(b.name))\n .map(async (directory) => {\n const entries = await fs.promises.readdir(path.join(targetPath, directory.name), {\n withFileTypes: true,\n });\n return entries\n .filter((entry) => entry.isFile() && filter(entry.name))\n .sort((a, b) => a.name.localeCompare(b.name))\n .map((entry) => path.join(directory.name, entry.name));\n })\n )\n ).flat(1);\n}\n\n/** Iterate folders recursively for files, optionally sorting results and filtering directories */\nexport async function* scanFilesRecursively(\n parentPath: string,\n includeDirectory?: (parentPath: string, name: string) => boolean,\n sort = !fs.opendir\n) {\n const queue = [parentPath];\n let targetPath: string | undefined;\n while (queue.length > 0 && (targetPath = queue.shift()) != null) {\n try {\n const entries = sort\n ? (await fs.promises.readdir(targetPath, { withFileTypes: true })).sort((a, b) =>\n a.name.localeCompare(b.name)\n )\n : await fs.promises.opendir(targetPath);\n for await (const entry of entries) {\n if (entry.isDirectory() && entry.name !== 'node_modules') {\n if (!includeDirectory || includeDirectory(targetPath, entry.name)) {\n queue.push(path.join(targetPath, entry.name));\n }\n } else if (entry.isFile()) {\n yield {\n path: path.join(targetPath, entry.name),\n parentPath: targetPath,\n name: entry.name,\n } as const;\n }\n }\n } catch {\n continue;\n }\n }\n}\n\nexport const fileExistsAsync = async (file: string): Promise => {\n const stat = await fs.promises.stat(file).catch(() => null);\n return stat?.isFile() ? file : null;\n};\n"]} \ No newline at end of file +{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;;;;;AAMA,0CAaC;AAGD,wDAoBC;AAGD,oDA+BC;AA5ED,4CAAoB;AACpB,gDAAwB;AAExB,uCAAoC;AAEpC,6EAA6E;AACtE,KAAK,UAAU,eAAe,CACnC,UAAkB,EAClB,MAAqC;IAErC,IAAI,CAAC;QACH,qDAAqD;QACrD,OAAO,CAAC,MAAM,YAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;aACpE,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;aACvD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;aAC5C,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,cAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,0FAA0F;AACnF,KAAK,UAAU,sBAAsB,CAC1C,UAAkB,EAClB,MAAqC;IAErC,OAAO,CACL,MAAM,OAAO,CAAC,GAAG,CACf,CAAC,MAAM,YAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;SAC7D,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,CAAC;SACvE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;SAC5C,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE;QACvB,MAAM,OAAO,GAAG,MAAM,YAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,cAAI,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE;YAC/E,aAAa,EAAE,IAAI;SACpB,CAAC,CAAC;QACH,OAAO,OAAO;aACX,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;aACvD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;aAC5C,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,cAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3D,CAAC,CAAC,CACL,CACF,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACZ,CAAC;AAED,kGAAkG;AAC3F,KAAK,SAAS,CAAC,CAAC,oBAAoB,CACzC,UAAkB,EAClB,gBAAgE,EAChE,IAAI,GAAG,CAAC,YAAE,CAAC,OAAO;IAElB,MAAM,KAAK,GAAG,CAAC,UAAU,CAAC,CAAC;IAC3B,IAAI,UAA8B,CAAC;IACnC,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;QAChE,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,IAAI;gBAClB,CAAC,CAAC,CAAC,MAAM,YAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAC7E,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAC7B;gBACH,CAAC,CAAC,MAAM,YAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;YAC1C,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAClC,IAAI,KAAK,CAAC,WAAW,EAAE,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;oBACzD,IAAI,CAAC,gBAAgB,IAAI,gBAAgB,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;wBAClE,KAAK,CAAC,IAAI,CAAC,cAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;oBAChD,CAAC;gBACH,CAAC;qBAAM,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;oBAC1B,MAAM;wBACJ,IAAI,EAAE,cAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC;wBACvC,UAAU,EAAE,UAAU;wBACtB,IAAI,EAAE,KAAK,CAAC,IAAI;qBACR,CAAC;gBACb,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;IACH,CAAC;AACH,CAAC;AAEM,MAAM,eAAe,GAAG,KAAK,EAAE,IAAY,EAA0B,EAAE;IAC5E,MAAM,IAAI,GAAG,MAAM,YAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAC5D,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AACtC,CAAC,CAAC;AAHW,QAAA,eAAe,mBAG1B;AAEW,QAAA,QAAQ,GACnB,cAAI,CAAC,GAAG,KAAK,GAAG;IACd,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,GAAG,IAAI,GAAG,cAAI,CAAC,GAAG,GAAG,MAAM,EAAE;IACjD,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CACf,GAAG,IAAI,GAAG,cAAI,CAAC,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,cAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;AAEnF,MAAM,aAAa,GAAG,KAAK,EAAE,MAAc,EAA0B,EAAE;IAC5E,IAAI,CAAC;QACH,OAAO,MAAM,YAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC,CAAC;AANW,QAAA,aAAa,iBAMxB;AAIW,QAAA,eAAe,GAAG,IAAA,iBAAO,EAAC,KAAK,UAAU,eAAe,CACnE,QAAgB;IAEhB,IAAI,CAAC;QACH,MAAM,eAAe,GAAG,MAAM,YAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACrE,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;QACzC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;YAC7C,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC,CAAC,CAAC","sourcesContent":["import fs from 'fs';\nimport path from 'path';\n\nimport { memoize } from './memoize';\n\n/** List filtered top-level files in `targetPath` (returns absolute paths) */\nexport async function listFilesSorted(\n targetPath: string,\n filter: (basename: string) => boolean\n): Promise {\n try {\n // `readdir` isn't guaranteed to be sorted on Windows\n return (await fs.promises.readdir(targetPath, { withFileTypes: true }))\n .filter((entry) => entry.isFile() && filter(entry.name))\n .sort((a, b) => a.name.localeCompare(b.name))\n .map((entry) => path.join(targetPath, entry.name));\n } catch {\n return [];\n }\n}\n\n/** List nested files in top-level directories in `targetPath` (returns relative paths) */\nexport async function listFilesInDirectories(\n targetPath: string,\n filter: (basename: string) => boolean\n): Promise {\n return (\n await Promise.all(\n (await fs.promises.readdir(targetPath, { withFileTypes: true }))\n .filter((entry) => entry.isDirectory() && entry.name !== 'node_modules')\n .sort((a, b) => a.name.localeCompare(b.name))\n .map(async (directory) => {\n const entries = await fs.promises.readdir(path.join(targetPath, directory.name), {\n withFileTypes: true,\n });\n return entries\n .filter((entry) => entry.isFile() && filter(entry.name))\n .sort((a, b) => a.name.localeCompare(b.name))\n .map((entry) => path.join(directory.name, entry.name));\n })\n )\n ).flat(1);\n}\n\n/** Iterate folders recursively for files, optionally sorting results and filtering directories */\nexport async function* scanFilesRecursively(\n parentPath: string,\n includeDirectory?: (parentPath: string, name: string) => boolean,\n sort = !fs.opendir\n) {\n const queue = [parentPath];\n let targetPath: string | undefined;\n while (queue.length > 0 && (targetPath = queue.shift()) != null) {\n try {\n const entries = sort\n ? (await fs.promises.readdir(targetPath, { withFileTypes: true })).sort((a, b) =>\n a.name.localeCompare(b.name)\n )\n : await fs.promises.opendir(targetPath);\n for await (const entry of entries) {\n if (entry.isDirectory() && entry.name !== 'node_modules') {\n if (!includeDirectory || includeDirectory(targetPath, entry.name)) {\n queue.push(path.join(targetPath, entry.name));\n }\n } else if (entry.isFile()) {\n yield {\n path: path.join(targetPath, entry.name),\n parentPath: targetPath,\n name: entry.name,\n } as const;\n }\n }\n } catch {\n continue;\n }\n }\n}\n\nexport const fileExistsAsync = async (file: string): Promise => {\n const stat = await fs.promises.stat(file).catch(() => null);\n return stat?.isFile() ? file : null;\n};\n\nexport const fastJoin: (from: string, append: string) => string =\n path.sep === '/'\n ? (from, append) => `${from}${path.sep}${append}`\n : (from, append) =>\n `${from}${path.sep}${append[0] === '@' ? append.replace('/', path.sep) : append}`;\n\nexport const maybeRealpath = async (target: string): Promise => {\n try {\n return await fs.promises.realpath(target);\n } catch {\n return null;\n }\n};\n\nexport type PackageJson = Record & { name?: string; version?: string };\n\nexport const loadPackageJson = memoize(async function loadPackageJson(\n jsonPath: string\n): Promise {\n try {\n const packageJsonText = await fs.promises.readFile(jsonPath, 'utf8');\n const json = JSON.parse(packageJsonText);\n if (typeof json !== 'object' || json == null) {\n return null;\n }\n return json;\n } catch {\n return null;\n }\n});\n"]} \ No newline at end of file diff --git a/packages/expo-modules-autolinking/src/ExpoModuleConfig.ts b/packages/expo-modules-autolinking/src/ExpoModuleConfig.ts index e20b3a9ab00a79..55c84c7d60105f 100644 --- a/packages/expo-modules-autolinking/src/ExpoModuleConfig.ts +++ b/packages/expo-modules-autolinking/src/ExpoModuleConfig.ts @@ -1,6 +1,7 @@ import fs from 'fs'; import path from 'path'; +import { memoize } from './memoize'; import { AndroidGradleAarProjectDescriptor, AndroidGradlePluginDescriptor, @@ -9,7 +10,6 @@ import { RawModuleConfigApple, SupportedPlatform, } from './types'; -import { memoize } from './utils'; function arrayize(value: T[] | T | undefined): T[] { if (Array.isArray(value)) { diff --git a/packages/expo-modules-autolinking/src/__tests__/concurrency-test.ts b/packages/expo-modules-autolinking/src/__tests__/concurrency-test.ts new file mode 100644 index 00000000000000..b1500000c9ed63 --- /dev/null +++ b/packages/expo-modules-autolinking/src/__tests__/concurrency-test.ts @@ -0,0 +1,71 @@ +import { createLimiter } from '../concurrency'; + +const withResolvers = () => { + let resolve: (value: T) => void; + const promise = new Promise((_resolve) => { + resolve = _resolve; + }); + return { + promise, + resolve(value: T): Promise { + resolve(value); + return promise.then(() => Promise.resolve()); + }, + }; +}; + +describe(createLimiter, () => { + it('limits concurrent executions', async () => { + const a = withResolvers(); + const b = withResolvers(); + const c = withResolvers(); + const d = withResolvers(); + + const limit = createLimiter(2); + const started: string[] = []; + const stopped: string[] = []; + + limit(async () => { + started.push('a'); + await a.promise; + stopped.push('a'); + }); + limit(async () => { + started.push('b'); + await b.promise; + stopped.push('b'); + }); + limit(async () => { + started.push('c'); + await c.promise; + stopped.push('c'); + }); + limit(async () => { + started.push('d'); + await d.promise; + stopped.push('d'); + }); + + expect(started).toEqual(['a', 'b']); + expect(stopped).toEqual([]); + + await a.resolve(); + expect(stopped).toEqual(['a']); + + await c.resolve(); + expect(started).toEqual(['a', 'b', 'c', 'd']); + expect(stopped).toEqual(['a', 'c']); + + await b.resolve(); + expect(stopped).toEqual(['a', 'c', 'b']); + + await d.resolve(); + expect(stopped).toEqual(['a', 'c', 'b', 'd']); + + await limit(async () => { + stopped.push('e'); + }); + + expect(stopped).toEqual(['a', 'c', 'b', 'd', 'e']); + }); +}); diff --git a/packages/expo-modules-autolinking/src/__tests__/memoize.test.ts b/packages/expo-modules-autolinking/src/__tests__/memoize.test.ts new file mode 100644 index 00000000000000..9c04fbc5e58caf --- /dev/null +++ b/packages/expo-modules-autolinking/src/__tests__/memoize.test.ts @@ -0,0 +1,47 @@ +import { createMemoizer, memoize, _verifyMemoizerFreed } from '../memoize'; + +it('provides cached value for memoizer', async () => { + const memoizer = createMemoizer(); + + let num = 0; + const fn = memoize(async () => ++num); + + await memoizer.withMemoizer(async () => { + expect(await fn('test')).toBe(1); + expect(await fn('test')).toBe(1); + expect(num).toBe(1); + // Busts cache + expect(await fn('test-2')).toBe(2); + expect(await fn('test-2')).toBe(2); + expect(num).toBe(2); + }); + + expect(_verifyMemoizerFreed()).toBe(true); +}); + +it('allows uncached calls', async () => { + // NOTE: This is to mute the `console.warn` log + process.env.NODE_ENV = 'not-test'; + + let num = 0; + const fn = memoize(async () => ++num); + + expect(await fn('test')).toBe(1); + expect(await fn('test')).toBe(2); + expect(num).toBe(2); + + expect(_verifyMemoizerFreed()).toBe(true); +}); + +it('allows direct calls without async context', async () => { + const memoizer = createMemoizer(); + + let num = 0; + const fn = memoize(async () => ++num); + + expect(await memoizer.call(fn, 'test')).toBe(1); + expect(await memoizer.call(fn, 'test')).toBe(1); + expect(num).toBe(1); + + expect(_verifyMemoizerFreed()).toBe(true); +}); diff --git a/packages/expo-modules-autolinking/src/autolinking/findModules.ts b/packages/expo-modules-autolinking/src/autolinking/findModules.ts index 77c2779f071844..5a71f79b4c66fd 100644 --- a/packages/expo-modules-autolinking/src/autolinking/findModules.ts +++ b/packages/expo-modules-autolinking/src/autolinking/findModules.ts @@ -7,6 +7,7 @@ import { filterMapResolutionResult, mergeResolutionResults, } from '../dependencies'; +import { createMemoizer } from '../memoize'; import { PackageRevision, SearchResults, SupportedPlatform } from '../types'; export async function resolveExpoModule( @@ -46,6 +47,7 @@ export async function findModulesAsync({ appRoot, autolinkingOptions, }: FindModulesParams): Promise { + const memoizer = createMemoizer(); const excludeNames = new Set(autolinkingOptions.exclude); // custom native modules should be resolved first so that they can override other modules @@ -53,13 +55,15 @@ export async function findModulesAsync({ ? [autolinkingOptions.nativeModulesDir, ...autolinkingOptions.searchPaths] : autolinkingOptions.searchPaths; - return filterMapResolutionResult( - mergeResolutionResults( - await Promise.all([ - ...searchPaths.map((searchPath) => scanDependenciesInSearchPath(searchPath)), - scanDependenciesRecursively(appRoot), - ]) - ), - (resolution) => resolveExpoModule(resolution, autolinkingOptions.platform, excludeNames) - ); + return memoizer.withMemoizer(async () => { + return filterMapResolutionResult( + mergeResolutionResults( + await Promise.all([ + ...searchPaths.map((searchPath) => scanDependenciesInSearchPath(searchPath)), + scanDependenciesRecursively(appRoot), + ]) + ), + (resolution) => resolveExpoModule(resolution, autolinkingOptions.platform, excludeNames) + ); + }); } diff --git a/packages/expo-modules-autolinking/src/autolinking/resolveModules.ts b/packages/expo-modules-autolinking/src/autolinking/resolveModules.ts index 5b05aafd9a43cc..88d9d090076a33 100644 --- a/packages/expo-modules-autolinking/src/autolinking/resolveModules.ts +++ b/packages/expo-modules-autolinking/src/autolinking/resolveModules.ts @@ -1,4 +1,5 @@ import { AutolinkingOptions } from '../commands/autolinkingOptions'; +import { taskAll } from '../concurrency'; import { getLinkingImplementationForPlatform } from '../platforms'; import type { ExtraDependencies, @@ -16,8 +17,9 @@ export async function resolveModulesAsync( // Additional output property for Cocoapods flags const extraOutput = { flags: autolinkingOptions.flags }; - const moduleDescriptorList = await Promise.all( - Object.entries(searchResults).map(async ([packageName, revision]) => { + const moduleDescriptorList = await taskAll( + Object.entries(searchResults), + async ([packageName, revision]) => { const resolvedModule = await platformLinking.resolveModuleAsync( packageName, revision, @@ -30,7 +32,7 @@ export async function resolveModulesAsync( packageName: resolvedModule.packageName ?? packageName, } : null; - }) + } ); return moduleDescriptorList diff --git a/packages/expo-modules-autolinking/src/concurrency.ts b/packages/expo-modules-autolinking/src/concurrency.ts new file mode 100644 index 00000000000000..1f9014f873e67d --- /dev/null +++ b/packages/expo-modules-autolinking/src/concurrency.ts @@ -0,0 +1,67 @@ +export interface Limiter { + ( + fn: (...args: Arguments) => PromiseLike | ReturnType, + ...args: Arguments + ): Promise; +} + +interface QueueItem { + resolve(): void; + next: QueueItem | null; +} + +export const createLimiter = (limit: number): Limiter => { + let running = 0; + let head: QueueItem | null = null; + let tail: QueueItem | null = null; + + const enqueue = () => + new Promise((resolve) => { + const item: QueueItem = { resolve, next: null }; + if (tail) { + tail.next = item; + tail = item; + } else { + head = item; + tail = item; + } + }); + + const dequeue = () => { + if (running < limit && head !== null) { + const { resolve, next } = head; + head.next = null; + head = next; + if (head === null) { + tail = null; + } + running++; + resolve(); + } + }; + + return async (fn, ...args) => { + if (running < limit) { + running++; + } else { + await enqueue(); + } + try { + return await fn(...args); + } finally { + running--; + dequeue(); + } + }; +}; + +export const taskAll = (inputs: T[], map: (input: T) => Promise): Promise => { + // NOTE: This doesn't depend on CPU cores, but instead is hard-coded depending on + // number of concurrent IO-bound tasks. `taskAll` can be called concurrently, and + // we don't keep track of concurrent `taskAll` calls in expo-modules-autolinking. + // There's a fixed number of concurrent pending IO operations that Node.js handles + // nicely. It seems that expo-modules-autolinking behaves nicely when this number + // is around ~8, but this may be higher if disk + core speed is higher. + const limiter = createLimiter(8); + return Promise.all(inputs.map((input) => limiter(map, input))); +}; diff --git a/packages/expo-modules-autolinking/src/dependencies/CachedDependenciesLinker.ts b/packages/expo-modules-autolinking/src/dependencies/CachedDependenciesLinker.ts index 5ca5c7f074b731..84ef57f0fe3d96 100644 --- a/packages/expo-modules-autolinking/src/dependencies/CachedDependenciesLinker.ts +++ b/packages/expo-modules-autolinking/src/dependencies/CachedDependenciesLinker.ts @@ -8,6 +8,7 @@ import { type ResolutionResult, DependencyResolutionSource } from './types'; import { filterMapResolutionResult, mergeResolutionResults } from './utils'; import { resolveExpoModule } from '../autolinking/findModules'; import { AutolinkingOptions, createAutolinkingOptionsLoader } from '../commands/autolinkingOptions'; +import { createMemoizer, type Memoizer } from '../memoize'; import { resolveReactNativeModule, RNConfigReactNativeProjectConfig } from '../reactNativeConfig'; import { loadConfigAsync } from '../reactNativeConfig/config'; @@ -17,6 +18,7 @@ export interface CachedDependenciesSearchOptions { } export interface CachedDependenciesLinker { + memoizer: Memoizer; getOptionsForPlatform(platform: SupportedPlatform): Promise; loadReactNativeProjectConfig(): Promise; scanDependenciesFromRNProjectConfig(): Promise; @@ -27,6 +29,8 @@ export interface CachedDependenciesLinker { export function makeCachedDependenciesLinker(params: { projectRoot: string; }): CachedDependenciesLinker { + const memoizer = createMemoizer(); + const autolinkingOptionsLoader = createAutolinkingOptionsLoader({ projectRoot: params.projectRoot, }); @@ -40,40 +44,45 @@ export function makeCachedDependenciesLinker(params: { let recursiveDependencies: Promise | undefined; return { + memoizer, async getOptionsForPlatform(platform) { const options = await autolinkingOptionsLoader.getPlatformOptions(platform); return makeCachedDependenciesSearchOptions(options); }, async loadReactNativeProjectConfig() { if (reactNativeProjectConfig === undefined) { - reactNativeProjectConfig = loadConfigAsync( + reactNativeProjectConfig = memoizer.call( + loadConfigAsync, await getAppRoot() - ) as Promise; + ) as Promise; } return reactNativeProjectConfig; }, async scanDependenciesFromRNProjectConfig() { - const reactNativeProjectConfig = await this.loadReactNativeProjectConfig(); - return ( - reactNativeProjectConfigDependencies || - (reactNativeProjectConfigDependencies = scanDependenciesFromRNProjectConfig( - await getAppRoot(), - reactNativeProjectConfig - )) - ); + if (reactNativeProjectConfigDependencies === undefined) { + reactNativeProjectConfigDependencies = memoizer.withMemoizer(async () => { + return await scanDependenciesFromRNProjectConfig( + await getAppRoot(), + await this.loadReactNativeProjectConfig() + ); + }); + } + return reactNativeProjectConfigDependencies; }, async scanDependenciesRecursively() { - return ( - recursiveDependencies || - (recursiveDependencies = scanDependenciesRecursively(await getAppRoot())) - ); + if (recursiveDependencies === undefined) { + recursiveDependencies = memoizer.withMemoizer(async () => { + return scanDependenciesRecursively(await getAppRoot()); + }); + } + return recursiveDependencies; }, async scanDependenciesInSearchPath(searchPath: string) { let result = dependenciesResultBySearchPath.get(searchPath); if (!result) { dependenciesResultBySearchPath.set( searchPath, - (result = scanDependenciesInSearchPath(searchPath)) + (result = memoizer.withMemoizer(scanDependenciesInSearchPath, searchPath)) ); } return result; @@ -100,36 +109,38 @@ export async function scanDependencyResolutionsForPlatform( ]) ); - const dependencies = await filterMapResolutionResult(resolutions, async (resolution) => { - if (excludeNames.has(resolution.name)) { - return null; - } else if (includeNames.has(resolution.name)) { - return resolution; - } else if (resolution.source === DependencyResolutionSource.RN_CLI_LOCAL) { - // If the dependency was resolved frpom the React Native project config, we'll only - // attempt to resolve it as a React Native module - const reactNativeModuleDesc = await resolveReactNativeModule( - resolution, - reactNativeProjectConfig, - platform, - excludeNames - ); - if (!reactNativeModuleDesc) { - return null; - } - } else { - const [reactNativeModule, expoModule] = await Promise.all([ - resolveReactNativeModule(resolution, reactNativeProjectConfig, platform, excludeNames), - resolveExpoModule(resolution, platform, excludeNames), - ]); - if (!reactNativeModule && !expoModule) { + return await linker.memoizer.withMemoizer(async () => { + const dependencies = await filterMapResolutionResult(resolutions, async (resolution) => { + if (excludeNames.has(resolution.name)) { return null; + } else if (includeNames.has(resolution.name)) { + return resolution; + } else if (resolution.source === DependencyResolutionSource.RN_CLI_LOCAL) { + // If the dependency was resolved frpom the React Native project config, we'll only + // attempt to resolve it as a React Native module + const reactNativeModuleDesc = await resolveReactNativeModule( + resolution, + reactNativeProjectConfig, + platform, + excludeNames + ); + if (!reactNativeModuleDesc) { + return null; + } + } else { + const [reactNativeModule, expoModule] = await Promise.all([ + resolveReactNativeModule(resolution, reactNativeProjectConfig, platform, excludeNames), + resolveExpoModule(resolution, platform, excludeNames), + ]); + if (!reactNativeModule && !expoModule) { + return null; + } } - } - return resolution; - }); + return resolution; + }); - return dependencies; + return dependencies; + }); } export async function scanExpoModuleResolutionsForPlatform( @@ -147,10 +158,12 @@ export async function scanExpoModuleResolutionsForPlatform( ].filter((x) => x != null) ) ); - return await filterMapResolutionResult(resolutions, async (resolution) => { - return !excludeNames.has(resolution.name) - ? await resolveExpoModule(resolution, platform, excludeNames) - : null; + return await linker.memoizer.withMemoizer(async () => { + return await filterMapResolutionResult(resolutions, async (resolution) => { + return !excludeNames.has(resolution.name) + ? await resolveExpoModule(resolution, platform, excludeNames) + : null; + }); }); } diff --git a/packages/expo-modules-autolinking/src/dependencies/__tests__/resolution-test.ts b/packages/expo-modules-autolinking/src/dependencies/__tests__/resolution-test.ts index 9e5381112d117c..f4397e34d9acd0 100644 --- a/packages/expo-modules-autolinking/src/dependencies/__tests__/resolution-test.ts +++ b/packages/expo-modules-autolinking/src/dependencies/__tests__/resolution-test.ts @@ -2,6 +2,7 @@ import { vol } from 'memfs'; import type { NestedDirectoryJSON } from 'memfs/lib/volume'; import path from 'path'; +import { createMemoizer, _verifyMemoizerFreed } from '../../memoize'; import { scanDependenciesRecursively } from '../resolution'; function mockedNodeModule( @@ -33,12 +34,19 @@ const symlinkMany = (symlinks: Record) => { const projectRoot = '/fake/project'; +const itWithMemoize = (name: string, fn: () => Promise) => { + return it(name, async () => { + await createMemoizer().withMemoizer(fn); + expect(_verifyMemoizerFreed()).toBe(true); + }); +}; + describe(scanDependenciesRecursively, () => { afterEach(() => { vol.reset(); }); - it('discovers flat dependencies', async () => { + itWithMemoize('discovers flat dependencies', async () => { vol.fromNestedJSON( { ...mockedNodeModule('root', { @@ -68,7 +76,7 @@ describe(scanDependenciesRecursively, () => { `); }); - it('discovers transitive dependencies', async () => { + itWithMemoize('discovers transitive dependencies', async () => { vol.fromNestedJSON( { ...mockedNodeModule('root', { @@ -116,7 +124,7 @@ describe(scanDependenciesRecursively, () => { `); }); - it('discovers transitive, hoisted dependencies', async () => { + itWithMemoize('discovers transitive, hoisted dependencies', async () => { vol.fromNestedJSON( { ...mockedNodeModule('root', { @@ -158,7 +166,7 @@ describe(scanDependenciesRecursively, () => { `); }); - it('discovers transitive, isolated dependencies', async () => { + itWithMemoize('discovers transitive, isolated dependencies', async () => { vol.fromNestedJSON( { ...mockedNodeModule('root', { @@ -213,7 +221,7 @@ describe(scanDependenciesRecursively, () => { `); }); - it('discovers dependencies on nameless package.json', async () => { + itWithMemoize('discovers dependencies on nameless package.json', async () => { vol.fromNestedJSON( { 'package.json': JSON.stringify({ @@ -246,7 +254,7 @@ describe(scanDependenciesRecursively, () => { `); }); - it('ignores transitive, hoisted dependencies without dependents', async () => { + itWithMemoize('ignores transitive, hoisted dependencies without dependents', async () => { vol.fromNestedJSON( { ...mockedNodeModule('root', { @@ -277,7 +285,7 @@ describe(scanDependenciesRecursively, () => { `); }); - it('ignores dependency names from filter', async () => { + itWithMemoize('ignores dependency names from filter', async () => { vol.fromNestedJSON( { ...mockedNodeModule('root', { @@ -310,7 +318,7 @@ describe(scanDependenciesRecursively, () => { `); }); - it('discovers transitive, duplicate dependencies', async () => { + itWithMemoize('discovers transitive, duplicate dependencies', async () => { vol.fromNestedJSON( { ...mockedNodeModule('root', { @@ -380,7 +388,7 @@ describe(scanDependenciesRecursively, () => { `); }); - it('allows depth to be limited', async () => { + itWithMemoize('allows depth to be limited', async () => { vol.fromNestedJSON( { ...mockedNodeModule('root', { @@ -419,7 +427,7 @@ describe(scanDependenciesRecursively, () => { `); }); - it('discovers transitive peer dependencies', async () => { + itWithMemoize('discovers transitive peer dependencies', async () => { vol.fromNestedJSON( { ...mockedNodeModule('root', { @@ -467,7 +475,7 @@ describe(scanDependenciesRecursively, () => { `); }); - it('ignores transitive optional peer dependencies', async () => { + itWithMemoize('ignores transitive optional peer dependencies', async () => { vol.fromNestedJSON( { ...mockedNodeModule('root', { diff --git a/packages/expo-modules-autolinking/src/dependencies/__tests__/scanning-test.ts b/packages/expo-modules-autolinking/src/dependencies/__tests__/scanning-test.ts index 5963a45f177993..e65ec23017a4aa 100644 --- a/packages/expo-modules-autolinking/src/dependencies/__tests__/scanning-test.ts +++ b/packages/expo-modules-autolinking/src/dependencies/__tests__/scanning-test.ts @@ -2,6 +2,7 @@ import { vol } from 'memfs'; import type { NestedDirectoryJSON } from 'memfs/lib/volume'; import path from 'path'; +import { createMemoizer, _verifyMemoizerFreed } from '../../memoize'; import { scanDependenciesInSearchPath } from '../scanning'; function mockedNodeModule( @@ -30,12 +31,19 @@ const symlinkMany = (symlinks: Record) => { const projectRoot = '/fake/project'; const projectRootNodeModules = '/fake/project/node_modules'; +const itWithMemoize = (name: string, fn: () => Promise) => { + return it(name, async () => { + await createMemoizer().withMemoizer(fn); + expect(_verifyMemoizerFreed()).toBe(true); + }); +}; + describe(scanDependenciesInSearchPath, () => { afterEach(() => { vol.reset(); }); - it('discovers unscoped and scoped dependencies', async () => { + itWithMemoize('discovers unscoped and scoped dependencies', async () => { vol.fromNestedJSON( { node_modules: { @@ -72,7 +80,7 @@ describe(scanDependenciesInSearchPath, () => { `); }); - it('discovers symlinked dependencies', async () => { + itWithMemoize('discovers symlinked dependencies', async () => { vol.fromNestedJSON( { 'react-native-third-party': mockedNodeModule('react-native-third-party'), @@ -104,7 +112,7 @@ describe(scanDependenciesInSearchPath, () => { `); }); - it('discovers transitive, isolated dependencies', async () => { + itWithMemoize('discovers transitive, isolated dependencies', async () => { vol.fromNestedJSON( { ...mockedNodeModule('root', { @@ -143,7 +151,7 @@ describe(scanDependenciesInSearchPath, () => { `); }); - it('resolves conflicts as duplicates', async () => { + itWithMemoize('resolves conflicts as duplicates', async () => { vol.fromNestedJSON( { node_modules: { @@ -178,7 +186,7 @@ describe(scanDependenciesInSearchPath, () => { `); }); - it('ignores missing package.json files on dependencies', async () => { + itWithMemoize('ignores missing package.json files on dependencies', async () => { vol.fromNestedJSON( { node_modules: { @@ -215,7 +223,7 @@ describe(scanDependenciesInSearchPath, () => { `); }); - it('ignores files', async () => { + itWithMemoize('ignores files', async () => { vol.fromNestedJSON( { node_modules: { @@ -230,7 +238,7 @@ describe(scanDependenciesInSearchPath, () => { expect(result).toEqual({}); }); - it('ignores dependency names from filter', async () => { + itWithMemoize('ignores dependency names from filter', async () => { vol.fromNestedJSON( { node_modules: { @@ -260,7 +268,7 @@ describe(scanDependenciesInSearchPath, () => { `); }); - it('supports direct path to node module', async () => { + itWithMemoize('supports direct path to node module', async () => { vol.fromNestedJSON( { node_modules: { diff --git a/packages/expo-modules-autolinking/src/dependencies/resolution.ts b/packages/expo-modules-autolinking/src/dependencies/resolution.ts index 323b4193ec0992..451e92408498f7 100644 --- a/packages/expo-modules-autolinking/src/dependencies/resolution.ts +++ b/packages/expo-modules-autolinking/src/dependencies/resolution.ts @@ -5,14 +5,9 @@ import { type DependencyResolution, DependencyResolutionSource, } from './types'; -import { - type PackageJson, - defaultShouldIncludeDependency, - mergeResolutionResults, - loadPackageJson, - maybeRealpath, - fastJoin, -} from './utils'; +import { defaultShouldIncludeDependency, mergeResolutionResults } from './utils'; +import { taskAll } from '../concurrency'; +import { type PackageJson, loadPackageJson, maybeRealpath, fastJoin } from '../utils'; declare module 'node:module' { export function _nodeModulePaths(base: string): readonly string[]; @@ -99,10 +94,9 @@ async function resolveDependencies( return null; }; - const modules = await Promise.all( - Object.keys(dependencies) - .filter((dependencyName) => shouldIncludeDependency(dependencyName)) - .map((dependencyName) => resolveDependency(dependencyName)) + const modules = await taskAll( + Object.keys(dependencies).filter((dependencyName) => shouldIncludeDependency(dependencyName)), + (dependencyName) => resolveDependency(dependencyName) ); return modules.filter((resolution) => resolution != null); @@ -157,9 +151,7 @@ export async function scanDependenciesRecursively( } if (depth + 1 < maxDepth) { - const childResults = await Promise.all( - modules.map((resolution) => recurse(resolution, depth + 1)) - ); + const childResults = await taskAll(modules, (resolution) => recurse(resolution, depth + 1)); return mergeResolutionResults(childResults, searchResults); } else { return searchResults; diff --git a/packages/expo-modules-autolinking/src/dependencies/rncliLocal.ts b/packages/expo-modules-autolinking/src/dependencies/rncliLocal.ts index 49c4297ee8f5ec..fbd9345d5aa562 100644 --- a/packages/expo-modules-autolinking/src/dependencies/rncliLocal.ts +++ b/packages/expo-modules-autolinking/src/dependencies/rncliLocal.ts @@ -1,8 +1,10 @@ import path from 'path'; import { DependencyResolutionSource, type ResolutionResult } from './types'; -import { defaultShouldIncludeDependency, maybeRealpath } from './utils'; +import { defaultShouldIncludeDependency } from './utils'; +import { taskAll } from '../concurrency'; import { RNConfigReactNativeProjectConfig } from '../reactNativeConfig'; +import { maybeRealpath } from '../utils'; interface ResolutionOptions { shouldIncludeDependency?(name: string): boolean; @@ -19,27 +21,29 @@ export async function scanDependenciesFromRNProjectConfig( return searchResults; } - for (const dependencyName in projectConfig.dependencies) { - if (!shouldIncludeDependency(dependencyName)) { - continue; - } - const dependencyConfig = projectConfig.dependencies[dependencyName]; - if (dependencyConfig && dependencyConfig.root && typeof dependencyConfig.root === 'string') { - const originPath = path.resolve(rootPath, dependencyConfig.root); - const realPath = await maybeRealpath(originPath); - if (realPath) { - searchResults[dependencyName] = { - source: DependencyResolutionSource.RN_CLI_LOCAL, - name: dependencyName, - version: '', - path: realPath, - originPath, - duplicates: null, - depth: 0, - }; + await taskAll( + Object.keys(projectConfig.dependencies).filter((dependencyName) => + shouldIncludeDependency(dependencyName) + ), + async (dependencyName) => { + const dependencyConfig = projectConfig.dependencies![dependencyName]; + if (dependencyConfig && dependencyConfig.root && typeof dependencyConfig.root === 'string') { + const originPath = path.resolve(rootPath, dependencyConfig.root); + const realPath = await maybeRealpath(originPath); + if (realPath) { + searchResults[dependencyName] = { + source: DependencyResolutionSource.RN_CLI_LOCAL, + name: dependencyName, + version: '', + path: realPath, + originPath, + duplicates: null, + depth: 0, + }; + } } } - } + ); return searchResults; } diff --git a/packages/expo-modules-autolinking/src/dependencies/scanning.ts b/packages/expo-modules-autolinking/src/dependencies/scanning.ts index 264e3ca81c7b1e..41cf8c279b8b8e 100644 --- a/packages/expo-modules-autolinking/src/dependencies/scanning.ts +++ b/packages/expo-modules-autolinking/src/dependencies/scanning.ts @@ -5,7 +5,9 @@ import { type DependencyResolution, DependencyResolutionSource, } from './types'; -import { defaultShouldIncludeDependency, loadPackageJson, maybeRealpath, fastJoin } from './utils'; +import { taskAll } from '../concurrency'; +import { defaultShouldIncludeDependency } from './utils'; +import { loadPackageJson, maybeRealpath, fastJoin } from '../utils'; async function resolveDependency( basePath: string, @@ -21,7 +23,7 @@ async function resolveDependency( if (packageJson) { return { source: DependencyResolutionSource.SEARCH_PATH, - name: packageJson.name, + name: packageJson.name || '', version: packageJson.version || '', path: realPath || originPath, originPath, @@ -67,45 +69,39 @@ export async function scanDependenciesInSearchPath( if (resolution) resolvedDependencies.push(resolution); } else { const dirents = await fs.promises.readdir(rootPath!, { withFileTypes: true }); - await Promise.all( - dirents.map(async (entry) => { - if (entry.isSymbolicLink()) { + await taskAll(dirents, async (entry) => { + if (entry.isSymbolicLink()) { + const resolution = await resolveDependency(rootPath, entry.name, shouldIncludeDependency); + if (resolution) resolvedDependencies.push(resolution); + } else if (entry.isDirectory()) { + if (entry.name === 'node_modules') { + // Ignore nested node_modules folder + } + if (entry.name[0] === '.') { + // Ignore hidden folders + } else if (entry.name[0] === '@') { + // NOTE: We don't expect @-scope folders to be symlinks + const entryPath = fastJoin(rootPath, entry.name); + const childEntries = await fs.promises.readdir(entryPath, { withFileTypes: true }); + await Promise.all( + childEntries.map(async (child) => { + const dependencyName = `${entry.name}/${child.name}`; + if (child.isDirectory() || child.isSymbolicLink()) { + const resolution = await resolveDependency( + rootPath, + dependencyName, + shouldIncludeDependency + ); + if (resolution) resolvedDependencies.push(resolution); + } + }) + ); + } else { const resolution = await resolveDependency(rootPath, entry.name, shouldIncludeDependency); if (resolution) resolvedDependencies.push(resolution); - } else if (entry.isDirectory()) { - if (entry.name === 'node_modules') { - // Ignore nested node_modules folder - } - if (entry.name[0] === '.') { - // Ignore hidden folders - } else if (entry.name[0] === '@') { - // NOTE: We don't expect @-scope folders to be symlinks - const entryPath = fastJoin(rootPath, entry.name); - const childEntries = await fs.promises.readdir(entryPath, { withFileTypes: true }); - await Promise.all( - childEntries.map(async (child) => { - const dependencyName = `${entry.name}/${child.name}`; - if (child.isDirectory() || child.isSymbolicLink()) { - const resolution = await resolveDependency( - rootPath, - dependencyName, - shouldIncludeDependency - ); - if (resolution) resolvedDependencies.push(resolution); - } - }) - ); - } else { - const resolution = await resolveDependency( - rootPath, - entry.name, - shouldIncludeDependency - ); - if (resolution) resolvedDependencies.push(resolution); - } } - }) - ); + } + }); } for (let idx = 0; idx < resolvedDependencies.length; idx++) { diff --git a/packages/expo-modules-autolinking/src/dependencies/utils.ts b/packages/expo-modules-autolinking/src/dependencies/utils.ts index a173d24d40f289..0f42f989dac742 100644 --- a/packages/expo-modules-autolinking/src/dependencies/utils.ts +++ b/packages/expo-modules-autolinking/src/dependencies/utils.ts @@ -1,7 +1,6 @@ -import fs from 'fs'; import path from 'path'; -import { memoize } from '../utils'; +import { taskAll } from '../concurrency'; import { DependencyResolutionSource, type DependencyResolution, @@ -51,37 +50,6 @@ export function defaultShouldIncludeDependency(dependencyName: string): boolean } } -export const fastJoin: (from: string, append: string) => string = - path.sep === '/' - ? (from, append) => `${from}${path.sep}${append}` - : (from, append) => - `${from}${path.sep}${append[0] === '@' ? append.replace('/', path.sep) : append}`; - -export const maybeRealpath = async (target: string): Promise => { - try { - return await fs.promises.realpath(target); - } catch { - return null; - } -}; - -export type PackageJson = Record & { version?: string }; - -export const loadPackageJson = memoize(async function loadPackageJson( - jsonPath: string -): Promise { - try { - const packageJsonText = await fs.promises.readFile(jsonPath, 'utf8'); - const json = JSON.parse(packageJsonText); - if (typeof json !== 'object' || json == null) { - return null; - } - return json; - } catch { - return null; - } -}); - export function mergeWithDuplicate( a: DependencyResolution, b: DependencyResolution @@ -136,24 +104,22 @@ export async function filterMapResolutionResult( results: ResolutionResult, filterMap: (resolution: DependencyResolution) => Promise | T | null ): Promise> { - const resolutions = await Promise.all( - Object.keys(results).map(async (key) => { - const resolution = results[key]; - const result = resolution ? await filterMap(resolution) : null; - // If we failed to find a matching resolution from `searchPaths`, also try the other duplicates - // to see if the `searchPaths` result is not a module but another is - if (resolution?.source === DependencyResolutionSource.SEARCH_PATH && !result) { - for (let idx = 0; resolution.duplicates && idx < resolution.duplicates.length; idx++) { - const duplicate = resolution.duplicates[idx]; - const duplicateResult = await filterMap({ ...resolution, ...duplicate }); - if (duplicateResult != null) { - return duplicateResult; - } + const resolutions = await taskAll(Object.keys(results), async (key) => { + const resolution = results[key]; + const result = resolution ? await filterMap(resolution) : null; + // If we failed to find a matching resolution from `searchPaths`, also try the other duplicates + // to see if the `searchPaths` result is not a module but another is + if (resolution?.source === DependencyResolutionSource.SEARCH_PATH && !result) { + for (let idx = 0; resolution.duplicates && idx < resolution.duplicates.length; idx++) { + const duplicate = resolution.duplicates[idx]; + const duplicateResult = await filterMap({ ...resolution, ...duplicate }); + if (duplicateResult != null) { + return duplicateResult; } } - return result; - }) - ); + } + return result; + }); const output: Record = Object.create(null); for (let idx = 0; idx < resolutions.length; idx++) { const resolution = resolutions[idx]; diff --git a/packages/expo-modules-autolinking/src/index.ts b/packages/expo-modules-autolinking/src/index.ts index c6790b8b658b1c..3359f3b5bc7aac 100644 --- a/packages/expo-modules-autolinking/src/index.ts +++ b/packages/expo-modules-autolinking/src/index.ts @@ -5,6 +5,7 @@ import { reactNativeConfigCommand } from './commands/reactNativeConfigCommand'; import { resolveCommand } from './commands/resolveCommand'; import { searchCommand } from './commands/searchCommand'; import { verifyCommand } from './commands/verifyCommand'; +import { createMemoizer } from './memoize'; async function main(args: string[]) { const cli = commander @@ -17,7 +18,9 @@ async function main(args: string[]) { generateModulesProviderCommand(cli); reactNativeConfigCommand(cli); - await cli.parseAsync(args, { from: 'user' }); + await createMemoizer().withMemoizer(async () => { + await cli.parseAsync(args, { from: 'user' }); + }); } module.exports = main; diff --git a/packages/expo-modules-autolinking/src/memoize.ts b/packages/expo-modules-autolinking/src/memoize.ts new file mode 100644 index 00000000000000..0f4767a9808be8 --- /dev/null +++ b/packages/expo-modules-autolinking/src/memoize.ts @@ -0,0 +1,104 @@ +// expo-modules-autolinking has a few memoizable operations that we don't want to repeat. +// However, memoizing them naively means that we may hold on to the cached values for too long. +// Instead, we wrap all calls with a `Memoizer`. +// +// This could use AsyncLocalStorage, but those are expensive. Instead, we only share one +// cache for all calls, and assume that all memoizable return values may be memoized and +// shared globally. +// +// Memoizers are created once per run, and then shared between all subsequent calls. They +// are freed when their usage count to zero, after one tick. +// +// NOTE: If you need to debug whether the memoizer is properly used, change when the +// `console.warn` appears to see if you have any uncached calls. We allow uncached calls +// for backwards-compatibility, since, at worst, we have an uncached call, if the +// Memoizer is missing. + +const MAX_SIZE = 5_000; + +export interface Memoizer { + /** Calls a function with a memoizer cache, caching its return value */ + call>( + fn: Fn, + input: string, + ...args: Args + ): Promise; + + /** Invokes an async context with a memoizer cache */ + withMemoizer(callback: () => R): R; + withMemoizer(callback: (...args: TArgs) => R, ...args: TArgs): R; +} + +export interface MemoizableAsyncFn { + (input: string, ...args: Args): Promise; +} + +let currentMemoizer: Memoizer | undefined; +let currentContexts = 0; + +/** Wraps a function in a memoizer, using the memoizer async local storage */ +export function memoize>( + fn: Fn +): MemoizableAsyncFn { + return (input: string, ...args: Args) => { + // We either use the current memoizer (sync) or the memoize context (async) + if (!currentMemoizer) { + if (process.env.NODE_ENV === 'test') { + console.warn( + `expo-modules-autolinking: Memoized function called without memoize context (${fn.name})\n` + + new Error().stack + ); + } + return fn(input, ...args); + } + return currentMemoizer.call(fn, input, ...args); + }; +} + +/** Creates a memoizer that can provide a cache to memoized functions */ +export function createMemoizer(): Memoizer { + // If we already have a memoizer, reuse it, since we can share them globally + if (currentMemoizer) { + return currentMemoizer; + } + + const cacheByFn = new Map>(); + const memoizer: Memoizer = { + async call(fn, input, ...args) { + let cache = cacheByFn.get(fn); + if (!cache) { + cache = new Map(); + cacheByFn.set(fn, cache); + } + if (!cache.has(input)) { + const value = await memoizer.withMemoizer(fn, input, ...args); + if (cache.size > MAX_SIZE) { + cache.clear(); + } + cache.set(input, value); + return value; + } + return cache.get(input); + }, + async withMemoizer(fn: (...args: TArgs) => R, ...args: TArgs) { + currentMemoizer = memoizer; + currentContexts++; + try { + return await fn(...args); + } finally { + if (currentContexts > 0) { + currentContexts--; + } + if (currentContexts === 0) { + currentMemoizer = undefined; + } + } + }, + }; + return memoizer; +} + +/** @internal Used in tests to verify the memoizer was freed */ +export function _verifyMemoizerFreed() { + return currentMemoizer === undefined && currentContexts === 0; +} diff --git a/packages/expo-modules-autolinking/src/platforms/android/android.ts b/packages/expo-modules-autolinking/src/platforms/android/android.ts index bc7caf2eb4a887..389d9fb89f9cef 100644 --- a/packages/expo-modules-autolinking/src/platforms/android/android.ts +++ b/packages/expo-modules-autolinking/src/platforms/android/android.ts @@ -2,6 +2,7 @@ import fs from 'fs'; import path from 'path'; import { AutolinkingOptions } from '../../commands/autolinkingOptions'; +import { taskAll } from '../../concurrency'; import type { ExtraDependencies, ModuleDescriptorAndroid, PackageRevision } from '../../types'; import { scanFilesRecursively } from '../../utils'; @@ -65,59 +66,57 @@ export async function resolveModuleAsync( }; } - const projects = await Promise.all( - androidProjects.map(async (project) => { - const projectPath = path.join(revision.path, project.path); - - const aarProjects = (project.gradleAarProjects ?? [])?.map((aarProject) => { - const projectName = `${defaultProjectName}$${aarProject.name}`; - const projectDir = path.join(projectPath, 'build', projectName); - return { - name: projectName, - aarFilePath: path.join(revision.path, aarProject.aarFilePath), - projectDir, - }; - }); - - const { publication } = project; - const shouldUsePublicationScriptPath = project.shouldUsePublicationScriptPath - ? path.join(revision.path, project.shouldUsePublicationScriptPath) - : undefined; - - const packages = new Set(); - for await (const file of scanFilesRecursively(projectPath)) { - if (!file.name.endsWith('Package.java') && !file.name.endsWith('Package.kt')) { - continue; - } - const fileContent = await fs.promises.readFile(file.path, 'utf8'); - - // Very naive check to skip non-expo packages - if ( - !/\bimport\s+expo\.modules\.core\.(interfaces\.Package|BasePackage)\b/.test(fileContent) - ) { - continue; - } - - const classPathMatches = fileContent.match(/^package ([\w.]+)\b/m); - - if (classPathMatches) { - const basename = path.basename(file.name, path.extname(file.name)); - packages.add(`${classPathMatches[1]}.${basename}`); - } - } + const projects = await taskAll(androidProjects, async (project) => { + const projectPath = path.join(revision.path, project.path); + const aarProjects = (project.gradleAarProjects ?? [])?.map((aarProject) => { + const projectName = `${defaultProjectName}$${aarProject.name}`; + const projectDir = path.join(projectPath, 'build', projectName); return { - name: project.name, - sourceDir: projectPath, - modules: project.modules ?? [], - services: project.services ?? [], - packages: [...packages].sort((a, b) => a.localeCompare(b)), - ...(shouldUsePublicationScriptPath ? { shouldUsePublicationScriptPath } : {}), - ...(publication ? { publication } : {}), - ...(aarProjects?.length > 0 ? { aarProjects } : {}), + name: projectName, + aarFilePath: path.join(revision.path, aarProject.aarFilePath), + projectDir, }; - }) - ); + }); + + const { publication } = project; + const shouldUsePublicationScriptPath = project.shouldUsePublicationScriptPath + ? path.join(revision.path, project.shouldUsePublicationScriptPath) + : undefined; + + const packages = new Set(); + for await (const file of scanFilesRecursively(projectPath)) { + if (!file.name.endsWith('Package.java') && !file.name.endsWith('Package.kt')) { + continue; + } + const fileContent = await fs.promises.readFile(file.path, 'utf8'); + + // Very naive check to skip non-expo packages + if ( + !/\bimport\s+expo\.modules\.core\.(interfaces\.Package|BasePackage)\b/.test(fileContent) + ) { + continue; + } + + const classPathMatches = fileContent.match(/^package ([\w.]+)\b/m); + + if (classPathMatches) { + const basename = path.basename(file.name, path.extname(file.name)); + packages.add(`${classPathMatches[1]}.${basename}`); + } + } + + return { + name: project.name, + sourceDir: projectPath, + modules: project.modules ?? [], + services: project.services ?? [], + packages: [...packages].sort((a, b) => a.localeCompare(b)), + ...(shouldUsePublicationScriptPath ? { shouldUsePublicationScriptPath } : {}), + ...(publication ? { publication } : {}), + ...(aarProjects?.length > 0 ? { aarProjects } : {}), + }; + }); const coreFeatures = revision.config?.coreFeatures() ?? []; diff --git a/packages/expo-modules-autolinking/src/reactNativeConfig/__tests__/androidResolver-test.ts b/packages/expo-modules-autolinking/src/reactNativeConfig/__tests__/androidResolver-test.ts index 378d15d7b0cca8..1fdf240321c211 100644 --- a/packages/expo-modules-autolinking/src/reactNativeConfig/__tests__/androidResolver-test.ts +++ b/packages/expo-modules-autolinking/src/reactNativeConfig/__tests__/androidResolver-test.ts @@ -1,5 +1,6 @@ import { vol } from 'memfs'; +import { createMemoizer, _verifyMemoizerFreed } from '../../memoize'; import { matchNativePackageClassName, parseComponentDescriptorsAsync, @@ -11,13 +12,20 @@ import { jest.mock('fs/promises'); +const itWithMemoize = (name: string, fn: () => Promise) => { + return it(name, async () => { + await createMemoizer().withMemoizer(fn); + expect(_verifyMemoizerFreed()).toBe(true); + }); +}; + describe(resolveDependencyConfigImplAndroidAsync, () => { afterEach(() => { jest.resetAllMocks(); vol.reset(); }); - it('should return android config if all native files found', async () => { + itWithMemoize('should return android config if all native files found', async () => { vol.fromJSON({ '/app/node_modules/react-native-test/package.json': JSON.stringify({ version: '1.0.0' }), '/app/node_modules/react-native-test/android/build.gradle': ` @@ -59,10 +67,12 @@ public class TestPackage implements ReactPackage { `); }); - it('should return android config if gradle found but not AndroidManifest.xml', async () => { - vol.fromJSON({ - '/app/node_modules/react-native-test/package.json': JSON.stringify({ version: '1.0.0' }), - '/app/node_modules/react-native-test/android/build.gradle': ` + itWithMemoize( + 'should return android config if gradle found but not AndroidManifest.xml', + async () => { + vol.fromJSON({ + '/app/node_modules/react-native-test/package.json': JSON.stringify({ version: '1.0.0' }), + '/app/node_modules/react-native-test/android/build.gradle': ` android { namespace "com.test" defaultConfig { @@ -70,7 +80,7 @@ android { } } `, - '/app/node_modules/react-native-test/android/src/main/com/test/TestPackage.java': `\ + '/app/node_modules/react-native-test/android/src/main/com/test/TestPackage.java': `\ package com.test; import com.facebook.react.ReactPackage; @@ -78,30 +88,33 @@ import com.facebook.react.ReactPackage; public class TestPackage implements ReactPackage { } `, - }); - const result = await resolveDependencyConfigImplAndroidAsync( - '/app/node_modules/react-native-test', - undefined - ); - expect(result).not.toBeNull(); - }); - - it('should return C++-only config without AndroidManifest.xml and gradle file', async () => { - vol.fromJSON({ - '/app/node_modules/react-native-test/package.json': JSON.stringify({ version: '1.0.0' }), - '/app/node_modules/react-native-test/android/build.gradle': '', - '/app/node_modules/react-native-test/android/src/main/AndroidManifest.xml': '', - }); - const result = await resolveDependencyConfigImplAndroidAsync( - '/app/node_modules/react-native-test', - { - cxxModuleCMakeListsModuleName: 'TestMod', - cxxModuleCMakeListsPath: 'CMakeLists.txt', - cxxModuleHeaderName: 'TestModSpec', - sourceDir: 'cpp', - } - ); - expect(result).toMatchInlineSnapshot(` + }); + const result = await resolveDependencyConfigImplAndroidAsync( + '/app/node_modules/react-native-test', + undefined + ); + expect(result).not.toBeNull(); + } + ); + + itWithMemoize( + 'should return C++-only config without AndroidManifest.xml and gradle file', + async () => { + vol.fromJSON({ + '/app/node_modules/react-native-test/package.json': JSON.stringify({ version: '1.0.0' }), + '/app/node_modules/react-native-test/android/build.gradle': '', + '/app/node_modules/react-native-test/android/src/main/AndroidManifest.xml': '', + }); + const result = await resolveDependencyConfigImplAndroidAsync( + '/app/node_modules/react-native-test', + { + cxxModuleCMakeListsModuleName: 'TestMod', + cxxModuleCMakeListsPath: 'CMakeLists.txt', + cxxModuleHeaderName: 'TestModSpec', + sourceDir: 'cpp', + } + ); + expect(result).toMatchInlineSnapshot(` { "buildTypes": [], "cmakeListsPath": "/app/node_modules/react-native-test/cpp/build/generated/source/codegen/jni/CMakeLists.txt", @@ -115,23 +128,27 @@ public class TestPackage implements ReactPackage { "sourceDir": "/app/node_modules/react-native-test/cpp", } `); - }); - - it('should not misdetect an Expo module as a C++-only React Native module', async () => { - vol.fromJSON({ - '/app/node_modules/react-native-test/package.json': JSON.stringify({ version: '1.0.0' }), - '/app/node_modules/react-native-test/android/build.gradle': '', - '/app/node_modules/react-native-test/android/src/main/AndroidManifest.xml': '', - '/app/node_modules/react-native-test/expo-module.config.json': '{}', - }); - const result = await resolveDependencyConfigImplAndroidAsync( - '/app/node_modules/react-native-test', - undefined - ); - expect(result).toBe(null); - }); + } + ); + + itWithMemoize( + 'should not misdetect an Expo module as a C++-only React Native module', + async () => { + vol.fromJSON({ + '/app/node_modules/react-native-test/package.json': JSON.stringify({ version: '1.0.0' }), + '/app/node_modules/react-native-test/android/build.gradle': '', + '/app/node_modules/react-native-test/android/src/main/AndroidManifest.xml': '', + '/app/node_modules/react-native-test/expo-module.config.json': '{}', + }); + const result = await resolveDependencyConfigImplAndroidAsync( + '/app/node_modules/react-native-test', + undefined + ); + expect(result).toBe(null); + } + ); - it('should return android config from custom sourceDir', async () => { + itWithMemoize('should return android config from custom sourceDir', async () => { vol.fromJSON({ '/app/node_modules/react-native-test/package.json': JSON.stringify({ version: '1.0.0' }), '/app/node_modules/react-native-test/custom/android/build.gradle': ` @@ -160,7 +177,7 @@ public class TestPackage implements ReactPackage { expect(result?.sourceDir).toBe('/app/node_modules/react-native-test/custom/android'); }); - it('should return null if gradle found but without namespace', async () => { + itWithMemoize('should return null if gradle found but without namespace', async () => { vol.fromJSON({ '/app/node_modules/react-native-test/package.json': JSON.stringify({ version: '1.0.0' }), '/app/node_modules/react-native-test/android/build.gradle': ` @@ -186,7 +203,7 @@ public class TestPackage implements ReactPackage { expect(result).toBeNull(); }); - it('should return null if reactNativeConfig is null', async () => { + itWithMemoize('should return null if reactNativeConfig is null', async () => { const result = await resolveDependencyConfigImplAndroidAsync( '/app/node_modules/react-native-test', null @@ -194,7 +211,7 @@ public class TestPackage implements ReactPackage { expect(result).toBeNull(); }); - it('should return null if no gradle and AndroidManifest found', async () => { + itWithMemoize('should return null if no gradle and AndroidManifest found', async () => { const result = await resolveDependencyConfigImplAndroidAsync( '/app/node_modules/react-native-test', undefined @@ -208,7 +225,7 @@ describe(parsePackageNameAsync, () => { vol.reset(); }); - it('should parse package name from build.gradle', async () => { + itWithMemoize('should parse package name from build.gradle', async () => { vol.fromJSON({ '/app/node_modules/test/src/main/AndroidManifest.xml': '', '/app/node_modules/test/build.gradle': `\ @@ -227,7 +244,7 @@ android { expect(result).toEqual('com.test'); }); - it('should parse package name from AndroidManifest.xml', async () => { + itWithMemoize('should parse package name from AndroidManifest.xml', async () => { vol.fromJSON({ '/app/node_modules/test/src/main/AndroidManifest.xml': `\ @@ -248,7 +265,7 @@ describe(parseNativePackageClassNameAsync, () => { vol.reset(); }); - it('should parse component descriptors from java file', async () => { + itWithMemoize('should parse component descriptors from java file', async () => { vol.fromJSON({ '/app/node_modules/test/android/src/main/com/test/TestPackage.java': `\ package com.test; @@ -267,7 +284,7 @@ public class TestPackage implements ReactPackage { expect(result).toEqual('TestPackage'); }); - it('should parse component descriptors from kotlin file', async () => { + itWithMemoize('should parse component descriptors from kotlin file', async () => { vol.fromJSON({ '/app/node_modules/test/android/src/main/com/test/TestPackage.kt': `\ package com.test @@ -292,7 +309,7 @@ describe(parseLibraryNameAsync, () => { vol.reset(); }); - it('should parse library name from package.json', async () => { + itWithMemoize('should parse library name from package.json', async () => { const result = await parseLibraryNameAsync('/app/node_modules/test', { codegenConfig: { name: 'test', @@ -301,7 +318,7 @@ describe(parseLibraryNameAsync, () => { expect(result).toBe('test'); }); - it('should parse library name from build.gradle', async () => { + itWithMemoize('should parse library name from build.gradle', async () => { vol.fromJSON({ '/app/node_modules/test/build.gradle': `\ ext { @@ -313,7 +330,7 @@ ext { expect(result).toBe('test'); }); - it('should parse library name from build.gradle.kts', async () => { + itWithMemoize('should parse library name from build.gradle.kts', async () => { vol.fromJSON({ '/app/node_modules/test/build.gradle.kts': `\ ext { @@ -332,7 +349,7 @@ describe(parseComponentDescriptorsAsync, () => { vol.reset(); }); - it('should parse component descriptors', async () => { + itWithMemoize('should parse component descriptors', async () => { vol.fromJSON({ // not matched: no `codegenNativeComponent` pattern '/app/node_modules/test/Test.ts': `export default {};`, diff --git a/packages/expo-modules-autolinking/src/reactNativeConfig/__tests__/config-test.ts b/packages/expo-modules-autolinking/src/reactNativeConfig/__tests__/config-test.ts index 363f1e793ac76d..f41f8741c38700 100644 --- a/packages/expo-modules-autolinking/src/reactNativeConfig/__tests__/config-test.ts +++ b/packages/expo-modules-autolinking/src/reactNativeConfig/__tests__/config-test.ts @@ -1,18 +1,26 @@ import { vol } from 'memfs'; import path from 'path'; +import { createMemoizer, _verifyMemoizerFreed } from '../../memoize'; import { loadConfigAsync } from '../config'; jest.mock('fs/promises'); const EXPO_MONOREPO_ROOT = path.resolve(__dirname, '../../../../..'); -describe(loadConfigAsync, () => { +const itWithMemoize = (name: string, fn: () => Promise) => { + return it(name, async () => { + await createMemoizer().withMemoizer(fn); + expect(_verifyMemoizerFreed()).toBe(true); + }); +}; + +describe('loadConfigAsync', () => { afterEach(() => { vol.reset(); }); - it('should load react-native.config.js', async () => { + itWithMemoize('should load react-native.config.js', async () => { await jest.isolateModulesAsync(async () => { vol.fromJSON({ '/app/react-native.config.js': 'module.exports = { version: "1.0.0" };', @@ -22,7 +30,7 @@ describe(loadConfigAsync, () => { }); }); - it('should load react-native.config.ts', async () => { + itWithMemoize('should load react-native.config.ts', async () => { await jest.isolateModulesAsync(async () => { vol.fromJSON({ '/app/react-native.config.ts': 'export default { version: "1.0.0" };', @@ -32,7 +40,7 @@ describe(loadConfigAsync, () => { }); }); - it('should load react-native.config.ts with cjs exports', async () => { + itWithMemoize('should load react-native.config.ts with cjs exports', async () => { await jest.isolateModulesAsync(async () => { vol.fromJSON({ '/app/react-native.config.ts': 'module.exports = { version: "1.0.0" };', diff --git a/packages/expo-modules-autolinking/src/reactNativeConfig/__tests__/reactNativeConfig-test.ts b/packages/expo-modules-autolinking/src/reactNativeConfig/__tests__/reactNativeConfig-test.ts index e0f5f38fd74786..3968316a89cc52 100644 --- a/packages/expo-modules-autolinking/src/reactNativeConfig/__tests__/reactNativeConfig-test.ts +++ b/packages/expo-modules-autolinking/src/reactNativeConfig/__tests__/reactNativeConfig-test.ts @@ -1,6 +1,7 @@ import { vol } from 'memfs'; import { AutolinkingOptions } from '../../commands/autolinkingOptions'; +import { createMemoizer, _verifyMemoizerFreed } from '../../memoize'; import { findGradleAndManifestAsync, parsePackageNameAsync } from '../androidResolver'; import { loadConfigAsync } from '../config'; import { resolveDependencyConfigImplIosAsync } from '../iosResolver'; @@ -31,6 +32,13 @@ const BASE_AUTOLINKING_OPTIONS: AutolinkingOptions = { exclude: [], }; +const itWithMemoize = (name: string, fn: () => Promise) => { + return it(name, async () => { + await createMemoizer().withMemoizer(fn); + expect(_verifyMemoizerFreed()).toBe(true); + }); +}; + describe(createReactNativeConfigAsync, () => { const mockPlatformResolverIos = resolveDependencyConfigImplIosAsync as jest.MockedFunction< typeof resolveDependencyConfigImplIosAsync @@ -40,7 +48,7 @@ describe(createReactNativeConfigAsync, () => { vol.reset(); }); - it('should return config', async () => { + itWithMemoize('should return config', async () => { const packageJson = { name: 'test', version: '1.0.0', @@ -120,7 +128,7 @@ describe(createReactNativeConfigAsync, () => { `); }); - it('should return config with local dependencies', async () => { + itWithMemoize('should return config with local dependencies', async () => { const packageJson = { name: 'test', version: '1.0.0', @@ -171,7 +179,7 @@ describe(createReactNativeConfigAsync, () => { expect(result.dependencies['react-native-test'].root).toBe('/app/modules/react-native-test'); }); - it('should return config if local dependencies are not specified', async () => { + itWithMemoize('should return config if local dependencies are not specified', async () => { const packageJson = { name: 'test', version: '1.0.0', @@ -203,7 +211,7 @@ describe(createReactNativeConfigAsync, () => { }); describe(resolveAppProjectConfigAsync, () => { - it('should return app project config for android', async () => { + itWithMemoize('should return app project config for android', async () => { const androidResolver = require('../androidResolver'); const mockFindGradleAndManifestAsync = jest.spyOn( androidResolver, @@ -231,7 +239,7 @@ describe(resolveAppProjectConfigAsync, () => { `); }); - it('should return app project config for android with custom sourceDir', async () => { + itWithMemoize('should return app project config for android with custom sourceDir', async () => { vol.fromJSON({ '/brownfield/app/src/main/AndroidManifest.xml': `\ @@ -254,26 +262,29 @@ describe(resolveAppProjectConfigAsync, () => { `); }); - it('should return empty project config for android if no gradle files or manifest files', async () => { - const androidResolver = require('../androidResolver'); - const mockFindGradleAndManifestAsync = jest.spyOn( - androidResolver, - 'findGradleAndManifestAsync' - ) as jest.MockedFunction; - mockFindGradleAndManifestAsync.mockResolvedValueOnce({ - gradle: null, - manifest: null, - }); - const mockParsePackageNameAsync = jest.spyOn( - androidResolver, - 'parsePackageNameAsync' - ) as jest.MockedFunction; - mockParsePackageNameAsync.mockResolvedValueOnce('com.test'); - const config = await resolveAppProjectConfigAsync('/app', 'android'); - expect(config).toEqual({}); - }); + itWithMemoize( + 'should return empty project config for android if no gradle files or manifest files', + async () => { + const androidResolver = require('../androidResolver'); + const mockFindGradleAndManifestAsync = jest.spyOn( + androidResolver, + 'findGradleAndManifestAsync' + ) as jest.MockedFunction; + mockFindGradleAndManifestAsync.mockResolvedValueOnce({ + gradle: null, + manifest: null, + }); + const mockParsePackageNameAsync = jest.spyOn( + androidResolver, + 'parsePackageNameAsync' + ) as jest.MockedFunction; + mockParsePackageNameAsync.mockResolvedValueOnce('com.test'); + const config = await resolveAppProjectConfigAsync('/app', 'android'); + expect(config).toEqual({}); + } + ); - it('should return app project config for ios', async () => { + itWithMemoize('should return app project config for ios', async () => { const config = await resolveAppProjectConfigAsync('/app', 'ios'); expect(config).toMatchInlineSnapshot(` { @@ -284,7 +295,7 @@ describe(resolveAppProjectConfigAsync, () => { `); }); - it('should return app project config with custom sourceDir', async () => { + itWithMemoize('should return app project config with custom sourceDir', async () => { const androidResolver = require('../androidResolver'); const mockFindGradleAndManifestAsync = jest.spyOn( androidResolver, @@ -328,7 +339,7 @@ describe(resolveReactNativeModule, () => { typeof resolveDependencyConfigImplIosAsync >; - it('should return config with platform config', async () => { + itWithMemoize('should return config with platform config', async () => { mockPlatformResolverIos.mockResolvedValueOnce({ podspecPath: '/app/node_modules/react-native-test/RNTest.podspec', version: '1.0.0', @@ -365,7 +376,7 @@ describe(resolveReactNativeModule, () => { `); }); - it('should call the platform resolver', async () => { + itWithMemoize('should call the platform resolver', async () => { await resolveReactNativeModule( { name: 'react-native-test', @@ -386,7 +397,7 @@ describe(resolveReactNativeModule, () => { ); }); - it('should call platform resolver with config from library', async () => { + itWithMemoize('should call platform resolver with config from library', async () => { const libraryConfig: RNConfigReactNativeLibraryConfig = { dependency: { platforms: { @@ -422,63 +433,69 @@ describe(resolveReactNativeModule, () => { ); }); - it('should call platform resolver with merged config and project config will override library config', async () => { - const projectConfig: RNConfigReactNativeProjectConfig = { - dependencies: { - 'react-native-test': { - platforms: { - ios: null, + itWithMemoize( + 'should call platform resolver with merged config and project config will override library config', + async () => { + const projectConfig: RNConfigReactNativeProjectConfig = { + dependencies: { + 'react-native-test': { + platforms: { + ios: null, + }, }, }, - }, - }; - const libraryConfig: RNConfigReactNativeLibraryConfig = { - dependency: { - platforms: { - ios: { - configurations: ['Debug'], - scriptPhases: [{ name: 'test', path: './test.js' }], + }; + const libraryConfig: RNConfigReactNativeLibraryConfig = { + dependency: { + platforms: { + ios: { + configurations: ['Debug'], + scriptPhases: [{ name: 'test', path: './test.js' }], + }, }, }, - }, - }; - mockLoadReactNativeConfigAsync.mockResolvedValueOnce(libraryConfig); + }; + mockLoadReactNativeConfigAsync.mockResolvedValueOnce(libraryConfig); - await resolveReactNativeModule( - { - name: 'react-native-test', - version: '', - path: '/app/node_modules/react-native-test', - originPath: '/app/node_modules/react-native-test', - duplicates: null, - depth: 0, - }, - projectConfig, - 'ios', - new Set() - ); + await resolveReactNativeModule( + { + name: 'react-native-test', + version: '', + path: '/app/node_modules/react-native-test', + originPath: '/app/node_modules/react-native-test', + duplicates: null, + depth: 0, + }, + projectConfig, + 'ios', + new Set() + ); - expect(mockPlatformResolverIos).toHaveBeenCalledWith( - expect.objectContaining({ path: '/app/node_modules/react-native-test' }), - null, - undefined - ); - }); + expect(mockPlatformResolverIos).toHaveBeenCalledWith( + expect.objectContaining({ path: '/app/node_modules/react-native-test' }), + null, + undefined + ); + } + ); - it(`should return null for the react-native because it's a platform package`, async () => { - const result = await resolveReactNativeModule( - { - name: 'react-native', - version: '', - path: '/app/node_modules/react-native', - originPath: '/app/node_modules/react-native', - duplicates: null, - depth: 0, - }, - null, - 'ios', - new Set() - ); - expect(result).toBe(null); - }); + itWithMemoize( + `should return null for the react-native because it's a platform package`, + async () => { + const result = await resolveReactNativeModule( + { + name: 'react-native', + version: '', + path: '/app/node_modules/react-native', + originPath: '/app/node_modules/react-native', + duplicates: null, + depth: 0, + }, + null, + 'ios', + new Set() + ); + expect(result).toBe(null); + } + ); }); diff --git a/packages/expo-modules-autolinking/src/reactNativeConfig/androidResolver.ts b/packages/expo-modules-autolinking/src/reactNativeConfig/androidResolver.ts index c4dbdcc7d284bc..f164936cac009b 100644 --- a/packages/expo-modules-autolinking/src/reactNativeConfig/androidResolver.ts +++ b/packages/expo-modules-autolinking/src/reactNativeConfig/androidResolver.ts @@ -6,7 +6,8 @@ import type { RNConfigReactNativePlatformsConfigAndroid, } from './reactNativeConfig.types'; import type { ExpoModuleConfig } from '../ExpoModuleConfig'; -import { scanFilesRecursively, fileExistsAsync } from '../utils'; +import { taskAll } from '../concurrency'; +import { scanFilesRecursively, fileExistsAsync, fastJoin, loadPackageJson } from '../utils'; export async function resolveDependencyConfigImplAndroidAsync( packageRoot: string, @@ -61,7 +62,7 @@ export async function resolveDependencyConfigImplAndroidAsync( packageInstance = reactNativeConfig?.packageInstance || `new ${nativePackageClassName}()`; } - const packageJson = JSON.parse(await fs.readFile(path.join(packageRoot, 'package.json'), 'utf8')); + const packageJson = await loadPackageJson(fastJoin(packageRoot, 'package.json')); const buildTypes = reactNativeConfig?.buildTypes || []; const dependencyConfiguration = reactNativeConfig?.dependencyConfiguration; const libraryName = @@ -243,7 +244,7 @@ export async function parseComponentDescriptorsAsync( const results = new Set(); for await (const entry of scanFilesRecursively(jsRoot)) { if (extRe.test(entry.name)) { - const contents = await fs.readFile(entry.path); + const contents = await fs.readFile(entry.path, 'utf8'); const matched = matchComponentDescriptors(entry.path, contents); if (matched) { results.add(matched); @@ -254,14 +255,12 @@ export async function parseComponentDescriptorsAsync( } let lazyCodegenComponentRegex: RegExp | null = null; -function matchComponentDescriptors(_filePath: string, contents: Buffer): string | null { - const fileContents = contents.toString(); - +function matchComponentDescriptors(_filePath: string, contents: string): string | null { if (!lazyCodegenComponentRegex) { lazyCodegenComponentRegex = /codegenNativeComponent(<.*>)?\s*\(\s*["'`](\w+)["'`](,?[\s\S]+interfaceOnly:\s*(\w+))?/m; } - const match = fileContents.match(lazyCodegenComponentRegex); + const match = contents.match(lazyCodegenComponentRegex); if (!(match?.[4] === 'true') && match?.[2]) { return `${match[2]}ComponentDescriptor`; } @@ -298,8 +297,8 @@ const findAndroidManifestsAsync = async (targetPath: string) => { }; const getFileCandidatesAsync = async (targetPath: string, fileNames: string[]) => { - const gradlePaths = await Promise.all( - fileNames.map((fileName) => fileExistsAsync(path.join(targetPath, fileName))) + const gradlePaths = await taskAll(fileNames, (fileName) => + fileExistsAsync(path.join(targetPath, fileName)) ); return gradlePaths.filter((file) => file != null).sort((a, b) => a.localeCompare(b)); }; diff --git a/packages/expo-modules-autolinking/src/reactNativeConfig/config.ts b/packages/expo-modules-autolinking/src/reactNativeConfig/config.ts index ee50318c0bbddb..cdb221edeb93f6 100644 --- a/packages/expo-modules-autolinking/src/reactNativeConfig/config.ts +++ b/packages/expo-modules-autolinking/src/reactNativeConfig/config.ts @@ -2,15 +2,23 @@ import { evalModule } from '@expo/require-utils'; import fs from 'fs/promises'; import path from 'path'; -import { memoize, fileExistsAsync } from '../utils'; -import type { RNConfigReactNativeConfig } from './reactNativeConfig.types'; +import { memoize } from '../memoize'; +import { fileExistsAsync } from '../utils'; +import type { + RNConfigReactNativeConfig, + RNConfigReactNativeProjectConfig, +} from './reactNativeConfig.types'; const mockedNativeModules = path.join(__dirname, '..', '..', 'node_modules_mock'); +type LoadConfigAsync = ( + packageRoot: string +) => Promise; + /** * Load the `react-native.config.js` or `react-native.config.ts` from the package. */ -export const loadConfigAsync = memoize(async function loadConfigAsync< +export const loadConfigAsync: LoadConfigAsync = memoize(async function loadConfigAsync< T extends RNConfigReactNativeConfig, >(packageRoot: string): Promise { const configPath = ( diff --git a/packages/expo-modules-autolinking/src/utils.ts b/packages/expo-modules-autolinking/src/utils.ts index 8767915fb076f2..c9b63996a2f679 100644 --- a/packages/expo-modules-autolinking/src/utils.ts +++ b/packages/expo-modules-autolinking/src/utils.ts @@ -1,23 +1,7 @@ import fs from 'fs'; import path from 'path'; -const MAX_SIZE = 5_000; - -export function memoize Promise>(fn: Fn) { - const cache = new Map>(); - return async (input: string, ...args: any[]) => { - if (!cache.has(input)) { - const result = await fn(input, ...args); - if (cache.size > MAX_SIZE) { - cache.clear(); - } - cache.set(input, result); - return result; - } else { - return cache.get(input); - } - }; -} +import { memoize } from './memoize'; /** List filtered top-level files in `targetPath` (returns absolute paths) */ export async function listFilesSorted( @@ -96,3 +80,34 @@ export const fileExistsAsync = async (file: string): Promise => { const stat = await fs.promises.stat(file).catch(() => null); return stat?.isFile() ? file : null; }; + +export const fastJoin: (from: string, append: string) => string = + path.sep === '/' + ? (from, append) => `${from}${path.sep}${append}` + : (from, append) => + `${from}${path.sep}${append[0] === '@' ? append.replace('/', path.sep) : append}`; + +export const maybeRealpath = async (target: string): Promise => { + try { + return await fs.promises.realpath(target); + } catch { + return null; + } +}; + +export type PackageJson = Record & { name?: string; version?: string }; + +export const loadPackageJson = memoize(async function loadPackageJson( + jsonPath: string +): Promise { + try { + const packageJsonText = await fs.promises.readFile(jsonPath, 'utf8'); + const json = JSON.parse(packageJsonText); + if (typeof json !== 'object' || json == null) { + return null; + } + return json; + } catch { + return null; + } +});