Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions packages/dev/codemods/src/use-subpaths/src/codemod.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,93 @@ import {RangeCalendar, CalendarCell, Heading} from 'react-aria-components';
import { RangeCalendar, CalendarCell, Heading } from 'react-aria-components/RangeCalendar';
`
);

test(
'rewrites declare module for RouterConfig on @react-spectrum/s2 to Provider subpath',
`
declare module '@react-spectrum/s2' {
interface RouterConfig {
routerOptions: { x: string };
}
}
`,
`
declare module '@react-spectrum/s2/Provider' {
interface RouterConfig {
routerOptions: { x: string };
}
}
`
);

test(
'rewrites declare module for RouterConfig on @adobe/react-spectrum to Provider subpath',
`
declare module '@adobe/react-spectrum' {
interface RouterConfig {
routerOptions: { x: string };
}
}
`,
`
declare module '@adobe/react-spectrum/Provider' {
interface RouterConfig {
routerOptions: { x: string };
}
}
`
);

test(
'leaves declare module on an existing Provider subpath unchanged',
`
declare module '@react-spectrum/s2/Provider' {
interface RouterConfig {
routerOptions: { x: string };
}
}
`,
`
declare module '@react-spectrum/s2/Provider' {
interface RouterConfig {
routerOptions: { x: string };
}
}
`
);

test(
'does not rewrite react-aria-components declare module when there is no Provider subpath',
`
declare module 'react-aria-components' {
interface RouterConfig {
routerOptions: { x: string };
}
}
`,
`
declare module 'react-aria-components' {
interface RouterConfig {
routerOptions: { x: string };
}
}
`
);

test(
'does not rewrite declare module on root package when not augmenting RouterConfig',
`
declare module '@react-spectrum/s2' {
interface SomethingElse {
x: string;
}
}
`,
`
declare module '@react-spectrum/s2' {
interface SomethingElse {
x: string;
}
}
`
);
40 changes: 37 additions & 3 deletions packages/dev/codemods/src/use-subpaths/src/codemod.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable max-depth */
import {API, FileInfo} from 'jscodeshift';
import {getSpecifiersByPackage} from './specifiers';
import {getSpecifiersByPackage, MONOPACKAGE_ROOTS} from './specifiers';
import {parse} from '@babel/parser';
import {parse as recastParse} from 'recast';
import * as t from '@babel/types';
Expand Down Expand Up @@ -64,6 +64,25 @@ function resolveTargetSource(
return candidates[0];
}

function moduleAugmentsRouterConfig(body: t.TSModuleBlock): boolean {
for (let stmt of body.body) {
if (stmt.type === 'TSInterfaceDeclaration' && stmt.id.type === 'Identifier' && stmt.id.name === 'RouterConfig') {
return true;
}

if (
stmt.type === 'ExportNamedDeclaration' &&
stmt.declaration?.type === 'TSInterfaceDeclaration' &&
stmt.declaration.id.type === 'Identifier' &&
stmt.declaration.id.name === 'RouterConfig'
) {
return true;
}
}

return false;
}

export default function transformer(file: FileInfo, api: API): string {
let specifiersByPackage = getSpecifiersByPackage(file.path);
let j = api.jscodeshift.withParser({
Expand Down Expand Up @@ -102,6 +121,7 @@ export default function transformer(file: FileInfo, api: API): string {
let program = root.get().node.program as t.Program;
let uniqueSources = new Set<string>();
let existingImports = new Map<string, t.ImportDeclaration>();
let didChange = false;

for (let node of program.body) {
if (node.type === 'ImportDeclaration') {
Expand All @@ -128,9 +148,23 @@ export default function transformer(file: FileInfo, api: API): string {
}
}
}
}

let didChange = false;
if (node.type === 'TSModuleDeclaration' && node.declare && node.id.type === 'StringLiteral') {
let mod = node.id.value;
if (!MONOPACKAGE_ROOTS.includes(mod) || node.body?.type !== 'TSModuleBlock' || !moduleAugmentsRouterConfig(node.body)) {
continue;
}

let target = `${mod}/Provider`;
let candidates = specifiersByPackage[mod]?.Provider;
if (!candidates?.includes(target)) {
continue;
}

node.id = t.stringLiteral(target);
didChange = true;
}
}

program.body = program.body.flatMap(node => {
if (node.type !== 'ImportDeclaration') {
Expand Down
4 changes: 2 additions & 2 deletions packages/dev/codemods/src/use-subpaths/src/specifiers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {parse} from '@babel/parser';
import path from 'path';
import url from 'url';

const PACKAGES = [
export const MONOPACKAGE_ROOTS = [
'@adobe/react-spectrum',
'@react-spectrum/s2',
'react-aria-components',
Expand All @@ -17,7 +17,7 @@ const specifiersByPackage: Record<string, Record<string, string[]>> = {};

/** Builds a mapping of monopackage -> export -> subpaths that contain the export. */
export function getSpecifiersByPackage(from: string) {
for (let pkg of PACKAGES) {
for (let pkg of MONOPACKAGE_ROOTS) {
if (specifiersByPackage[pkg]) {
continue;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/dev/s2-docs/pages/s2/getting-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ Install React Spectrum with your preferred package manager.
import {Provider} from '@react-spectrum/s2/Provider';

// Configure the type of the `routerOptions` prop on all React Spectrum components.
declare module '@react-spectrum/s2' {
declare module '@react-spectrum/s2/Provider' {
interface RouterConfig {
routerOptions: NonNullable<Parameters<ReturnType<typeof useRouter>['push']>[1]>
}
Expand Down Expand Up @@ -402,7 +402,7 @@ Install React Spectrum with your preferred package manager.

/*- begin highlight -*/
// Configure the type of the `routerOptions` prop on all React Spectrum components.
declare module '@react-spectrum/s2' {
declare module '@react-spectrum/s2/Provider' {
interface RouterConfig {
routerOptions: NavigateOptions
}
Expand Down
8 changes: 4 additions & 4 deletions packages/dev/s2-docs/src/routers-s2.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ import {Step, Counter} from './Step';

```tsx
// src/app.tsx
import {Provider} from '@react-spectrum/s2';
import {Provider} from '@react-spectrum/s2/Provider';
import {BrowserRouter, useNavigate, useHref, type NavigateOptions} from 'react-router';

/*- begin highlight -*/
// Configure the type of the `routerOptions` prop on all React Spectrum components.
declare module '@react-spectrum/s2' {
declare module '@react-spectrum/s2/Provider' {
interface RouterConfig {
routerOptions: NavigateOptions
}
Expand All @@ -43,12 +43,12 @@ import {Step, Counter} from './Step';

```tsx
// src/routes/__root.tsx
import {Provider} from '@react-spectrum/s2';
import {Provider} from '@react-spectrum/s2/Provider';
import {useRouter, type NavigateOptions, type ToOptions} from '@tanstack/react-router';

/*- begin highlight -*/
// Configure the type of the `href` and `routerOptions` props on all React Spectrum components.
declare module '@react-spectrum/s2' {
declare module '@react-spectrum/s2/Provider' {
interface RouterConfig {
href: ToOptions,
routerOptions: Omit<NavigateOptions, keyof ToOptions>
Expand Down
Loading