diff --git a/change/@fluentui-priority-overflow-be962710-d1fe-4f92-866d-35605c166f3d.json b/change/@fluentui-priority-overflow-be962710-d1fe-4f92-866d-35605c166f3d.json new file mode 100644 index 00000000000000..0be9789d759fd0 --- /dev/null +++ b/change/@fluentui-priority-overflow-be962710-d1fe-4f92-866d-35605c166f3d.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore(priority-flow): re-generate api.md", + "packageName": "@fluentui/priority-overflow", + "email": "martinhochel@microsoft.com", + "dependentChangeType": "none" +} diff --git a/change/@fluentui-react-aria-4c83e3c1-60e7-497a-9e1d-0e1bb35664a8.json b/change/@fluentui-react-aria-4c83e3c1-60e7-497a-9e1d-0e1bb35664a8.json new file mode 100644 index 00000000000000..e6fa227b4fe5bc --- /dev/null +++ b/change/@fluentui-react-aria-4c83e3c1-60e7-497a-9e1d-0e1bb35664a8.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "docs(react-aria): re-generate api.md", + "packageName": "@fluentui/react-aria", + "email": "martinhochel@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/change/@fluentui-react-avatar-a74ed07c-650a-48fa-897f-c9b151866f7c.json b/change/@fluentui-react-avatar-a74ed07c-650a-48fa-897f-c9b151866f7c.json new file mode 100644 index 00000000000000..13f394d64b3dac --- /dev/null +++ b/change/@fluentui-react-avatar-a74ed07c-650a-48fa-897f-c9b151866f7c.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "docs: re-generate api.md files", + "packageName": "@fluentui/react-avatar", + "email": "martinhochel@microsoft.com", + "dependentChangeType": "none" +} diff --git a/change/@fluentui-react-context-selector-e362261c-c781-45d2-a4b2-1a2af9990e0e.json b/change/@fluentui-react-context-selector-e362261c-c781-45d2-a4b2-1a2af9990e0e.json new file mode 100644 index 00000000000000..c6b41b13e551df --- /dev/null +++ b/change/@fluentui-react-context-selector-e362261c-c781-45d2-a4b2-1a2af9990e0e.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "docs(react-context-selector): re-generate api.md", + "packageName": "@fluentui/react-context-selector", + "email": "martinhochel@microsoft.com", + "dependentChangeType": "none" +} diff --git a/change/@fluentui-react-overflow-ecf714e3-d218-4cc2-b03b-330efd0d6e8d.json b/change/@fluentui-react-overflow-ecf714e3-d218-4cc2-b03b-330efd0d6e8d.json new file mode 100644 index 00000000000000..b2fbcef441aa44 --- /dev/null +++ b/change/@fluentui-react-overflow-ecf714e3-d218-4cc2-b03b-330efd0d6e8d.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "docs: re-generate api.md files", + "packageName": "@fluentui/react-overflow", + "email": "martinhochel@microsoft.com", + "dependentChangeType": "none" +} diff --git a/change/@fluentui-react-positioning-8efb2e48-e33d-429a-be0e-d862aaf3e6f4.json b/change/@fluentui-react-positioning-8efb2e48-e33d-429a-be0e-d862aaf3e6f4.json new file mode 100644 index 00000000000000..3e3a3e70e60c75 --- /dev/null +++ b/change/@fluentui-react-positioning-8efb2e48-e33d-429a-be0e-d862aaf3e6f4.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "docs: re-generate api.md files", + "packageName": "@fluentui/react-positioning", + "email": "martinhochel@microsoft.com", + "dependentChangeType": "none" +} diff --git a/change/@fluentui-react-shared-contexts-e4e3f022-f79f-4ab2-95bf-a496d8d2784a.json b/change/@fluentui-react-shared-contexts-e4e3f022-f79f-4ab2-95bf-a496d8d2784a.json new file mode 100644 index 00000000000000..35d8e41d6d9231 --- /dev/null +++ b/change/@fluentui-react-shared-contexts-e4e3f022-f79f-4ab2-95bf-a496d8d2784a.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "docs(react-shared-contexts): re-generate api.md", + "packageName": "@fluentui/react-shared-contexts", + "email": "martinhochel@microsoft.com", + "dependentChangeType": "none" +} diff --git a/change/@fluentui-react-tabster-5ad9a59a-bea6-4483-9063-7c2d7dead914.json b/change/@fluentui-react-tabster-5ad9a59a-bea6-4483-9063-7c2d7dead914.json new file mode 100644 index 00000000000000..c4f00aa91e8c16 --- /dev/null +++ b/change/@fluentui-react-tabster-5ad9a59a-bea6-4483-9063-7c2d7dead914.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "docs: re-generate api.md files", + "packageName": "@fluentui/react-tabster", + "email": "martinhochel@microsoft.com", + "dependentChangeType": "none" +} diff --git a/change/@fluentui-react-utilities-a0cb439b-1243-4594-9a77-309c983360cf.json b/change/@fluentui-react-utilities-a0cb439b-1243-4594-9a77-309c983360cf.json new file mode 100644 index 00000000000000..f468fec39a1fcd --- /dev/null +++ b/change/@fluentui-react-utilities-a0cb439b-1243-4594-9a77-309c983360cf.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "docs(react-utilities): re-generate api.md", + "packageName": "@fluentui/react-utilities", + "email": "martinhochel@microsoft.com", + "dependentChangeType": "none" +} diff --git a/packages/react-components/priority-overflow/etc/priority-overflow.api.md b/packages/react-components/priority-overflow/etc/priority-overflow.api.md index c0511c2801bf22..6ecdc4d372dcb8 100644 --- a/packages/react-components/priority-overflow/etc/priority-overflow.api.md +++ b/packages/react-components/priority-overflow/etc/priority-overflow.api.md @@ -4,8 +4,6 @@ ```ts -// Warning: (ae-internal-missing-underscore) The name "createOverflowManager" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal (undocumented) export function createOverflowManager(): OverflowManager; @@ -61,8 +59,6 @@ export interface OverflowItemEntry { priority: number; } -// Warning: (ae-internal-missing-underscore) The name "OverflowManager" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal (undocumented) export interface OverflowManager { addItem: (items: OverflowItemEntry) => void; diff --git a/packages/react-components/react-aria/etc/react-aria.api.md b/packages/react-components/react-aria/etc/react-aria.api.md index cd59aadcec3e14..c9f136db5c0509 100644 --- a/packages/react-components/react-aria/etc/react-aria.api.md +++ b/packages/react-components/react-aria/etc/react-aria.api.md @@ -24,13 +24,9 @@ export type ARIAButtonSlotProps = // @public (undocumented) export type ARIAButtonType = 'button' | 'a' | 'div'; -// Warning: (ae-internal-missing-underscore) The name "useARIAButtonProps" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal export function useARIAButtonProps>(type?: Type, props?: Props): ARIAButtonResultProps; -// Warning: (ae-internal-missing-underscore) The name "useARIAButtonShorthand" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal export const useARIAButtonShorthand: ResolveShorthandFunction; diff --git a/packages/react-components/react-aria/package.json b/packages/react-components/react-aria/package.json index 3ac29cc46ffed4..4b18fb4445a02c 100644 --- a/packages/react-components/react-aria/package.json +++ b/packages/react-components/react-aria/package.json @@ -20,7 +20,7 @@ "start": "yarn storybook", "test": "jest --passWithNoTests", "docs": "api-extractor run --config=config/api-extractor.local.json --local", - "build:local": "tsc -p ./tsconfig.lib.json --module esnext --emitDeclarationOnly && node ../../../scripts/typescript/normalize-import --output ./dist/types/packages/react-components/react-aria/src && yarn docs", + "build:local": "tsc -p ./tsconfig.lib.json --module esnext --emitDeclarationOnly && node ../../../scripts/typescript/normalize-import --output ./dist/types/types/packages/react-components/react-aria/src && yarn docs", "storybook": "start-storybook", "type-check": "tsc -b tsconfig.json" }, diff --git a/packages/react-components/react-avatar/etc/react-avatar.api.md b/packages/react-components/react-avatar/etc/react-avatar.api.md index 93f7fe85e263c0..5779770c5074c2 100644 --- a/packages/react-components/react-avatar/etc/react-avatar.api.md +++ b/packages/react-components/react-avatar/etc/react-avatar.api.md @@ -143,8 +143,6 @@ export type AvatarState = ComponentState & Required>; }; -// Warning: (ae-internal-missing-underscore) The name "getInitials" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal export function getInitials(displayName: string | undefined | null, isRtl: boolean, options?: { allowPhoneInitials?: boolean; diff --git a/packages/react-components/react-context-selector/etc/react-context-selector.api.md b/packages/react-components/react-context-selector/etc/react-context-selector.api.md index e1993a52f0ac56..95349d41a1f253 100644 --- a/packages/react-components/react-context-selector/etc/react-context-selector.api.md +++ b/packages/react-components/react-context-selector/etc/react-context-selector.api.md @@ -6,21 +6,15 @@ import * as React_2 from 'react'; -// Warning: (ae-internal-missing-underscore) The name "Context" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal (undocumented) export type Context = React_2.Context & { Provider: React_2.FC>; Consumer: never; }; -// Warning: (ae-internal-missing-underscore) The name "ContextSelector" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal (undocumented) export type ContextSelector = (value: Value) => SelectedValue; -// Warning: (ae-internal-missing-underscore) The name "ContextValue" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal (undocumented) export type ContextValue = { listeners: ((payload: readonly [ContextVersion, Value]) => void)[]; @@ -28,30 +22,20 @@ export type ContextValue = { version: React_2.MutableRefObject; }; -// Warning: (ae-internal-missing-underscore) The name "ContextValues" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal (undocumented) export type ContextValues = ContextValue & { listeners: ((payload: readonly [ContextVersion, Record]) => void)[]; }; -// Warning: (ae-internal-missing-underscore) The name "ContextVersion" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal (undocumented) export type ContextVersion = number; -// Warning: (ae-internal-missing-underscore) The name "createContext" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal (undocumented) export const createContext: (defaultValue: Value) => Context; -// Warning: (ae-internal-missing-underscore) The name "useContextSelector" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal export const useContextSelector: (context: Context, selector: ContextSelector) => SelectedValue; -// Warning: (ae-internal-missing-underscore) The name "useHasParentContext" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal export function useHasParentContext(context: Context): boolean; diff --git a/packages/react-components/react-overflow/etc/react-overflow.api.md b/packages/react-components/react-overflow/etc/react-overflow.api.md index a93c73947eeee2..09fab788d7190b 100644 --- a/packages/react-components/react-overflow/etc/react-overflow.api.md +++ b/packages/react-components/react-overflow/etc/react-overflow.api.md @@ -46,13 +46,9 @@ export function useIsOverflowGroupVisible(id: string): OverflowGroupState; // @public (undocumented) export function useIsOverflowItemVisible(id: string): boolean; -// Warning: (ae-internal-missing-underscore) The name "useOverflowContainer" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal (undocumented) export const useOverflowContainer: (update: OnUpdateOverflow, options: Omit) => UseOverflowContainerReturn; -// Warning: (ae-internal-missing-underscore) The name "UseOverflowContainerReturn" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal (undocumented) export interface UseOverflowContainerReturn { containerRef: React_2.RefObject; @@ -63,8 +59,6 @@ export interface UseOverflowContainerReturn { // @public (undocumented) export const useOverflowCount: () => number; -// Warning: (ae-internal-missing-underscore) The name "useOverflowItem" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal export function useOverflowItem(id: string, priority?: number, groupId?: string): React_2.RefObject; diff --git a/packages/react-components/react-positioning/etc/react-positioning.api.md b/packages/react-components/react-positioning/etc/react-positioning.api.md index 6743c6fe31e292..792c36e9a9648f 100644 --- a/packages/react-components/react-positioning/etc/react-positioning.api.md +++ b/packages/react-components/react-positioning/etc/react-positioning.api.md @@ -16,21 +16,15 @@ export type AutoSize = 'height' | 'height-always' | 'width' | 'width-always' | ' // @public (undocumented) export type Boundary = HTMLElement | Array | 'clippingParents' | 'scrollParent' | 'window'; -// Warning: (ae-internal-missing-underscore) The name "createArrowHeightStyles" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal export function createArrowHeightStyles(arrowHeight: number): { width: string; height: string; }; -// Warning: (ae-internal-missing-underscore) The name "createArrowStyles" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal export function createArrowStyles(options: CreateArrowStylesOptions): GriffelStyle; -// Warning: (ae-internal-missing-underscore) The name "CreateArrowStylesOptions" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal export type CreateArrowStylesOptions = { arrowHeight: number | undefined; @@ -42,8 +36,6 @@ export type CreateArrowStylesOptions = { // @public export function createVirtualElementFromClick(nativeEvent: MouseEvent): PositioningVirtualElement; -// Warning: (ae-internal-missing-underscore) The name "mergeArrowOffset" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal export function mergeArrowOffset(userOffset: Offset | undefined | null, arrowHeight: number): Offset; @@ -109,8 +101,6 @@ export type PositioningVirtualElement = { // @public (undocumented) export function resolvePositioningShorthand(shorthand: PositioningShorthand | undefined | null): Readonly; -// Warning: (ae-internal-missing-underscore) The name "usePositioning" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal (undocumented) export function usePositioning(options: UsePositioningOptions): { targetRef: React_2.MutableRefObject; @@ -118,8 +108,6 @@ export function usePositioning(options: UsePositioningOptions): { arrowRef: React_2.MutableRefObject; }; -// Warning: (ae-internal-missing-underscore) The name "usePositioningMouseTarget" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal export const usePositioningMouseTarget: (initialState?: PositioningVirtualElement | (() => PositioningVirtualElement) | undefined) => readonly [PositioningVirtualElement | undefined, (event: React_2.MouseEvent | MouseEvent | undefined | null) => void]; diff --git a/packages/react-components/react-shared-contexts/etc/react-shared-contexts.api.md b/packages/react-components/react-shared-contexts/etc/react-shared-contexts.api.md index 16bcb2f1dc99b2..342a64fed5ef73 100644 --- a/packages/react-components/react-shared-contexts/etc/react-shared-contexts.api.md +++ b/packages/react-components/react-shared-contexts/etc/react-shared-contexts.api.md @@ -7,8 +7,6 @@ import * as React_2 from 'react'; import type { Theme } from '@fluentui/react-theme'; -// Warning: (ae-internal-missing-underscore) The name "Provider_unstable" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal (undocumented) export const Provider_unstable: React_2.Provider; @@ -24,23 +22,15 @@ export type ThemeClassNameContextValue_unstable = string; // @public (undocumented) export const ThemeClassNameProvider_unstable: React_2.Provider; -// Warning: (ae-internal-missing-underscore) The name "ThemeContext_unstable" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal (undocumented) export const ThemeContext_unstable: React_2.Context; -// Warning: (ae-internal-missing-underscore) The name "ThemeContextValue_unstable" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal (undocumented) export type ThemeContextValue_unstable = Theme | Partial | undefined; -// Warning: (ae-internal-missing-underscore) The name "ThemeProvider_unstable" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal (undocumented) export const ThemeProvider_unstable: React_2.Provider; -// Warning: (ae-internal-missing-underscore) The name "TooltipVisibilityContextValue_unstable" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal export type TooltipVisibilityContextValue_unstable = { visibleTooltip?: { @@ -48,21 +38,15 @@ export type TooltipVisibilityContextValue_unstable = { }; }; -// Warning: (ae-internal-missing-underscore) The name "TooltipVisibilityProvider_unstable" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal (undocumented) export const TooltipVisibilityProvider_unstable: React_2.Provider; // @public (undocumented) export function useFluent_unstable(): ProviderContextValue_unstable; -// Warning: (ae-internal-missing-underscore) The name "useThemeClassName_unstable" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal (undocumented) export function useThemeClassName_unstable(): ThemeClassNameContextValue_unstable; -// Warning: (ae-internal-missing-underscore) The name "useTooltipVisibility_unstable" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal (undocumented) export function useTooltipVisibility_unstable(): TooltipVisibilityContextValue_unstable; diff --git a/packages/react-components/react-tabster/etc/react-tabster.api.md b/packages/react-components/react-tabster/etc/react-tabster.api.md index ac4ae061269cc6..b1fba8c4bd81c1 100644 --- a/packages/react-components/react-tabster/etc/react-tabster.api.md +++ b/packages/react-components/react-tabster/etc/react-tabster.api.md @@ -89,8 +89,6 @@ export interface UseModalAttributesOptions { trapFocus?: boolean; } -// Warning: (ae-internal-missing-underscore) The name "useTabsterAttributes" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal export const useTabsterAttributes: (props: Types.TabsterAttributeProps) => Types.TabsterDOMAttribute; diff --git a/packages/react-components/react-utilities/etc/react-utilities.api.md b/packages/react-components/react-utilities/etc/react-utilities.api.md index fd373fd08d061a..a6e98969eef71e 100644 --- a/packages/react-components/react-utilities/etc/react-utilities.api.md +++ b/packages/react-components/react-utilities/etc/react-utilities.api.md @@ -7,16 +7,12 @@ import { DispatchWithoutAction } from 'react'; import * as React_2 from 'react'; -// Warning: (ae-internal-missing-underscore) The name "applyTriggerPropsToChildren" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal export const applyTriggerPropsToChildren: (children: React_2.ReactElement> | ((props: TTriggerProps) => React_2.ReactElement | null) | null | undefined, triggerProps: TTriggerProps) => React_2.ReactElement | null; // @public export function canUseDOM(): boolean; -// Warning: (ae-internal-missing-underscore) The name "clamp" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal export const clamp: (value: number, min: number, max: number) => number; @@ -35,8 +31,6 @@ export type ComponentState = { // @public export type ExtractSlotProps = Exclude; -// Warning: (ae-internal-missing-underscore) The name "FluentTriggerComponent" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal export type FluentTriggerComponent = { isFluentTriggerComponent?: boolean; @@ -61,8 +55,6 @@ export const getPartitionedNativeProps: ; }; -// Warning: (ae-internal-missing-underscore) The name "getRTLSafeKey" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal export const getRTLSafeKey: (key: string, dir: 'ltr' | 'rtl') => string; @@ -72,20 +64,14 @@ export function getSlots(state: ComponentState): { slotProps: ObjectSlotProps; }; -// Warning: (ae-internal-missing-underscore) The name "getTriggerChild" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal export const getTriggerChild:

(children: React_2.ReactNode) => React_2.ReactElement> & { ref?: React_2.Ref | undefined; }; -// Warning: (ae-internal-missing-underscore) The name "mergeCallbacks" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal export function mergeCallbacks(callback1: ((...args: Args) => void) | undefined, callback2: ((...args: Args) => void) | undefined): (...args: Args) => void; -// Warning: (ae-internal-missing-underscore) The name "RefObjectFunction" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal export type RefObjectFunction = React_2.RefObject & ((value: T) => void); @@ -107,8 +93,6 @@ export type ResolveShorthandOptions = { defaultProps?: Props; }; -// Warning: (ae-internal-missing-underscore) The name "shouldPreventDefaultOnKeyDown" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal export function shouldPreventDefaultOnKeyDown(e: KeyboardEvent | React_2.KeyboardEvent): boolean; @@ -143,13 +127,9 @@ export type SlotShorthandValue = React_2.ReactChild | React_2.ReactNodeArray | R // @public export const SSRProvider: React_2.FC; -// Warning: (ae-internal-missing-underscore) The name "useControllableState" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal export const useControllableState: (options: UseControllableStateOptions) => [State, React_2.Dispatch>]; -// Warning: (ae-internal-missing-underscore) The name "UseControllableStateOptions" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal (undocumented) export type UseControllableStateOptions = { defaultState?: State | (() => State); @@ -157,39 +137,27 @@ export type UseControllableStateOptions = { initialState: State; }; -// Warning: (ae-internal-missing-underscore) The name "useEventCallback" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal export const useEventCallback: (fn: (...args: Args) => Return) => (...args: Args) => Return; -// Warning: (ae-internal-missing-underscore) The name "useFirstMount" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal export function useFirstMount(): boolean; -// Warning: (ae-internal-missing-underscore) The name "useForceUpdate" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal export function useForceUpdate(): DispatchWithoutAction; // @public export function useId(prefix?: string, providedId?: string): string; -// Warning: (ae-internal-missing-underscore) The name "useIsomorphicLayoutEffect" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal export const useIsomorphicLayoutEffect: typeof React_2.useEffect; // @public export function useIsSSR(): boolean; -// Warning: (ae-internal-missing-underscore) The name "useMergedRefs" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal export function useMergedRefs(...refs: (React_2.Ref | undefined)[]): RefObjectFunction; -// Warning: (ae-internal-missing-underscore) The name "UseOnClickOrScrollOutsideOptions" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal (undocumented) export type UseOnClickOrScrollOutsideOptions = { element: Document | undefined; @@ -199,23 +167,15 @@ export type UseOnClickOrScrollOutsideOptions = { callback: (ev: MouseEvent | TouchEvent) => void; }; -// Warning: (ae-internal-missing-underscore) The name "useOnClickOutside" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal export const useOnClickOutside: (options: UseOnClickOrScrollOutsideOptions) => void; -// Warning: (ae-internal-missing-underscore) The name "useOnScrollOutside" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal export const useOnScrollOutside: (options: UseOnClickOrScrollOutsideOptions) => void; -// Warning: (ae-internal-missing-underscore) The name "usePrevious" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal (undocumented) export const usePrevious: (value: ValueType) => ValueType | null; -// Warning: (ae-internal-missing-underscore) The name "useTimeout" should be prefixed with an underscore because the declaration is marked as @internal -// // @internal export function useTimeout(): readonly [(fn: () => void, delay: number) => void, () => void]; diff --git a/scripts/api-extractor/api-extractor.common.v-next.json b/scripts/api-extractor/api-extractor.common.v-next.json index ddc592d64c87de..20f98320b8ef71 100644 --- a/scripts/api-extractor/api-extractor.common.v-next.json +++ b/scripts/api-extractor/api-extractor.common.v-next.json @@ -4,15 +4,31 @@ "enabled": true }, "docModel": { - "enabled": true, + "enabled": false, "apiJsonFilePath": "/dist/.api.json" }, "dtsRollup": { "enabled": true, - "untrimmedFilePath": "/dist/index.d.ts" + // TODO: replace following line with these 2 commented ones after all v9 is migrated to new build and .d.ts API stripping + "untrimmedFilePath": "/dist/index.d.ts", + // "untrimmedFilePath": "/dist/untrimmed.d.ts", + // "publicTrimmedFilePath": "/dist/index.d.ts", + "omitTrimmingComments": false + }, + "compiler": { + "skipLibCheck": false, + "tsconfigFilePath": "/tsconfig.lib.json" }, - "mainEntryPointFilePath": "/lib/index.d.ts", + "tsdocMetadata": { + "enabled": false + }, + "mainEntryPointFilePath": "/../../../dist/out-tsc/types/packages/react-components//src/index.d.ts", "messages": { + "compilerMessageReporting": { + "default": { + "logLevel": "error" + } + }, "extractorMessageReporting": { "ae-forgotten-export": { "logLevel": "none", @@ -23,6 +39,10 @@ }, "ae-unresolved-link": { "logLevel": "none" + }, + "ae-internal-missing-underscore": { + "logLevel": "none", + "addToApiReportFile": false } }, "tsdocMessageReporting": { diff --git a/scripts/beachball/tagVNext.ts b/scripts/beachball/tagVNext.ts index e7056ca0d55a87..1af493fcbed658 100644 --- a/scripts/beachball/tagVNext.ts +++ b/scripts/beachball/tagVNext.ts @@ -43,7 +43,7 @@ function getPackagesToTag() { const packageInfos: AllPackageInfo = getAllPackageInfo(); return Object.values(packageInfos) .map(packageInfo => { - if (!packageInfo.packageJson.private && isConvergedPackage(packageInfo.packageJson)) { + if (!packageInfo.packageJson.private && isConvergedPackage({ packagePathOrJson: packageInfo.packageJson })) { return { name: packageInfo.packageJson.name, version: packageInfo.packageJson.version, diff --git a/scripts/beachball/utils.ts b/scripts/beachball/utils.ts index e18b1c6b38c5ba..2e41c8eb8d7bb1 100644 --- a/scripts/beachball/utils.ts +++ b/scripts/beachball/utils.ts @@ -34,7 +34,7 @@ export function getConfig({ version }: { version: 'v8' | 'vNext' }) { function getVNextPackagePaths(allPackageInfo: AllPackageInfo) { return Object.values(allPackageInfo) .map(packageInfo => { - if (isConvergedPackage(packageInfo.packageJson)) { + if (isConvergedPackage({ packagePathOrJson: packageInfo.packageJson })) { return packageInfo.packagePath; } diff --git a/scripts/create-component/create-component.ts b/scripts/create-component/create-component.ts index e93fa6135539cb..5b152d64ee9a69 100644 --- a/scripts/create-component/create-component.ts +++ b/scripts/create-component/create-component.ts @@ -16,7 +16,7 @@ import { names, WorkspaceJsonConfiguration } from '@nrwl/devkit'; const convergedComponentPackages = Object.entries(getAllPackageInfo()) .filter( ([pkgName, info]) => - isConvergedPackage(info.packageJson) && + isConvergedPackage({ packagePathOrJson: info.packageJson }) && pkgName.startsWith('@fluentui/react-') && info.packagePath.startsWith('packages') && !!info.packageJson.dependencies?.['@fluentui/react-utilities'], diff --git a/scripts/just.config.ts b/scripts/just.config.ts index 1672b7fa6f67f1..6406ae09cd17b7 100644 --- a/scripts/just.config.ts +++ b/scripts/just.config.ts @@ -5,7 +5,7 @@ import fs from 'fs'; import { babel } from './tasks/babel'; import { clean } from './tasks/clean'; -import { copy } from './tasks/copy'; +import { copy, copyCompiled } from './tasks/copy'; import { jest as jestTask, jestWatch } from './tasks/jest'; import { sass } from './tasks/sass'; import { ts } from './tasks/ts'; @@ -50,6 +50,7 @@ export function preset() { task('no-op', () => {}).cached(); task('clean', clean); task('copy', copy); + task('copy-compiled', copyCompiled); task('jest', jestTask); task('jest-watch', jestWatch); task('sass', sass()); @@ -91,6 +92,7 @@ export function preset() { task('ts', () => { return series( 'ts:compile', + condition('copy-compiled', () => isConvergedPackage({ projectType: 'library' })), 'ts:postprocess', condition('babel:postprocess', () => fs.existsSync(path.join(process.cwd(), '.babelrc.json'))), ); diff --git a/scripts/monorepo/findGitRoot.js b/scripts/monorepo/findGitRoot.js index 08d98e385dd2c1..93a3115ad991d7 100644 --- a/scripts/monorepo/findGitRoot.js +++ b/scripts/monorepo/findGitRoot.js @@ -6,6 +6,10 @@ const path = require('path'); let cwdForGitRoot; let gitRoot; +/** + * + * @returns {string} + */ function findGitRoot() { let cwd = process.cwd(); diff --git a/scripts/monorepo/index.d.ts b/scripts/monorepo/index.d.ts index 9f5c280ed7cb44..d1bbff5fe611a3 100644 --- a/scripts/monorepo/index.d.ts +++ b/scripts/monorepo/index.d.ts @@ -20,7 +20,7 @@ export interface PackageInfo { export type AllPackageInfo = { [packageName: string]: PackageInfo }; -export declare function findGitRoot(cwd?: string): string; +export declare function findGitRoot(): string; /** * Find all the dependencies (and their dependencies) within the repo for a specific package @@ -37,11 +37,19 @@ export declare function getAllPackageInfo(): AllPackageInfo; /** * Determines whether a package is converged, based on its version. - * @param packagePathOrJson optional different package path to run in OR previously-read package.json + * + * @param {Object} [options] + * @param {PathOrPackageJson} [options.packagePathOrJson] - optional different package path to run in OR previously-read package.json * (defaults to reading package.json from `process.cwd()`) - * @returns true if it's a converged package (version >= 9) + * @param {'library' | 'application' | 'all'} [options.projectType] - filter for what project types you wanna apply the condition + * + * @returns {boolean} true if it's a converged package (version >= 9) */ -export declare function isConvergedPackage(packagePathOrJson?: string | PackageJson): boolean; + +export declare function isConvergedPackage(option?: { + packagePathOrJson?: string | PackageJson; + projectType?: 'library' | 'application' | 'all'; +}): boolean; /** * @param since - Commit to compare against @@ -56,3 +64,18 @@ export declare function getAffectedPackages(since?: string): Set; * @returns - A git commit SHA */ export declare function getNthCommit(n = 1, ref = 'HEAD'): string; + +/** + * + * Gets project metadata from monorepo source of truth which is `workspace.json` + */ +export declare function getProjectMetadata(options: { + /** + * repo root path + */ + root?: string; + /** + * package name + */ + name: string; +}): import('@nrwl/devkit').ProjectConfiguration; diff --git a/scripts/monorepo/index.js b/scripts/monorepo/index.js index 27b511c3b90dd6..6d8e66120fd0bb 100644 --- a/scripts/monorepo/index.js +++ b/scripts/monorepo/index.js @@ -6,4 +6,5 @@ module.exports = { isConvergedPackage: require('./isConvergedPackage'), getAffectedPackages: require('./getAffectedPackages'), getNthCommit: require('./getNthCommit'), + ...require('./utils'), }; diff --git a/scripts/monorepo/isConvergedPackage.js b/scripts/monorepo/isConvergedPackage.js index 8a5e4b8a900914..018c58923a01dc 100644 --- a/scripts/monorepo/isConvergedPackage.js +++ b/scripts/monorepo/isConvergedPackage.js @@ -1,6 +1,7 @@ // @ts-check const semver = require('semver'); const { readConfig } = require('../read-config'); +const { getProjectMetadata } = require('./utils'); /** * @typedef {string | import('./index').PackageJson} PathOrPackageJson @@ -8,16 +9,32 @@ const { readConfig } = require('../read-config'); /** * Determines whether a package is converged, based on its version. - * @param {PathOrPackageJson} [packagePathOrJson] optional different package path to run in OR previously-read package.json + * + * @param {Object} [options] + * @param {PathOrPackageJson} [options.packagePathOrJson] - optional different package path to run in OR previously-read package.json * (defaults to reading package.json from `process.cwd()`) + * @param {'library' | 'application' | 'all'} [options.projectType] - filter for what project types you wanna apply the condition + * * @returns {boolean} true if it's a converged package (version >= 9) */ -function isConvergedPackage(packagePathOrJson) { +function isConvergedPackage(options = {}) { + const { packagePathOrJson, projectType = 'all' } = options; const packageJson = !packagePathOrJson || typeof packagePathOrJson === 'string' ? readConfig('package.json', /** @type {string|undefined} */ (packagePathOrJson)) : packagePathOrJson; - return !!packageJson && (semver.major(packageJson.version) >= 9 || isNightlyVersion(packageJson.version)); + + if (!packageJson) { + throw new Error(`package.json doesn't exist`); + } + + const metadata = getProjectMetadata({ name: packageJson.name }); + + if (projectType !== 'all' && metadata.projectType !== projectType) { + return false; + } + + return semver.major(packageJson.version) >= 9 || isNightlyVersion(packageJson.version); } /** diff --git a/scripts/monorepo/runPublished.js b/scripts/monorepo/runPublished.js index f8aa24ca9deee5..2b7859ea9fd093 100644 --- a/scripts/monorepo/runPublished.js +++ b/scripts/monorepo/runPublished.js @@ -29,16 +29,20 @@ const websitePackages = [ // in the root package.json's publishing-related scripts and will need to be updated if --scope changes. const beachballPackageScopes = Object.entries(getAllPackageInfo()) .filter(([, { packageJson, packagePath }]) => { - // Ignore northstar - if (/[\\/]fluentui[\\/]/.test(packagePath)) { + const isNorthstar = /[\\/]fluentui[\\/]/.test(packagePath); + + if (isNorthstar || packageJson.private === true) { return false; } + const isConverged = isConvergedPackage({ packagePathOrJson: packageJson }); if (process.env.RELEASE_VNEXT) { - return isConvergedPackage(packageJson) && packageJson.private !== true; - } else if (!isConvergedPackage(packageJson)) { + return isConverged; + } + + if (!isConverged) { // v8 scope - return packageJson.private !== true || websitePackages.includes(packageJson.name); + return websitePackages.includes(packageJson.name); } // Ignore v9/converged packages when releasing v8 diff --git a/scripts/monorepo/utils.js b/scripts/monorepo/utils.js new file mode 100644 index 00000000000000..53e6abb629ca6b --- /dev/null +++ b/scripts/monorepo/utils.js @@ -0,0 +1,21 @@ +// @ts-check + +const fs = require('fs'); +const path = require('path'); + +const findGitRoot = require('./findGitRoot'); + +/** + * Gets project metadata from monorepo source of truth which is `workspace.json` + * @param {{root?:string;name:string}} options + * @returns {import('@nrwl/devkit').ProjectConfiguration} + */ +function getProjectMetadata(options) { + const { root = findGitRoot() } = options; + /**@type {import('@nrwl/devkit').WorkspaceJsonConfiguration} */ + const nxWorkspace = JSON.parse(fs.readFileSync(path.join(root, 'workspace.json'), 'utf-8')); + + return nxWorkspace.projects[options.name]; +} + +exports.getProjectMetadata = getProjectMetadata; diff --git a/scripts/storybook/utils.js b/scripts/storybook/utils.js index 2dd53c2abbc06b..4389d48269f0ea 100644 --- a/scripts/storybook/utils.js +++ b/scripts/storybook/utils.js @@ -93,7 +93,7 @@ function getCodesandboxBabelOptions() { const allPackageInfo = getAllPackageInfo(); return Object.values(allPackageInfo).reduce((acc, cur) => { - if (isConvergedPackage(cur.packageJson)) { + if (isConvergedPackage({ packagePathOrJson: cur.packageJson, projectType: 'library' })) { const prereleaseTags = semver.prerelease(cur.packageJson.version); const isNonRcPrerelease = prereleaseTags && !prereleaseTags[0].includes('rc'); acc[cur.packageJson.name] = isNonRcPrerelease diff --git a/scripts/tasks/api-extractor.ts b/scripts/tasks/api-extractor.ts index 900f6181226447..dcebe9becf3ee4 100644 --- a/scripts/tasks/api-extractor.ts +++ b/scripts/tasks/api-extractor.ts @@ -1,8 +1,10 @@ -import fs from 'fs'; import * as glob from 'glob'; import * as path from 'path'; -import jju from 'jju'; -import { apiExtractorVerifyTask, task, series, resolveCwd, logger, TaskFunction, TscTaskOptions } from 'just-scripts'; +import { apiExtractorVerifyTask, task, series, logger, TaskFunction } from 'just-scripts'; +import { ExtractorMessageCategory } from '@microsoft/api-extractor'; +import chalk from 'chalk'; +import { getTsPathAliasesConfig, getTsPathAliasesApiExtractorConfig } from './utils'; +import { getJustArgv } from './argv'; const apiExtractorConfigs: Array< [ @@ -23,10 +25,49 @@ const apiExtractorConfigs: Array< const apiExtractorConfigsForExecution = apiExtractorConfigs.filter(([, configName]) => configName !== 'local'); -// Whether to update automatically on build -const localBuild = !process.env.TF_BUILD; +const compilerMessages = { + /** + * Module has no exported member ''. + * This error is thrown when package uses other package `@internal` API's that are removed + */ + TS2305: 'TS2305', + /** + * Could not find a declaration file for module + * This error is thrown when package depends on package that is missing rollup .d.ts (needs to be generated) + */ + TS7016: 'TS7016', +}; + +/** + * Utility to convert enums (which lack proper strict dictionary checking) to strict dictionary + * + * This is mainly needed because api-extractor ships everything as typescript enums + */ +type CreateStrictDictionary> = { [K in keyof T]: `${T[K]}` }; + +const messageCategories: CreateStrictDictionary = { + Compiler: 'Compiler', + Console: 'console', + Extractor: 'Extractor', + TSDoc: 'TSDoc', +}; + +/** + * @see https://api-extractor.com/pages/commands/api-extractor_run/ + */ +interface ApiExtractorCliRunCommandArgs { + config: string; + diagnostics: boolean; + local: boolean; + verbose: boolean; + 'typescript-compiler-folder': string; +} export function apiExtractor() { + const args: ReturnType & Partial = getJustArgv(); + + const { isUsingTsSolutionConfigs, packageJson, tsConfig, tsConfigPath } = getTsPathAliasesConfig(); + return apiExtractorConfigsForExecution.length ? (series( ...apiExtractorConfigsForExecution.map(([configPath, configName]) => { @@ -34,22 +75,51 @@ export function apiExtractor() { task( taskName, + apiExtractorVerifyTask({ - configJsonFilePath: configPath, - localBuild, + showVerboseMessages: args.verbose, + showDiagnostics: args.diagnostics, + typescriptCompilerFolder: args['typescript-compiler-folder'], + configJsonFilePath: args.config ?? configPath, + localBuild: args.local ?? !process.env.TF_BUILD, + + messageCallback: message => { + if (!isUsingTsSolutionConfigs) { + return; + } + if (message.category !== messageCategories.Compiler) { + return; + } + + if (message.messageId === compilerMessages.TS2305) { + logger.error( + chalk.bgRed.white.bold(`api-extractor | API VIOLATION:`), + chalk.red(`Looks like your package public API surface uses \`@internal\` marked API's!`), + '\n', + ); + } + + if (message.messageId === compilerMessages.TS7016) { + logger.error( + chalk.bgRed.white.bold(`api-extractor | MISSING DEPENDENCY TYPE DECLARATIONS:`), + chalk.red(`Looks like your package dependencies don't have generated index.d.ts type definitions.`), + '\n', + chalk.blueBright( + `🛠 Fix this by running: ${chalk.italic(`yarn lage generate-api --to ${packageJson.name}`)}`, + ), + '\n', + ); + } + }, onConfigLoaded: config => { - const tsConfig: TsConfig = jju.parse(fs.readFileSync(resolveCwd('./tsconfig.json'), 'utf-8')); - const isUsingTsSolutionConfigs = fs.existsSync(resolveCwd('./tsconfig.lib.json')); - - if (isUsingTsSolutionConfigs) { - logger.info(`api-extractor: package is using TS path aliases. Overriding TS compiler settings.`); - // baseUrl is the only override needed, but if any overrides are specified, API Extractor - // no longer reads the default tsconfig.json. So we have to include the whole tsconfig here. - tsConfig.compilerOptions.baseUrl = '.'; - config.compiler = { - overrideTsconfig: tsConfig, - }; + if (!isUsingTsSolutionConfigs) { + return; } + + logger.info(`api-extractor: package is using TS path aliases. Overriding TS compiler settings.`); + const compilerConfig = getTsPathAliasesApiExtractorConfig({ tsConfig, tsConfigPath, packageJson }); + + config.compiler = compilerConfig; }, }), ); @@ -68,15 +138,3 @@ export function apiExtractor() { logger.info(`skipping api-extractor execution - no configs present`); }; } - -interface TsConfig { - extends?: string; - - /** - * typescript doesn't provide a correct type for the compiler options file - * (`typescript.CompilerOptions` has enum values instead of raw options in some cases) - */ - compilerOptions: Omit; - include?: string[]; - exclude?: string[]; -} diff --git a/scripts/tasks/copy.ts b/scripts/tasks/copy.ts index 25c5caba7a215c..d4a5035f3f8e48 100644 --- a/scripts/tasks/copy.ts +++ b/scripts/tasks/copy.ts @@ -1,6 +1,8 @@ import * as fs from 'fs-extra'; import * as path from 'path'; -import { series, resolveCwd, copyTask, copyInstructionsTask } from 'just-scripts'; +import { series, resolveCwd, copyTask, copyInstructionsTask, logger } from 'just-scripts'; +import { getProjectMetadata, findGitRoot } from '../monorepo'; +import { getTsPathAliasesConfig } from './utils'; export function expandSourcePath(pattern: string): string { if (!pattern) { @@ -30,6 +32,64 @@ export function expandSourcePath(pattern: string): string { } } +/** + * + * Used solely for packages that use TS solution config files with TS path aliases + */ +export function copyCompiled() { + const { isUsingTsSolutionConfigs, packageJson, tsConfig } = getTsPathAliasesConfig(); + const root = findGitRoot(); + + const packageDir = process.cwd(); + + if (!isUsingTsSolutionConfigs) { + throw new Error(`this task compliant only with packages that use TS solution config files.`); + } + + // TODO: remove after all v9 is migrated to new build and .d.ts API stripping + const hasNewCompilationSetup = (tsConfig.compilerOptions.outDir as string).includes('dist/out-tsc'); + + if (!hasNewCompilationSetup) { + logger.info('copy-compiled: noop '); + + return; + } + + const projectMetadata = getProjectMetadata({ root, name: packageJson.name }); + + const paths = { + esm: { + in: path.join( + packageDir, + tsConfig.compilerOptions.outDir as string, + path.dirname(packageJson.module), + projectMetadata.sourceRoot, + ), + out: path.join(packageDir, path.dirname(packageJson.module)), + }, + commonJs: { + in: path.join( + packageDir, + tsConfig.compilerOptions.outDir as string, + path.dirname(packageJson.main), + projectMetadata.sourceRoot, + ), + out: path.join(packageDir, path.dirname(packageJson.main)), + }, + }; + + return series( + copyTask({ + paths: [paths.esm.in], + dest: paths.esm.out, + }), + copyTask({ + paths: [paths.commonJs.in], + + dest: paths.commonJs.out, + }), + ); +} export function copy() { const configPath = path.resolve(process.cwd(), 'config/pre-copy.json'); diff --git a/scripts/tasks/ts.ts b/scripts/tasks/ts.ts index 225504a8cc2cca..652f96151fcdc2 100644 --- a/scripts/tasks/ts.ts +++ b/scripts/tasks/ts.ts @@ -1,7 +1,7 @@ -import fs from 'fs'; import * as path from 'path'; -import { tscTask, TscTaskOptions, resolveCwd, logger } from 'just-scripts'; +import { tscTask, TscTaskOptions, logger } from 'just-scripts'; import { getJustArgv } from './argv'; +import { getTsPathAliasesConfig } from './utils'; const libPath = path.resolve(process.cwd(), 'lib'); const srcPath = path.resolve(process.cwd(), 'src'); @@ -22,18 +22,24 @@ function prepareTsTaskConfig(options: TscTaskOptions) { options.sourceMap = true; } - const tsConfigLib = 'tsconfig.lib.json'; - const isUsingTsSolutionConfigs = fs.existsSync(resolveCwd(tsConfigLib)); + const { isUsingTsSolutionConfigs, tsConfigFile, tsConfig } = getTsPathAliasesConfig(); if (isUsingTsSolutionConfigs) { - // For converged packages (which use TS path aliases), explicitly set `baseUrl` and `rootDir` to current package root. - // > - This is a temporary workaround for current way of building packages via lage and just scripts. - // > - Without setting baseUrl we would get all aliased packages build within outDir - // > - Without setting rootDir we would get output dir mapping following path from monorepo root logger.info(`📣 TSC: package is using TS path aliases. Overriding tsconfig settings.`); - options.baseUrl = '.'; - options.rootDir = './src'; - options.project = tsConfigLib; + + const tsConfigOutDir = tsConfig.compilerOptions.outDir as string; + + const hasNewCompilationSetup = tsConfigOutDir.includes('dist/out-tsc'); + + if (hasNewCompilationSetup) { + options.outDir = `${tsConfigOutDir}/${options.outDir}`; + } else { + // TODO: remove after all v9 is migrated to new build and .d.ts API stripping + options.baseUrl = '.'; + options.rootDir = './src'; + } + + options.project = tsConfigFile; } return options; diff --git a/scripts/tasks/utils.ts b/scripts/tasks/utils.ts new file mode 100644 index 00000000000000..97d3174cdfa6ff --- /dev/null +++ b/scripts/tasks/utils.ts @@ -0,0 +1,105 @@ +import * as fs from 'fs'; +import * as path from 'path'; +import * as jju from 'jju'; +import type { TscTaskOptions } from 'just-scripts'; +import { offsetFromRoot } from '@nrwl/devkit'; +import { appRootPath } from '@nrwl/tao/src/utils/app-root'; + +export function getTsPathAliasesConfig() { + const cwd = process.cwd(); + const tsConfigFile = 'tsconfig.lib.json'; + const tsConfigPath = path.join(cwd, './tsconfig.lib.json'); + const tsConfig: TsConfig | null = fs.existsSync(tsConfigPath) + ? jju.parse(fs.readFileSync(tsConfigPath, 'utf-8')) + : null; + const packageJson: PackageJson = JSON.parse(fs.readFileSync(path.join(cwd, './package.json'), 'utf-8')); + + const isUsingTsSolutionConfigs = Boolean(tsConfig); + + return { tsConfig, isUsingTsSolutionConfigs, tsConfigFile, tsConfigPath, packageJson }; +} + +const packagesWithInvalidTypes = [ + /** + * @see @storybook/api/dist/ts3.9/lib/stories.d.ts:1:8 - `import React from 'react'` + */ + '@storybook/api', +]; + +/** + * Some 3rd party packages might ship invalid types for consumers that don't have synthetic default imports enabled + * In that case our package needs to have `allowSyntheticDefaultImports` to pass the TS lib check. + * + * NOTE: This is safe to use on type declaration level for following reasons: + * - it doesn't affect emitted runtime code + * - it doesn't affect our declaration types emit + */ +function enableAllowSyntheticDefaultImports(options: { pkgJson: PackageJson }) { + const dependencies = Object.keys({ ...options.pkgJson.dependencies, ...options.pkgJson.peerDependencies }); + const shouldEnable = dependencies.some(dependency => packagesWithInvalidTypes.includes(dependency)); + + return shouldEnable ? { allowSyntheticDefaultImports: true } : null; +} + +export function getTsPathAliasesApiExtractorConfig(options: { + tsConfig: TsConfig; + tsConfigPath: string; + packageJson: PackageJson; +}) { + const rootOffset = offsetFromRoot(path.dirname(options.tsConfigPath.replace(appRootPath, ''))); + /** + * This special TSConfig config is all that's needed for api-extractor so it has all type information used for package: + * + * NOTES: + * - `compilerOptions.paths` doesn't work, nor is possible to turn them off when `extends` is used + * + */ + const apiExtractorTsConfig: TsConfig = { + include: options.tsConfig.include, + /** + * `files` might be used to specify additional `d.ts` or global type definitions. IF they exist in package tsconfig we need to include them + */ + ...(options.tsConfig.files ? { files: options.tsConfig.files } : null), + compilerOptions: { + ...enableAllowSyntheticDefaultImports({ pkgJson: options.packageJson }), + strict: true, + lib: options.tsConfig.compilerOptions.lib, + typeRoots: ['node_modules/@types', `${rootOffset}typings`], + types: options.tsConfig.compilerOptions.types, + }, + }; + + return { + /** + * explicitly turned off, as we wanna check use-cases where package B re-exports/uses `@internal` API from package A + * With this TS compiler will check for package A definition file and throw error if we violate aforementioned rule + */ + skipLibCheck: false, + overrideTsconfig: apiExtractorTsConfig, + }; +} + +interface PackageJson { + name: string; + version: string; + main: string; + module?: string; + scripts?: Record; + dependencies?: Record; + devDependencies?: Record; + peerDependencies?: Record; +} + +export interface TsConfig { + extends?: string; + + /** + * typescript doesn't provide a correct type for the compiler options file + * (`typescript.CompilerOptions` has enum values instead of raw options in some cases) + */ + compilerOptions: Omit; + files?: string[]; + include?: string[]; + exclude?: string[]; + references?: Array<{ path: string }>; +} diff --git a/tools/generators/migrate-converged-pkg/__fixtures__/conformance-setup.ts__tmpl__ b/tools/generators/migrate-converged-pkg/__fixtures__/conformance-setup.ts__tmpl__ new file mode 100644 index 00000000000000..c8dbf2f0fb36f9 --- /dev/null +++ b/tools/generators/migrate-converged-pkg/__fixtures__/conformance-setup.ts__tmpl__ @@ -0,0 +1,5 @@ +import { isConformant as baseIsConformant } from '@fluentui/react-conformance'; + +export function isConformant( + testInfo: Omit, 'componentPath'> & { componentPath?: string } +){} diff --git a/tools/generators/migrate-converged-pkg/__fixtures__/old-jest-config.js__tmpl__ b/tools/generators/migrate-converged-pkg/__fixtures__/old-jest-config.js__tmpl__ new file mode 100644 index 00000000000000..3ed4f68a5bc7f6 --- /dev/null +++ b/tools/generators/migrate-converged-pkg/__fixtures__/old-jest-config.js__tmpl__ @@ -0,0 +1,9 @@ +const { createConfig } = require('@fluentui/scripts/jest/jest-resources'); +const path = require('path'); + +const config = createConfig({ + setupFiles: [path.resolve(path.join(__dirname, 'config', 'tests.js'))], + snapshotSerializers: ['@griffel/jest-serializer'], +}); + +module.exports = config; diff --git a/tools/generators/migrate-converged-pkg/index.spec.ts b/tools/generators/migrate-converged-pkg/index.spec.ts index 398e75f99a7b5d..ec00bb46adfe2f 100644 --- a/tools/generators/migrate-converged-pkg/index.spec.ts +++ b/tools/generators/migrate-converged-pkg/index.spec.ts @@ -269,9 +269,9 @@ describe('migrate-converged-pkg generator', () => { extends: './tsconfig.json', compilerOptions: { noEmit: false, - outDir: 'dist', + outDir: '../../dist/out-tsc', declaration: true, - declarationDir: 'dist/types', + declarationDir: '../../dist/out-tsc/types', inlineSources: true, lib: ['ES2019', 'dom'], types: ['static-assets', 'environment'], @@ -785,30 +785,41 @@ describe('migrate-converged-pkg generator', () => { describe(`api-extractor.json updates`, () => { it(`should create api-extractor.json`, async () => { const projectConfig = readProjectConfiguration(tree, options.name); + const apiExtractorConfigPath = `${projectConfig.root}/config/api-extractor.json`; - expect(tree.exists(`${projectConfig.root}/config/api-extractor.json`)).toBeFalsy(); + expect(tree.exists(apiExtractorConfigPath)).toBeFalsy(); await generator(tree, options); - expect(tree.exists(`${projectConfig.root}/config/api-extractor.json`)).toBeTruthy(); + expect(tree.exists(apiExtractorConfigPath)).toBeTruthy(); + expect(readJson(tree, apiExtractorConfigPath)).toMatchInlineSnapshot(` + Object { + "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", + "dtsRollup": Object { + "enabled": true, + "publicTrimmedFilePath": "/dist/index.d.ts", + "untrimmedFilePath": "", + }, + "extends": "@fluentui/scripts/api-extractor/api-extractor.common.v-next.json", + } + `); }); - it(`should create api-extractor.local.json for scripts:docs task consumption`, async () => { + it(`should remove api-extractor.local.json if present`, async () => { const projectConfig = readProjectConfiguration(tree, options.name); + const apiExtractorLocalPath = `${projectConfig.root}/config/api-extractor.local.json`; - expect(tree.exists(`${projectConfig.root}/config/api-extractor.local.json`)).toBeFalsy(); + expect(tree.exists(apiExtractorLocalPath)).toBeFalsy(); await generator(tree, options); - /* eslint-disable @fluentui/max-len */ - expect(readJson(tree, `${projectConfig.root}/config/api-extractor.local.json`)).toMatchInlineSnapshot(` - Object { - "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", - "extends": "./api-extractor.json", - "mainEntryPointFilePath": "/dist/types/packages/react-components//src/index.d.ts", - } - `); - /* eslint-enable @fluentui/max-len */ + expect(tree.exists(apiExtractorLocalPath)).toBeFalsy(); + + writeJson(tree, apiExtractorLocalPath, {}); + + await generator(tree, options); + + expect(tree.exists(apiExtractorLocalPath)).toBeFalsy(); }); }); @@ -826,13 +837,24 @@ describe('migrate-converged-pkg generator', () => { it(`should update package npm scripts`, async () => { const projectConfig = readProjectConfiguration(tree, options.name); - let pkgJson = readJson(tree, `${projectConfig.root}/package.json`); + const pkgJsonPath = `${projectConfig.root}/package.json`; + updateJson(tree, pkgJsonPath, json => { + json.scripts.docs = 'api-extractor run --config=config/api-extractor.local.json --local'; + json.scripts['build:local'] = + // eslint-disable-next-line @fluentui/max-len + 'tsc -p ./tsconfig.lib.json --module esnext --emitDeclarationOnly && node ../../../scripts/typescript/normalize-import --output ./dist/types/packages/react-components && yarn docs'; + return json; + }); + let pkgJson = readJson(tree, pkgJsonPath); + /* eslint-disable @fluentui/max-len */ expect(pkgJson.scripts).toMatchInlineSnapshot(` Object { "build": "just-scripts build", + "build:local": "tsc -p ./tsconfig.lib.json --module esnext --emitDeclarationOnly && node ../../../scripts/typescript/normalize-import --output ./dist/types/packages/react-components && yarn docs", "clean": "just-scripts clean", "code-style": "just-scripts code-style", + "docs": "api-extractor run --config=config/api-extractor.local.json --local", "just": "just-scripts", "lint": "just-scripts lint", "start": "just-scripts dev:storybook", @@ -842,15 +864,14 @@ describe('migrate-converged-pkg generator', () => { "update-snapshots": "just-scripts jest -u", } `); + /* eslint-enable @fluentui/max-len */ await generator(tree, options); pkgJson = readJson(tree, `${projectConfig.root}/package.json`); expect(pkgJson.scripts).toEqual({ - docs: 'api-extractor run --config=config/api-extractor.local.json --local', - // eslint-disable-next-line @fluentui/max-len - 'build:local': `tsc -p ./tsconfig.lib.json --module esnext --emitDeclarationOnly && node ../../../scripts/typescript/normalize-import --output ./dist/types/packages/react-components/react-dummy/src && yarn docs`, + 'generate-api': 'tsc -p ./tsconfig.lib.json --emitDeclarationOnly && just-scripts api-extractor', build: 'just-scripts build', clean: 'just-scripts clean', 'code-style': 'just-scripts code-style', @@ -1226,6 +1247,12 @@ function setupDummyPackage( root: `packages/${normalizedPkgName}`, }; + // this is needed to stop TS parsing static imports and evaluating them in nx dep graph tree as true dependency - https://github.com/nrwl/nx/issues/8938 + const jestConfigTemplate = fs.readFileSync( + path.join(__dirname, '__fixtures__', 'old-jest-config.js__tmpl__'), + 'utf-8', + ); + const templates = { packageJson: { name: pkgName, @@ -1248,17 +1275,7 @@ function setupDummyPackage( tsConfig: { ...normalizedOptions.tsConfig, }, - jestConfig: stripIndents` - const { createConfig } = require('@fluentui/scripts/jest/jest-resources'); - const path = require('path'); - - const config = createConfig({ - setupFiles: [path.resolve(path.join(__dirname, 'config', 'tests.js'))], - snapshotSerializers: ['@griffel/jest-serializer'], - }); - - module.exports = config; - `, + jestConfig: stripIndents`${jestConfigTemplate}`, jestSetupFile: stripIndents` /** Jest test setup file. */ `, @@ -1333,16 +1350,9 @@ function setupDummyPackage( } function addConformanceSetup(tree: Tree, projectConfig: ReadProjectConfiguration) { - tree.write( - `${projectConfig.root}/src/common/isConformant.ts`, - stripIndents` - import { isConformant as baseIsConformant } from '@fluentui/react-conformance'; - - export function isConformant( - testInfo: Omit, 'componentPath'> & { componentPath?: string } - ){} - `, - ); + // this is needed to stop TS parsing static imports and evaluating them in nx dep graph tree as true dependency - https://github.com/nrwl/nx/issues/8938 + const template = fs.readFileSync(path.join(__dirname, '__fixtures__', 'conformance-setup.ts__tmpl__'), 'utf-8'); + tree.write(`${projectConfig.root}/src/common/isConformant.ts`, stripIndents`${template}`); } function addUnstableSetup(tree: Tree, projectConfig: ReadProjectConfiguration) { diff --git a/tools/generators/migrate-converged-pkg/index.ts b/tools/generators/migrate-converged-pkg/index.ts index fb32829753dfa8..29c4beaa87d572 100644 --- a/tools/generators/migrate-converged-pkg/index.ts +++ b/tools/generators/migrate-converged-pkg/index.ts @@ -145,30 +145,27 @@ function runMigrationOnProject(tree: Tree, schema: AssertedSchema, _userLog: Use // ==== helpers ==== const templates = { - apiExtractor: (options: { tsconfig: TsConfig }) => { - const { tsconfig } = options; - if (!tsconfig.compilerOptions.declarationDir) { - throw new Error(`Provided TS config is missing declarationDir.`); - } - - /* eslint-disable @fluentui/max-len */ + apiExtractor: () => { return { main: { $schema: 'https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json', extends: '@fluentui/scripts/api-extractor/api-extractor.common.v-next.json', - // @TODO - remove this once all v9 packages have been migrated to ship rolluped types - mainEntryPointFilePath: `/${tsconfig.compilerOptions.declarationDir}/index.d.ts`, - }, - local: { - $schema: 'https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json', - extends: './api-extractor.json', - mainEntryPointFilePath: `/${tsconfig.compilerOptions.declarationDir}/packages/react-components//src/index.d.ts`, + // TODO: remove after all v9 is migrated to new build and .d.ts API stripping + dtsRollup: { + enabled: true, + untrimmedFilePath: '', + publicTrimmedFilePath: '/dist/index.d.ts', + }, }, - /* eslint-enable @fluentui/max-len */ }; }, - tsconfig: (options: { platform: 'node' | 'web'; js: boolean; hasConformance: boolean }) => { + tsconfig: (options: { + platform: 'node' | 'web'; + js: boolean; + hasConformance: boolean; + projectConfig: ProjectConfiguration; + }) => { return { main: () => { const tsConfig = { @@ -209,9 +206,9 @@ const templates = { compilerOptions: { noEmit: false, lib: ['ES2019'], - outDir: 'dist', declaration: true, - declarationDir: 'dist/types', + declarationDir: offsetFromRoot(options.projectConfig.root) + 'dist/out-tsc/types', + outDir: offsetFromRoot(options.projectConfig.root) + 'dist/out-tsc', inlineSources: true, types: ['static-assets', 'environment'], } as TsConfig['compilerOptions'], @@ -545,14 +542,11 @@ interface NormalizedSchemaWithTsConfigs extends NormalizedSchema { } function updatePackageJson(tree: Tree, options: NormalizedSchemaWithTsConfigs) { - /* eslint-disable @fluentui/max-len */ const scripts = { - docs: 'api-extractor run --config=config/api-extractor.local.json --local', - 'build:local': `tsc -p ./tsconfig.lib.json --module esnext --emitDeclarationOnly && node ../../../scripts/typescript/normalize-import --output ./${options.tsconfigs.lib.compilerOptions.declarationDir}/packages/react-components/${options.normalizedPkgName}/src && yarn docs`, + 'generate-api': 'tsc -p ./tsconfig.lib.json --emitDeclarationOnly && just-scripts api-extractor', test: 'jest --passWithNoTests', 'type-check': 'tsc -b tsconfig.json', }; - /* eslint-enable @fluentui/max-len */ updateJson(tree, options.paths.packageJson, (json: PackageJson) => { json.scripts = json.scripts || {}; @@ -561,6 +555,8 @@ function updatePackageJson(tree: Tree, options: NormalizedSchemaWithTsConfigs) { delete json.scripts['update-snapshots']; delete json.scripts['start-test']; delete json.scripts['test:watch']; + delete json.scripts['build:local']; + delete json.scripts.docs; Object.assign(json.scripts, scripts); @@ -576,8 +572,9 @@ function updatePackageJson(tree: Tree, options: NormalizedSchemaWithTsConfigs) { } function updateApiExtractorForLocalBuilds(tree: Tree, options: NormalizedSchemaWithTsConfigs) { - const apiExtractor = templates.apiExtractor({ tsconfig: options.tsconfigs.lib }); - writeJson(tree, joinPathFragments(options.paths.configRoot, 'api-extractor.local.json'), apiExtractor.local); + const apiExtractor = templates.apiExtractor(); + + tree.delete(joinPathFragments(options.paths.configRoot, 'api-extractor.local.json')); writeJson(tree, joinPathFragments(options.paths.configRoot, 'api-extractor.json'), apiExtractor.main); return tree; @@ -847,7 +844,12 @@ function createTsSolutionConfig(tree: Tree, options: NormalizedSchema) { const js = isJs(tree, options); const hasConformance = hasConformanceSetup(tree, options); - const tsConfigs = templates.tsconfig({ platform: packageType, js, hasConformance }); + const tsConfigs = templates.tsconfig({ + platform: packageType, + js, + hasConformance, + projectConfig: options.projectConfig, + }); const main = tsConfigs.main(); const lib = tsConfigs.lib(); const test = tsConfigs.test();