diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 00000000..aebd91c5 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v22.16.0 diff --git a/package.json b/package.json index 09ebf5de..267f6b86 100644 --- a/package.json +++ b/package.json @@ -17,5 +17,5 @@ "devDependencies": { "typescript": "^5.2.2" }, - "packageManager": "pnpm@8.6.12" + "packageManager": "pnpm@10.12.1" } diff --git a/packages/cli/package.json b/packages/cli/package.json index 4b0488ea..3531e557 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -13,11 +13,11 @@ "commander": "^11.0.0", "glob": "^10.3.10", "liquidjs": "^10.9.2", - "next": "^13.5.2", + "next": "^15.3.4", "pino": "^8.15.7", "pino-pretty": "^10.2.3" }, "devDependencies": { - "@types/node": "20.4.2" + "@types/node": "22.15.32" } } diff --git a/packages/compose/src/components.tsx b/packages/compose/src/components.tsx index a79388d5..e8d8d0ac 100644 --- a/packages/compose/src/components.tsx +++ b/packages/compose/src/components.tsx @@ -29,7 +29,7 @@ export function Card ({ }: CardProps) { return ( - + {children} ); diff --git a/packages/compose/src/factory.ts b/packages/compose/src/factory.ts index 6da5f0ee..5db5a006 100644 --- a/packages/compose/src/factory.ts +++ b/packages/compose/src/factory.ts @@ -2,7 +2,7 @@ import { BuiltinWidgetsMap } from '@ossinsight/widgets-core/src/renderer/builtin import { isEmptyData } from '@ossinsight/widgets-core/src/utils/datasource'; import { FlexBaseLayout, GridLayout, Layout, WidgetLayout } from '@ossinsight/widgets-utils/src/compose'; -function Compose (component: any, props: any, ...children: any): Layout { +function Compose (component: any, props: any, ...children: any): Layout | null { const { padding = 0, gap = 0, size = undefined, grow = undefined, data, ifEmpty, ...restProps } = props; if (ifEmpty) { if (isEmptyData(data)) { @@ -12,7 +12,7 @@ function Compose (component: any, props: any, ...children: any): Layout { layout: 'widget', widget: 'builtin:empty', data: {}, - parameters: undefined, + parameters: {}, children: [], }; } @@ -34,7 +34,7 @@ function Compose (component: any, props: any, ...children: any): Layout { } // flatten children to a single array and remove falsy values. - children = children.filter(Boolean).flatMap(child => child); + children = children.filter(Boolean).flatMap((child: any) => child); if (typeof component === 'function') { return component({ ...props, children }); diff --git a/packages/compose/tsconfig.json b/packages/compose/tsconfig.json index 034b1b30..86bcda85 100644 --- a/packages/compose/tsconfig.json +++ b/packages/compose/tsconfig.json @@ -8,7 +8,9 @@ "outDir": "dist", "rootDir": "src", "sourceMap": true, - "jsx": "react-jsx" + "jsx": "react-jsx", + "strict": true, + "skipLibCheck": true }, "include": ["src"], "exclude": [ diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 33422402..fe9eabac 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -8,11 +8,12 @@ "dev": "tsc -w" }, "devDependencies": { + "@types/eslint": "^9.6.1", "@types/node": "20.4.2", - "eslint": "8.45.0" + "eslint": "^9.29.0" }, "peerDependencies": { - "eslint": "8.45.0" + "eslint": "^9.29.0" }, "dependencies": { "@stoplight/json": "^3.21.0", diff --git a/packages/eslint-plugin/src/index.ts b/packages/eslint-plugin/src/index.ts index ab602c89..c613c3d4 100644 --- a/packages/eslint-plugin/src/index.ts +++ b/packages/eslint-plugin/src/index.ts @@ -44,6 +44,8 @@ const plugin: ESLint.Plugin = { return []; case 'ref': return validateRefDatasource(result, datasource, i); + default: + return []; } } } diff --git a/packages/eslint-plugin/src/rules/datasource-ref.ts b/packages/eslint-plugin/src/rules/datasource-ref.ts index 7fd091d2..8f13111f 100644 --- a/packages/eslint-plugin/src/rules/datasource-ref.ts +++ b/packages/eslint-plugin/src/rules/datasource-ref.ts @@ -20,7 +20,7 @@ export function validateRefDatasource (result: JsonParserResult, datasource return [{ ruleId: 'ossinsight/datasource-ref', ...transformJsonRange(location), - message: e.message, + message: (((e as Error)?.message ?? 'Unknown Error') || String(e)), severity: 2, }]; } diff --git a/packages/eslint-plugin/src/rules/datasource-schema.ts b/packages/eslint-plugin/src/rules/datasource-schema.ts index 9ad9942e..96276b79 100644 --- a/packages/eslint-plugin/src/rules/datasource-schema.ts +++ b/packages/eslint-plugin/src/rules/datasource-schema.ts @@ -8,7 +8,7 @@ export function validateDatasourceSchema (result: JsonParserResult): Linter const res = datasourceSchema(result.data); if (!res) { - return transformJsonSchemaErrorObject('ossinsight/datasource-schema', result, datasourceSchema.errors); + return transformJsonSchemaErrorObject('ossinsight/datasource-schema', result, datasourceSchema.errors ?? []); } return []; diff --git a/packages/eslint-plugin/src/rules/params-schema.ts b/packages/eslint-plugin/src/rules/params-schema.ts index 184828f7..a5fd72d9 100644 --- a/packages/eslint-plugin/src/rules/params-schema.ts +++ b/packages/eslint-plugin/src/rules/params-schema.ts @@ -8,7 +8,7 @@ export function validateParamsSchema (result: JsonParserResult): Linter.Lin const res = paramsSchema(result.data); if (!res) { - return transformJsonSchemaErrorObject('ossinsight/params-schema', result, paramsSchema.errors); + return transformJsonSchemaErrorObject('ossinsight/params-schema', result, paramsSchema.errors ?? []); } return []; diff --git a/packages/eslint-plugin/tsconfig.json b/packages/eslint-plugin/tsconfig.json index eee456a1..9a8a2412 100644 --- a/packages/eslint-plugin/tsconfig.json +++ b/packages/eslint-plugin/tsconfig.json @@ -3,7 +3,7 @@ "module": "NodeNext", "lib": ["ESNext"], "target": "ESNext", - "strict": false, + "strict": true, "moduleResolution": "nodenext", "isolatedModules": false, "esModuleInterop": true, diff --git a/packages/ui/package.json b/packages/ui/package.json index b5b5f901..ce4ced5a 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -7,60 +7,38 @@ "@headlessui/react": "^1.7.17", "@ossinsight/widgets-utils": "workspace:^", "@primer/octicons-react": "^19.7.0", - "@radix-ui/react-avatar": "^1.0.3", - "@radix-ui/react-label": "^2.0.2", - "@radix-ui/react-menubar": "^1.0.3", - "@radix-ui/react-popover": "^1.0.6", - "@radix-ui/react-select": "^1.2.2", - "@radix-ui/react-tabs": "^1.0.4", - "@radix-ui/react-toggle-group": "^1.0.4", - "@radix-ui/react-tooltip": "^1.0.6", + "radix-ui": "^1.4.2", "clsx": "^2.0.0", "react-transition-state": "^2.1.1", "react-window": "^1.8.9", "rehype-react": "^7.2.0", "remark-parse": "^10.0.2", "remark-rehype": "^10.1.0", - "tailwind-merge": "^1.14.0", + "tailwind-merge": "^2.6.0", "unified": "^10.1.2" }, "devDependencies": { "@faker-js/faker": "^8.1.0", - "@storybook/addon-essentials": "^7.4.3", - "@storybook/addon-interactions": "^7.4.3", - "@storybook/addon-links": "^7.4.3", - "@storybook/addon-onboarding": "^1.0.8", - "@storybook/addon-styling": "^1.3.7", - "@storybook/blocks": "^7.4.3", - "@storybook/nextjs": "^7.4.3", - "@storybook/react": "^7.4.3", - "@storybook/testing-library": "^0.2.1", - "@storybook/theming": "^7.4.3", "@svgr/webpack": "^8.1.0", "@types/mdast": "^4.0.0", - "@types/react": "18.2.15", - "@types/react-dom": "18.2.7", + "@types/react": "19.1.0", + "@types/react-dom": "^19.1.6", "@types/react-window": "^1.8.5", "autoprefixer": "10.4.14", "bootstrap-icons": "^1.11.1", "highlight.js": "^11.8.0", - "next": "^13.5.2", + "next": "^15.3.4", "postcss": "8.4.26", - "react": "18.2.0", - "react-dom": "18.2.0", + "react": "19.2.0-canary-3fbfb9ba-20250409", + "react-dom": "19.2.0-canary-3fbfb9ba-20250409", "sass": "^1.68.0", - "storybook": "^7.4.3", "tailwindcss": "3.3.3" }, "peerDependencies": { "bootstrap-icons": "^1.10.5", - "next": "^13.5.2", - "react": "18.2.0", - "react-dom": "18.2.0", - "tailwindcss": "3.3.3" - }, - "scripts": { - "storybook": "storybook dev --no-open -p 6006", - "build-storybook": "storybook build" + "next": "^15.3.4", + "react": "19.2.0-canary-3fbfb9ba-20250409", + "react-dom": "19.2.0-canary-3fbfb9ba-20250409", + "tailwindcss": "3.4.17" } } diff --git a/packages/ui/src/components/Button/styles.scss b/packages/ui/src/components/Button/styles.scss index c4e3da9d..5de90abc 100644 --- a/packages/ui/src/components/Button/styles.scss +++ b/packages/ui/src/components/Button/styles.scss @@ -1,4 +1,5 @@ -@import "../../styles/controls"; +@use "../../styles/theme" as *; +@use "../../styles/controls" as *; .Button { @apply px-2 py-1 text-sm border transition inline-flex items-center justify-center gap-1; diff --git a/packages/ui/src/components/GHAvatar/GHAvatar.tsx b/packages/ui/src/components/GHAvatar/GHAvatar.tsx index 9c6d4661..98aa6686 100644 --- a/packages/ui/src/components/GHAvatar/GHAvatar.tsx +++ b/packages/ui/src/components/GHAvatar/GHAvatar.tsx @@ -1,4 +1,4 @@ -import * as RuiAvatar from '@radix-ui/react-avatar'; +import { Avatar as RuiAvatar } from 'radix-ui'; import { AvatarSkeleton } from '../Skeleton'; export interface GHAvatarProps { diff --git a/packages/ui/src/components/GHRepoSelector/GHOrgRepoSelector.tsx b/packages/ui/src/components/GHRepoSelector/GHOrgRepoSelector.tsx index ab263312..e0e696b0 100644 --- a/packages/ui/src/components/GHRepoSelector/GHOrgRepoSelector.tsx +++ b/packages/ui/src/components/GHRepoSelector/GHOrgRepoSelector.tsx @@ -1,27 +1,13 @@ +import { Popover, Transition } from '@headlessui/react'; +import { ChevronDownIcon, RepoIcon, SearchIcon } from '@primer/octicons-react'; +import * as React from 'react'; +import { FixedSizeList, ListChildComponentProps } from 'react-window'; +import '../Selector/style.scss'; import { RemoteSelector, RemoteSelectorProps } from '../RemoteSelector'; import { GHRepoItem } from './GHRepoItem'; import { GHRepoListItem } from './GHRepoListItem'; -import { - getRepoText, - isRepoEquals, - searchRepo, - getRepoListByOrgId, -} from './utils'; import type { RemoteRepoInfo } from './GHRepoSelector'; -import * as React from 'react'; -import * as SelectPrimitive from '@radix-ui/react-select'; -import CheckIcon from 'bootstrap-icons/icons/check.svg'; -import { - RepoIcon, - SearchIcon, - ChevronUpIcon, - ChevronDownIcon, -} from '@primer/octicons-react'; -import { twMerge } from 'tailwind-merge'; -import '../Selector/style.scss'; -import { Select } from '../Selector'; -import { Listbox, Transition, Popover } from '@headlessui/react'; -import { FixedSizeList, ListChildComponentProps } from 'react-window'; +import { getRepoListByOrgId, getRepoText, isRepoEquals, searchRepo } from './utils'; export interface GHOrgRepoSelectorProps extends Pick, 'id' | 'renderInput'> { @@ -34,7 +20,7 @@ export interface GHOrgRepoSelectorProps disableInput?: boolean; } -export function GHOrgRepoSelector({ +export function GHOrgRepoSelector ({ repos, onRepoSelected, onRepoRemoved, @@ -92,25 +78,25 @@ export function GHOrgRepoSelector({ ); } -function SearchInput(props: React.InputHTMLAttributes) { +function SearchInput (props: React.InputHTMLAttributes) { return (
-
-
-
@@ -225,30 +211,30 @@ export function HLGHOrgRepoSelectorTemplate(props: { return ( <> - + {({ open }) => { return ( <> - - + + {selectedItems.length === 0 ? ( <>{allItem.name} ) : ( selectedItems.map((i) => i.name).join(', ') )} - - + + {/* TODO - fix repos.length mismatch public repos sum */} {/* {parseItemsLength( - selectedItems.length === 0 - ? repos.length - : selectedItems.length - )} */} + selectedItems.length === 0 + ? repos.length + : selectedItems.length + )} */} {selectedItems.length === 0 ? `All` : parseItemsLength(selectedItems.length)} @@ -257,25 +243,25 @@ export function HLGHOrgRepoSelectorTemplate(props: { className={`h-5 w-5 text-gray-400 transition ease-in duration-100 ${ open ? 'transform rotate-180' : '' }`} - aria-hidden='true' + aria-hidden="true" /> - + -
+
{/* -- search input -- */}
@@ -326,11 +312,11 @@ export function HLGHOrgRepoSelectorTemplate(props: { // all selected, unselect all if ( filteredReposMemo.every((i) => - selectedItems.includes(i) + selectedItems.includes(i), ) ) { const result = selectedItems.filter( - (i) => !filteredReposMemo.includes(i) + (i) => !filteredReposMemo.includes(i), ); setSelectedItems(result); return; @@ -339,7 +325,7 @@ export function HLGHOrgRepoSelectorTemplate(props: { const result = [ ...selectedItems, ...filteredReposMemo.filter( - (i) => !selectedItems.includes(i) + (i) => !selectedItems.includes(i), ), ]; setSelectedItems(result); @@ -356,20 +342,20 @@ export function HLGHOrgRepoSelectorTemplate(props: { {`Select all '${deferredText}'`} 0 && filteredReposMemo.every((i) => - selectedItems.includes(i) + selectedItems.includes(i), ) } readOnly - className='absolute inset-y-0 left-0 flex items-center ml-3 mt-2.5 text-[var(--text-color-subtitle)] h-4 w-4 rounded border-gray-300 focus:ring-[var(--selector-border-color)] accent-[var(--selector-fill-color)]' + className="absolute inset-y-0 left-0 flex items-center ml-3 mt-2.5 text-[var(--text-color-subtitle)] h-4 w-4 rounded border-gray-300 focus:ring-[var(--selector-border-color)] accent-[var(--selector-fill-color)]" />
)} -
+
{/* -- list all repos -- */} ( - defaultSelectedIds.length === 0 ? [] : null + defaultSelectedIds.length === 0 ? [] : null, ); React.useEffect(() => { diff --git a/packages/ui/src/components/InputPopover/InputPopover.tsx b/packages/ui/src/components/InputPopover/InputPopover.tsx index 2e818c8c..d031bdf7 100644 --- a/packages/ui/src/components/InputPopover/InputPopover.tsx +++ b/packages/ui/src/components/InputPopover/InputPopover.tsx @@ -1,5 +1,5 @@ -import * as RuiPopover from '@radix-ui/react-popover'; import clsx from 'clsx'; +import { Popover as RuiPopover } from 'radix-ui'; import { ReactElement, ReactNode } from 'react'; import { preventDefault } from '../../utils/event'; @@ -9,7 +9,7 @@ export interface InputPopoverProps { input: ReactElement; popperContent: ReactNode; - popoverPortalProps?: Omit; + popoverPortalProps?: Omit; popoverContentProps?: Omit; } diff --git a/packages/ui/src/components/Selector/Select.tsx b/packages/ui/src/components/Selector/Select.tsx index 983c6ad8..7ccd153a 100644 --- a/packages/ui/src/components/Selector/Select.tsx +++ b/packages/ui/src/components/Selector/Select.tsx @@ -1,17 +1,13 @@ -import * as SelectPrimitive from '@radix-ui/react-select'; +import { Listbox, Transition } from '@headlessui/react'; +import { ChevronDownIcon as GHChevronDownIcon } from '@primer/octicons-react'; import CheckIcon from 'bootstrap-icons/icons/check.svg'; import ChevronDownIcon from 'bootstrap-icons/icons/chevron-down.svg'; import ChevronUpIcon from 'bootstrap-icons/icons/chevron-up.svg'; import clsx from 'clsx'; +import { Select as SelectPrimitive } from 'radix-ui'; import * as React from 'react'; import { ReactNode } from 'react'; import './style.scss'; -import { Listbox, Transition } from '@headlessui/react'; -import { - ChevronUpIcon as GHChevronUpIcon, - ChevronDownIcon as GHChevronDownIcon, - CheckIcon as GHCheckIcon, -} from '@primer/octicons-react'; export const Select = React.forwardRef< HTMLButtonElement, @@ -121,7 +117,7 @@ export type SelectParamOption = { [key: string]: any; }; -export function HLSelect(props: { +export function HLSelect (props: { value: SelectParamOption; onChange: (v: SelectParamOption) => void; options: Array>; @@ -132,26 +128,26 @@ export function HLSelect(props: { return ( <> -
- - +
+ + {startIcon} {value.title} - + - + {options.map((opt) => ( (props: { {opt.title} {selected ? ( - -