diff --git a/package.json b/package.json index c0318e64165..ffded991e0f 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,9 @@ "publish-npm": "lerna run --scope @razorpay/blade publish-npm", "release": "lerna run --scope @razorpay/blade generate-github-npmrc && changeset publish", "build": "lerna run --scope @razorpay/blade build", - "postinstall": "lerna run --scope eslint-plugin-blade build" + "postinstall": "lerna run --scope eslint-plugin-blade build", + "aicodemod:serve": "node packages/blade/codemods/aicodemod/server.mjs", + "aicodemod:host": "npx localtunnel --port 3000 --subdomain blade-ds" }, "dependencies": {}, "devDependencies": { diff --git a/packages/blade/codemods/aicodemod/README.md b/packages/blade/codemods/aicodemod/README.md new file mode 100644 index 00000000000..cbac1133dca --- /dev/null +++ b/packages/blade/codemods/aicodemod/README.md @@ -0,0 +1,26 @@ +# Blade AI Codemod + +## 1. Install Blade Globally + +```sh +npm install -g @razorpay/blade +``` + +## 2. Run `aicodemod` Command to Migrate + +```sh +aicodemod + --code-knowledge presets/dashboard/table-pattern-1 +``` + +`--code-knowledge`: The AI needs some info about existing codebase and some patterns on how to migrate. We currently have created a preset knowledge for migrating one of the patterns in table. + +## 3. Fix any visual or syntax issues if there + +AI Codemod is there to help you get going with migration. You might still have 10% work left to review if the code logic is in place and visually things are looking as expected. + +> [!NOTE] +> +> **POC Limitations** +> +> As currently its just POC, its optimized to only migrate to Blade Table component. It can also diff --git a/packages/blade/codemods/aicodemod/bin.mjs b/packages/blade/codemods/aicodemod/bin.mjs new file mode 100755 index 00000000000..06d44e1cd22 --- /dev/null +++ b/packages/blade/codemods/aicodemod/bin.mjs @@ -0,0 +1,128 @@ +#!/usr/bin/env node +import fs from 'fs'; +import path from 'path'; + +const getFlagValue = (flag) => { + const flagIndex = process.argv.indexOf(flag); + if (flagIndex < 0) { + return undefined; + } + + return process.argv[flagIndex + 1]; +}; + +// This is for passing ngrok instance URL +const BASE_URL = 'https://blade-chat.dev.razorpay.in'; +const SERVER_ENDPOINT = '/chat'; + +const preset = getFlagValue('--code-knowledge') ?? 'presets/dashboard/table-pattern-1'; + +const getChatCompletionFromServer = async (messages) => { + const url = BASE_URL + SERVER_ENDPOINT; + + // Define the fetch options + const options = { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'rzpctx-dev-serve-user': 'base', + }, + body: JSON.stringify({ input: messages }), + }; + + try { + // Make the fetch call + const response = await fetch(url, options); + return response.text(); + } catch (err) { + throw err; + } +}; + +const __dirname = new URL('.', import.meta.url).pathname; +const cwd = process.cwd(); + +let codeKnowledge; +const consumerPresetPath = path.join(cwd, preset); +const predefinedPresetPath = path.join(__dirname, 'knowledge', `${preset}.md`); + +if (fs.existsSync(consumerPresetPath)) { + codeKnowledge = fs.readFileSync(consumerPresetPath, 'utf-8'); +} else { + codeKnowledge = fs.readFileSync(predefinedPresetPath, 'utf-8'); +} + +const bladeKnowledge = fs.readFileSync(path.resolve(__dirname, './knowledge/Table.md'), 'utf-8'); + +const usageFileArg = process.argv[2]; +const usageFilePath = path.join(cwd, usageFileArg); +const usage = fs.readFileSync(usageFilePath, 'utf-8'); + +const ultimatePrompt = ` +I want you to migrate our old codebase code from custom implementation, to use our design-system component called Blade. + +You will find code snippets of these things below- + +1. Blade's Table Documentation: Documentation of our design-system table +2. Custom Component Definitions: Custom component implementations to help figure out what some of the internally used components do +3. Migration Example: A reference example of migration. How the output migrated code would look like on given certain input. +4. Code to Migrate: Migrate this code to use our design-system components + +Return Format: +- Refer to Blade's Table documentation and Custom Component Definitons and Migration Example and return the migrated code snippet of usage using Blade +- Return raw migrated code without additional text +- Don't change unrelated code and imports +- If something existed in previous code, but does not map to anything in new code. Add a TODO comment describing what needs to be done +- Remove unused variables, functions, and imports +- Make sure Blade's Header and Footer are also used wherever needed. +- Ignore the code related to mobile responsiveness as Blade components are responsive by default + +## 1. Blade's Table Documentation +${bladeKnowledge} + +${codeKnowledge} + +## 4. Code to Migrate +\`\`\`jsx +${usage} +\`\`\` +`; + +const messages = [ + { + role: 'system', + content: [ + { + type: 'text', + text: + 'You are an AI assistant that helps in migrating codebase from old custom implementation to our internal design-system components', + }, + ], + }, + { + role: 'user', + content: [ + { + type: 'text', + text: ultimatePrompt, + }, + ], + }, +]; + +const answer = await getChatCompletionFromServer(messages); + +if (answer) { + console.log('USAGE STATS', { + inputLength: JSON.stringify(messages).length, + }); + + const cleanOut = answer.startsWith('```jsx') + ? answer.slice(`\`\`\`jsx`.length + 1, -('```'.length + 1)) + : answer; + fs.writeFileSync(usageFilePath, cleanOut); +} else { + console.log( + "Something's not right. The server didn't respond correctly. Hopefully there are more helpful logs above ^^", + ); +} diff --git a/packages/blade/codemods/aicodemod/knowledge/Table.md b/packages/blade/codemods/aicodemod/knowledge/Table.md new file mode 100644 index 00000000000..30d77d70df7 --- /dev/null +++ b/packages/blade/codemods/aicodemod/knowledge/Table.md @@ -0,0 +1,596 @@ +# Table + +A table component helps in displaying data in a grid format, through rows and columns of cells. Table facilitates data organisation and allow users to: scan, sort, compare, and take action on large amounts of data. + +## Props + +```ts +type TableNode = Item & { + id: Identifier; +}; + +type TableData = { + nodes: TableNode[]; +}; + +type TableBackgroundColors = `surface.background.gray.${DotNotationToken< + Theme['colors']['surface']['background']['gray'] +>}`; + +type TableHeaderProps = { + /** + * The children of TableHeader should be TableHeaderRow + * @example + * + * + * Header Cell 1 + * + * + **/ + children: React.ReactNode; +}; + +type TableHeaderRowProps = { + /** + * The children of TableHeaderRow should be TableHeaderCell + * @example + * + * + * Header Cell 1 + * + * + **/ + children: React.ReactNode; + /** + * The rowDensity prop determines the density of the table. + * The rowDensity prop can be 'compact', 'normal', or'comfortable'. + * The default value is `normal`. + **/ + rowDensity?: TableProps['rowDensity']; +}; + +type TableHeaderCellProps = { + /** + * The children of TableHeaderCell can be a string or a ReactNode. + **/ + children: string | React.ReactNode; + /** + * The unique key of the column. + * This is used to identify the column for sorting in sortFunctions prop of Table. + * Sorting is enabled only for columns whose key is present in sortableColumns prop of Table. + **/ + headerKey?: string; +}; + +type TableProps = { + /** + * The children of the Table component should be a function that returns TableHeader, TableBody and TableFooter components. + * The function will be called with the tableData prop. + */ + children: (tableData: TableNode[]) => React.ReactElement; + /** + * The data prop is an object with a nodes property that is an array of objects. + * Each object in the array is a row in the table. + * The object should have an id property that is a unique identifier for the row. + */ + data: TableData; + /** + * Selection mode determines how the table rows can be selected. + * @default 'row' + **/ + multiSelectTrigger?: 'checkbox' | 'row'; + /** + * The selectionType prop determines the type of selection that is allowed on the table. + * The selectionType prop can be 'none', 'single' or 'multiple'. + * @default 'none' + **/ + selectionType?: 'none' | 'single' | 'multiple'; + /** + * The onSelectionChange prop is a function that is called when the selection changes. + * The function is called with an object that has a values property that is an array of the selected rows. + **/ + onSelectionChange?: ({ + values, + selectedIds, + }: { + /** + * Note: on server side paginated data, this prop will only contain the selected rows on the current page. + * + * Thus, it's recommended to use `selectedIds` for more consistent state management across server/client paginated data. + * + * *Deprecated:* Use `selectedIds` instead. + * + * @deprecated + */ + values: TableNode[]; + /** + * An array of selected row ids. + */ + selectedIds: Identifier[]; + }) => void; + /** + * The isHeaderSticky prop determines whether the table header is sticky or not. + * The default value is `false`. + **/ + isHeaderSticky?: boolean; + /** + * The isFooterSticky prop determines whether the table footer is sticky or not. + * The default value is `false`. + **/ + isFooterSticky?: boolean; + /** + * The isFirstColumnSticky prop determines whether the first column is sticky or not. + * The default value is `false`. + **/ + isFirstColumnSticky?: boolean; + /** + * The rowDensity prop determines the density of the table. + * The rowDensity prop can be 'compact', 'normal', or'comfortable'. + * The default value is `normal`. + **/ + rowDensity?: 'compact' | 'normal' | 'comfortable'; + /** + * The onSortChange prop is a function that is called when the sort changes. + * The function is called with an object that has a sortKey property that is the key of the column that is sorted and a isSortReversed property that is a boolean that determines whether the sort is reversed or not. + **/ + onSortChange?: ({ + sortKey, + isSortReversed, + }: { + sortKey: TableHeaderCellProps['headerKey']; + isSortReversed: boolean; + }) => void; + /** + * The sortFunctions prop is an object that has a key for each column that is sortable. + * The value of each key is a function that is called when the column is sorted. + * The function is called with an array of the rows in the table. + * The function should return an array of the rows in the table. + **/ + sortFunctions?: Record[]) => TableNode[]>; + /** + * The toolbar prop is a React element that is rendered above the table. + * The toolbar prop should be a `TableToolbar` component. + **/ + toolbar?: React.ReactElement; + /** + * The pagination prop is a React element that is rendered below the table. + * The pagination prop should be a `TablePagination` component. + **/ + pagination?: React.ReactElement; + /** + * The height prop is a responsive styled prop that determines the height of the table. + **/ + height?: BoxProps['height']; + /** + * The showStripedRows prop determines whether the table should have striped rows or not. + * The default value is `false`. + **/ + showStripedRows?: boolean; + /** + * The gridTemplateColumns prop determines the grid-template-columns CSS property of the table. + * The default value is `repeat(${columnCount},minmax(100px, 1fr))`. + **/ + gridTemplateColumns?: string; + /** + * The isLoading prop determines whether the table is loading or not. + * The default value is `false`. + **/ + isLoading?: boolean; + /** + * The isRefreshing prop determines whether the table is refreshing or not. + * The default value is `false`. + **/ + isRefreshing?: boolean; + /** + * The showBorderedCells prop determines whether the table should have bordered cells or not. + **/ + showBorderedCells?: boolean; +} & StyledPropsBlade; + +type Identifier = string | number; + +type TableBodyProps = { + /** + * The children of the TableBody component should be TableRow components. + * @example + * + * + * ... + * + * + **/ + children: React.ReactNode; +}; + +type TableRowProps = { + /** + * The children of the TableRow component should be TableCell components. + * @example + * + * ... + * + **/ + children: React.ReactNode; + /** + * The item prop is used to pass the individual table item to the TableRow component. + * @example + * tableData.map((tableItem) => ( + * + * ... + * + * )); + **/ + item: TableNode; + /** + * The isDisabled prop is used to disable the TableRow component. + * @example + * + * ... + * + **/ + isDisabled?: boolean; + /** + * Callback triggered when the row is hovered. It is called with the current row item prop. + */ + onHover?: ({ item }: { item: TableNode }) => void; + /** + * Callback triggered when the row is clicked. It is called with the current row item prop. + */ + onClick?: ({ item }: { item: TableNode }) => void; +}; + +type TableCellProps = { + /** + * The children of the TableCell component should be a string or a ReactNode. + * @example + * {'Hello'} + * + * ... + * + * + * + * + **/ + children: React.ReactNode; +}; + +type TableEditableCellProps = Pick< + BaseInputProps, + | 'validationState' + | 'placeholder' + | 'defaultValue' + | 'name' + | 'onChange' + | 'onFocus' + | 'onBlur' + | 'value' + | 'isDisabled' + | 'isRequired' + | 'prefix' + | 'suffix' + | 'maxCharacters' + | 'autoFocus' + | 'keyboardReturnKeyType' + | 'autoCompleteSuggestionType' + | 'onSubmit' + | 'autoCapitalize' + | 'testID' + | 'onClick' + | 'leadingIcon' + | 'trailingButton' + | 'errorText' + | 'successText' +> & { + accessibilityLabel: NonNullable; +}; + +type TableFooterProps = { + /** + * The children of TableFooter should be TableFooterRow + * @example + * + * + * Footer Cell 1 + * + * + **/ + children: React.ReactNode; +}; + +type TableFooterRowProps = { + /** + * The children of TableFooterRow should be TableFooterCell + * @example + * + * + * Footer Cell 1 + * + * + **/ + children: React.ReactNode; +}; + +type TableFooterCellProps = { + /** + * The children of TableHeaderCell can be a string or a ReactNode. + **/ + children: string | React.ReactNode; +}; + +type TablePaginationCommonProps = { + /** + * The default page size. + * Page size controls how rows are shown per page. + * @default 10 + **/ + defaultPageSize?: 10 | 25 | 50; + /** + * The current page. Passing this prop will make the component controlled and will not update the page on its own. + **/ + currentPage?: number; + + /** + * Callback function that is called when the page size is changed + */ + onPageSizeChange?: ({ pageSize }: { pageSize: number }) => void; + /** + * Whether to show the page size picker. It will be always be hidden on mobile. + * Page size picker controls how rows are shown per page. + * @default true + */ + showPageSizePicker?: boolean; + /** + * Whether to show the page number selector. It will be always be hidden on mobile. + * Page number selectors is a group of buttons that allows the user to jump to a specific page. + * @default false + */ + showPageNumberSelector?: boolean; + /** + * Content of the label to be shown in the pagination component + * @default `Showing 1 to ${totalItems} Items` + */ + label?: string; + /** + * Whether to show the label. It will be always be hidden on mobile. + * @default false + */ + showLabel?: boolean; +}; + +type TablePaginationType = 'client' | 'server'; + +type TablePaginationServerProps = TablePaginationCommonProps & { + /** + * Whether the pagination is happening on client or server. + * If the pagination is happening on `client`, the Table component will **divide the data into pages** and show the pages based on the page size. + * If the pagination is happening on `server`, the Table component will **not divide the data into pages and will show all the data**. You will have to fetch data for each page as the page changes and pass it to the Table component. + * When paginationType is `server`, the `onPageChange` & `totalItemCount` props are required. + * @default 'client' + * */ + paginationType?: Extract; + /** + * The total number of possible items in the table. This is used to calculate the total number of pages when pagination is happening on server and not all the data is fetched at once. + */ + totalItemCount: number; + /** + * Callback function that is called when the page is changed + */ + onPageChange: ({ page }: { page: number }) => void; +}; + +type TablePaginationClientProps = TablePaginationCommonProps & { + /** + * Whether the pagination is happening on client or server. + * If the pagination is happening on `client`, the Table component will **divide the data into pages** and show the pages based on the page size. + * If the pagination is happening on `server`, the Table component will **not divide the data into pages and will show all the data**. You will have to fetch data for each page as the page changes and pass it to the Table component. + * When paginationType is `server`, the `onPageChange` & `totalItemCount` props are required. + * @default 'client' + * */ + paginationType?: Extract; + /** + * The total number of possible items in the table. This is used to calculate the total number of pages when pagination is happening on server and not all the data is fetched at once. + */ + totalItemCount?: number; + /** + * Callback function that is called when the page is changed + */ + onPageChange?: ({ page }: { page: number }) => void; +}; + +type TablePaginationProps = TablePaginationCommonProps & + (TablePaginationServerProps | TablePaginationClientProps); + +type TableToolbarProps = { + /** + * The children of TableToolbar should be TableToolbarActions + */ + children?: React.ReactNode; + /** + * The title of the TableToolbar. If not provided, it will show the default title. + * @default `Showing 1 to ${totalItems} Items` + */ + title?: string; + /** + * The title to show when items are selected. If not provided, it will show the default title. + * @default `${selectedRows.length} 'Items'} Selected` + */ + selectedTitle?: string; +}; + +type TableToolbarActionsProps = { + children?: React.ReactNode; +} & StyledPropsBlade; +``` + +## Example + +```jsx +import { + Table, + TableEditableCell, + TableHeader, + TableHeaderRow, + TableHeaderCell, + TableBody, + TableRow, + TableCell, + TableToolbar, + TableToolbarActions, + TableFooter, + TableFooterRow, + TableFooterCell, + TablePagination, +} from '@razorpay/blade/components'; + +const nodes: Item[] = [ + ...Array.from({ length: 100 }, (_, i) => ({ + id: (i + 1).toString(), + paymentId: `rzp${Math.floor(Math.random() * 1000000)}`, + amount: Number((Math.random() * 10000).toFixed(2)), + status: ['Completed', 'Pending', 'Failed'][Math.floor(Math.random() * 3)], + date: new Date(2021, Math.floor(Math.random() * 12), Math.floor(Math.random() * 28) + 1), + type: ['Payout', 'Refund'][Math.floor(Math.random() * 2)], + method: ['Bank Transfer', 'Credit Card', 'PayPal'][Math.floor(Math.random() * 3)], + bank: ['HDFC', 'ICICI', 'SBI'][Math.floor(Math.random() * 3)], + account: Math.floor(Math.random() * 1000000000).toString(), + name: [ + 'John Doe', + 'Jane Doe', + 'Bob Smith', + 'Alice Smith', + 'John Smith', + 'Jane Smith', + 'Bob Doe', + 'Alice Doe', + ][Math.floor(Math.random() * 8)], + })), +]; + +type Item = { + id: string, + paymentId: string, + amount: number, + status: string, + date: Date, + type: string, + method: string, + bank: string, + account: string, + name: string, +}; +const data: TableData = { + nodes, +}; + +const TableComponent: StoryFn = ({ ...args }) => { + return ( + + + + + + + + } + sortFunctions={{ + ID: (array) => array.sort((a, b) => Number(a.id) - Number(b.id)), + AMOUNT: (array) => array.sort((a, b) => a.amount - b.amount), + PAYMENT_ID: (array) => array.sort((a, b) => a.paymentId.localeCompare(b.paymentId)), + DATE: (array) => array.sort((a, b) => a.date.getTime() - b.date.getTime()), + STATUS: (array) => array.sort((a, b) => a.status.localeCompare(b.status)), + }} + pagination={ + + } + > + {/* tableData variables has things that you passed from data.nodes in Table component */} + {(tableData) => ( + <> + {/* Add when you need header */} + + + ID + Amount + Account + Date + Method + Status + + + + {tableData.map((tableItem, index) => ( + + + {tableItem.paymentId} + + + {tableItem.account} + + {tableItem.date?.toLocaleDateString('en-IN', { + year: 'numeric', + month: '2-digit', + day: '2-digit', + })} + + {tableItem.method} + + + {tableItem.status} + + + + ))} + + {/* Add when you need footer */} + + + Total + - + - + - + - + {args.selectionType === 'multiple' ? - : null} + + + + + + + )} +
+
+ ); +}; +``` diff --git a/packages/blade/codemods/aicodemod/knowledge/presets/dashboard/table-pattern-1.md b/packages/blade/codemods/aicodemod/knowledge/presets/dashboard/table-pattern-1.md new file mode 100644 index 00000000000..0c696bc9d04 --- /dev/null +++ b/packages/blade/codemods/aicodemod/knowledge/presets/dashboard/table-pattern-1.md @@ -0,0 +1,319 @@ +### 2. Custom Component Definitions + +#### EntityItemRow Component + +```jsx +import { Component } from 'react'; +import { connect } from 'react-redux'; + +class EntityItemRow extends Component { + render() { + const { + id, + luminateRowId, + activeEntityId, + activeSecEntityId, + rowClasses = '', + onRowClick, + item, + isDisabled, + } = this.props; + const receiverType = item?.receiver_type || ''; + const sourceChannel = item?.source_channel || ''; + return ( + { + onRowClick?.({ + id, + rowData: { receiverType, sourceChannel }, + }); + }} + className={`${luminateRowId === id ? 'luminate' : ''}${ + activeEntityId === id || activeSecEntityId === id ? ' active' : '' + }${rowClasses ?? ''}${isDisabled?.(item) ? ' disabled' : ''}`} + data-testid={`entity-item-row-${id}`} + > + {this.props.children} + + ); + } +} + +const mapStateToProps = (state) => { + return state.app; +}; + +export default connect(mapStateToProps, null)(EntityItemRow); +``` + +#### TableBody Component + +```jsx +import React from 'react'; +import TableLoader from 'common/ui/TableLoader'; +import EmptyTableRow from 'common/ui/EmptyTableRow'; + +export default (props) => { + let tableRowComponent; + const { + isLoading, + emptyTableRow, + emptyTableMsg, + colSpan, + rows, + children, + SpinnerComponent, + } = props; + + if (isLoading) { + tableRowComponent = SpinnerComponent || ; + } else if (!rows.length) { + tableRowComponent = emptyTableRow || ( + + ); + } + + return ( + + {tableRowComponent + ? typeof tableRowComponent === 'function' + ? tableRowComponent(colSpan) + : tableRowComponent + : children} + + ); +}; +``` + +#### ShowWhen Component + +```jsx +export const ShowWhen = (props) => { + const i18 = useI18Service(); + // creating an abstraction of just consuming splitz experiment, rest service should not be accessed via RouteGuard + const { abExperiments } = useSplitzService(); + + const { loader, children, session, ...rest } = props; + + const showWhenUtilResult = validateUtil( + { + options: rest, + session, + }, + { + i18, + splitz: { abExperiments }, + }, + ); + + if (showWhenUtilResult === TAGS_API_NOT_RESOLVED_YET) { + return loader || ; + } else if (showWhenUtilResult) { + return children; + } + return null; +}; +``` + +### 3. Migration Example + +#### Original Custom Implimentation Code + +```jsx +import Text from '@razorpay/blade-old/src/atoms/Text'; +import View from '@razorpay/blade-old/src/atoms/View'; +import Flex from '@razorpay/blade-old/src/atoms/Flex'; +import Icon from '@razorpay/blade-old/src/atoms/Icon'; + +import TableBody from 'common/ui/TableBody'; +import MobileListView from 'common/ui/MobileListView'; +import { amount, createdAt } from 'common/ui/item/pair'; + +import EntityItemRow from 'merchant/containers/EntityItemRow'; +import { isMobileDevice } from 'merchant/components/Home/data'; +import { + customer, + invoiceId, + invoiveStatus, + paymentLink, + paymentLinkId, + receiptNumber, + referenceId, +} from 'merchant/views/Invoices/Invoices/item'; +import { shareURL } from 'merchant/views/Invoices/Invoices/helpers'; + +const PaymentLinkMobileTableListView = (items) => { + const { item, onShareLinkSuccess = () => {} } = items; + + return ( + + + {paymentLinkId.value(item)} + + {item?.customer_details && customer.value(item)} + + {item?.short_url && ( + { + onShareLinkSuccess(); + shareURL(item.short_url, item?.id); + }} + > + + +
+ +
+ Share payment link +
+
+
+ )} + + + {amount.value(item)} + {invoiveStatus.value(item)} +
+ ); +}; + +const InvoiceListItem = (props) => { + const { invoice, columns } = props; + + return ( + + {columns.map(({ title, value }) => ( + {value(invoice)} + ))} + + ); +}; + +export default (props) => { + const { + type, + invoices, + isLoading, + onCopy = () => {}, + EmptyList, + isPaymentlinksV2Enabled, + } = props; + + const isPaymentLinksType = type === 'link'; + const label = isPaymentLinksType ? paymentLinkId : invoiceId; + const listStyle = isPaymentLinksType ? 'Payment-link-list' : 'Invoice-list'; + const receipt = isPaymentlinksV2Enabled ? referenceId : receiptNumber; + + const columns = [label, createdAt, amount, receipt, customer, paymentLink(onCopy), invoiveStatus]; + + return isMobileDevice() && isPaymentLinksType ? ( + + ) : ( +
+ + + + {columns.map(({ title }) => ( + + ))} + + + + {invoices.map((invoice) => ( + + ))} + +
{title}
+
+ ); +}; +``` + +#### Expected Code after Migration + +```jsx +import { + Table, + TableHeader, + TableHeaderRow, + TableHeaderCell, + TableBody, + TableRow, + TableCell, +} from '@razorpay/blade/components'; + +import { amount, createdAt } from 'common/ui/item/pair'; + +import { + customer, + invoiceId, + invoiveStatus, + paymentLink, + paymentLinkId, + receiptNumber, + referenceId, +} from 'merchant/views/Invoices/Invoices/item'; +import { shareURL } from 'merchant/views/Invoices/Invoices/helpers'; + +const InvoiceListItem = (props) => { + const { invoice, columns } = props; + + return ( + + {columns.map(({ title, value }) => ( + {value(invoice)} + ))} + + ); +}; + +export default (props) => { + const { + type, + invoices, + isLoading, + onCopy = () => {}, + EmptyList, + isPaymentlinksV2Enabled, + } = props; + + const isPaymentLinksType = type === 'link'; + const label = isPaymentLinksType ? paymentLinkId : invoiceId; + const receipt = isPaymentlinksV2Enabled ? referenceId : receiptNumber; + + const columns = [label, createdAt, amount, receipt, customer, paymentLink(onCopy), invoiveStatus]; + + return ( + + {(tableData) => ( + <> + + + {columns.map(({ title }) => ( + {title} + ))} + + + + {tableData.length <= 0 ? ( + + ) : ( + tableData.map((invoice) => ( + + )) + )} + + + )} +
+ ); +}; +``` diff --git a/packages/blade/package.json b/packages/blade/package.json index 60f770ce837..1a8cb1b06c5 100644 --- a/packages/blade/package.json +++ b/packages/blade/package.json @@ -7,7 +7,8 @@ "node": ">=18.12.1" }, "bin": { - "migrate-typography": "./codemods/migrate-typography/transformers/migrate-typography.ts" + "migrate-typography": "./codemods/migrate-typography/transformers/migrate-typography.ts", + "aicodemod": "./codemods/aicodemod/bin.mjs" }, "repository": { "type": "git", @@ -235,6 +236,7 @@ "dedent": "0.7.0", "eslint-plugin-mdx": "1.16.0", "execa": "5.0.0", + "fastify": "4.28.1", "figures": "3.2.0", "flat": "5.0.2", "globby": "14.0.1", diff --git a/yarn.lock b/yarn.lock index 89e65e6d1f0..8139ef058fe 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2476,6 +2476,34 @@ resolved "https://registry.yarnpkg.com/@fal-works/esbuild-plugin-global-externals/-/esbuild-plugin-global-externals-2.1.2.tgz#c05ed35ad82df8e6ac616c68b92c2282bd083ba4" integrity sha512-cEee/Z+I12mZcFJshKcCqC8tuX5hG3s+d+9nZ3LabqKF1vKdF41B92pJVCBggjAGORAeOzyyDDKrZwIkLffeOQ== +"@fastify/ajv-compiler@^3.5.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@fastify/ajv-compiler/-/ajv-compiler-3.6.0.tgz#907497a0e62a42b106ce16e279cf5788848e8e79" + integrity sha512-LwdXQJjmMD+GwLOkP7TVC68qa+pSSogeWWmznRJ/coyTcfe9qA05AHFSe1eZFwK6q+xVRpChnvFUkf1iYaSZsQ== + dependencies: + ajv "^8.11.0" + ajv-formats "^2.1.1" + fast-uri "^2.0.0" + +"@fastify/error@^3.3.0", "@fastify/error@^3.4.0": + version "3.4.1" + resolved "https://registry.yarnpkg.com/@fastify/error/-/error-3.4.1.tgz#b14bb4cac3dd4ec614becbc643d1511331a6425c" + integrity sha512-wWSvph+29GR783IhmvdwWnN4bUxTD01Vm5Xad4i7i1VuAOItLvbPAb69sb0IQ2N57yprvhNIwAP5B6xfKTmjmQ== + +"@fastify/fast-json-stringify-compiler@^4.3.0": + version "4.3.0" + resolved "https://registry.yarnpkg.com/@fastify/fast-json-stringify-compiler/-/fast-json-stringify-compiler-4.3.0.tgz#5df89fa4d1592cbb8780f78998355feb471646d5" + integrity sha512-aZAXGYo6m22Fk1zZzEUKBvut/CIIQe/BapEORnxiD5Qr0kPHqqI69NtEMCme74h+at72sPhbkb4ZrLd1W3KRLA== + dependencies: + fast-json-stringify "^5.7.0" + +"@fastify/merge-json-schemas@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@fastify/merge-json-schemas/-/merge-json-schemas-0.1.1.tgz#3551857b8a17a24e8c799e9f51795edb07baa0bc" + integrity sha512-fERDVz7topgNjtXsJTTW1JKLy0rhuLRcquYqNR9rF7OcVpCa2OVW49ZPDIhaRRCaUuvVxI+N416xUoF76HNSXA== + dependencies: + fast-deep-equal "^3.1.3" + "@floating-ui/core@^1.0.0", "@floating-ui/core@^1.2.6": version "1.6.0" resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.6.0.tgz#fa41b87812a16bf123122bf945946bae3fdf7fc1" @@ -8432,6 +8460,11 @@ absolute-path@^0.0.0: resolved "https://registry.yarnpkg.com/absolute-path/-/absolute-path-0.0.0.tgz#a78762fbdadfb5297be99b15d35a785b2f095bf7" integrity sha512-HQiug4c+/s3WOvEnDRxXVmNtSG5s2gJM9r19BTcqjp7BWcE48PB+Y2G6jE65kqI0LpsQeMZygt/b60Gi4KxGyA== +abstract-logging@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/abstract-logging/-/abstract-logging-2.0.1.tgz#6b0c371df212db7129b57d2e7fcf282b8bf1c839" + integrity sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA== + accepts@^1.3.7, accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7, accepts@~1.3.8: version "1.3.8" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" @@ -8579,6 +8612,13 @@ ajv-formats@^2.1.1: dependencies: ajv "^8.0.0" +ajv-formats@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-3.0.1.tgz#3d5dc762bca17679c3c2ea7e90ad6b7532309578" + integrity sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ== + dependencies: + ajv "^8.0.0" + ajv-keywords@^3.1.0, ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: version "3.5.2" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" @@ -8611,6 +8651,16 @@ ajv@^8.0.0, ajv@^8.0.1, ajv@^8.6.0, ajv@^8.9.0: require-from-string "^2.0.2" uri-js "^4.2.2" +ajv@^8.10.0, ajv@^8.11.0: + version "8.17.1" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.17.1.tgz#37d9a5c776af6bc92d7f4f9510eba4c0a60d11a6" + integrity sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g== + dependencies: + fast-deep-equal "^3.1.3" + fast-uri "^3.0.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + anser@^1.4.9: version "1.4.10" resolved "https://registry.yarnpkg.com/anser/-/anser-1.4.10.tgz#befa3eddf282684bd03b63dcda3927aef8c2e35b" @@ -9171,6 +9221,11 @@ atob@^2.1.2: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== +atomic-sleep@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b" + integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ== + autoprefixer@^10.4.13: version "10.4.19" resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.19.tgz#ad25a856e82ee9d7898c59583c1afeb3fa65f89f" @@ -9203,6 +9258,14 @@ available-typed-arrays@^1.0.7: dependencies: possible-typed-array-names "^1.0.0" +avvio@^8.3.0: + version "8.3.2" + resolved "https://registry.yarnpkg.com/avvio/-/avvio-8.3.2.tgz#cb5844a612e8421d1f3aef8895ef7fa12f73563f" + integrity sha512-st8e519GWHa/azv8S87mcJvZs4WsgTBjOw/Ih1CP6u+8SZvcOeAYNG6JbsIrAUUJJ7JfmrnOkR8ipDS+u9SIRQ== + dependencies: + "@fastify/error" "^3.3.0" + fastq "^1.17.1" + aws-sign2@~0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" @@ -11149,7 +11212,7 @@ cookie-signature@1.0.6: resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== -cookie@0.6.0: +cookie@0.6.0, cookie@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051" integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw== @@ -13625,7 +13688,7 @@ eventemitter3@^4.0.0, eventemitter3@^4.0.4: resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== -events@^3.0.0, events@^3.2.0: +events@^3.0.0, events@^3.2.0, events@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== @@ -13909,6 +13972,16 @@ extsprintf@^1.2.0: resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== +fast-content-type-parse@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fast-content-type-parse/-/fast-content-type-parse-1.1.0.tgz#4087162bf5af3294d4726ff29b334f72e3a1092c" + integrity sha512-fBHHqSTFLVnR61C+gltJuE5GkVQMV0S2nqUO8TJ+5Z3qAKG8vAx4FKai1s5jq/inV1+sREynIWSuQ6HgoSXpDQ== + +fast-decode-uri-component@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz#46f8b6c22b30ff7a81357d4f59abfae938202543" + integrity sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg== + fast-deep-equal@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" @@ -13962,11 +14035,46 @@ fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-sta resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== +fast-json-stringify@^5.7.0, fast-json-stringify@^5.8.0: + version "5.16.1" + resolved "https://registry.yarnpkg.com/fast-json-stringify/-/fast-json-stringify-5.16.1.tgz#a6d0c575231a3a08c376a00171d757372f2ca46e" + integrity sha512-KAdnLvy1yu/XrRtP+LJnxbBGrhN+xXu+gt3EUvZhYGKCr3lFHq/7UFJHHFgmJKoqlh6B40bZLEv7w46B0mqn1g== + dependencies: + "@fastify/merge-json-schemas" "^0.1.0" + ajv "^8.10.0" + ajv-formats "^3.0.1" + fast-deep-equal "^3.1.3" + fast-uri "^2.1.0" + json-schema-ref-resolver "^1.0.1" + rfdc "^1.2.0" + fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== +fast-querystring@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/fast-querystring/-/fast-querystring-1.1.2.tgz#a6d24937b4fc6f791b4ee31dcb6f53aeafb89f53" + integrity sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg== + dependencies: + fast-decode-uri-component "^1.0.1" + +fast-redact@^3.1.1: + version "3.5.0" + resolved "https://registry.yarnpkg.com/fast-redact/-/fast-redact-3.5.0.tgz#e9ea02f7e57d0cd8438180083e93077e496285e4" + integrity sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A== + +fast-uri@^2.0.0, fast-uri@^2.1.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-2.4.0.tgz#67eae6fbbe9f25339d5d3f4c4234787b65d7d55e" + integrity sha512-ypuAmmMKInk5q7XcepxlnUWDLWv4GFtaJqAzWKqn62IpQ3pejtr5dTVbt3vwqVaMKmkNR55sTT+CqUKIaT21BA== + +fast-uri@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.0.1.tgz#cddd2eecfc83a71c1be2cc2ef2061331be8a7134" + integrity sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw== + fast-xml-parser@^4.0.12: version "4.3.6" resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.3.6.tgz#190f9d99097f0c8f2d3a0e681a10404afca052ff" @@ -13979,7 +14087,29 @@ fastest-levenshtein@^1.0.12: resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5" integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg== -fastq@^1.6.0: +fastify@4.28.1: + version "4.28.1" + resolved "https://registry.yarnpkg.com/fastify/-/fastify-4.28.1.tgz#39626dedf445d702ef03818da33064440b469cd1" + integrity sha512-kFWUtpNr4i7t5vY2EJPCN2KgMVpuqfU4NjnJNCgiNB900oiDeYqaNDRcAfeBbOF5hGixixxcKnOU4KN9z6QncQ== + dependencies: + "@fastify/ajv-compiler" "^3.5.0" + "@fastify/error" "^3.4.0" + "@fastify/fast-json-stringify-compiler" "^4.3.0" + abstract-logging "^2.0.1" + avvio "^8.3.0" + fast-content-type-parse "^1.1.0" + fast-json-stringify "^5.8.0" + find-my-way "^8.0.0" + light-my-request "^5.11.0" + pino "^9.0.0" + process-warning "^3.0.0" + proxy-addr "^2.0.7" + rfdc "^1.3.0" + secure-json-parse "^2.7.0" + semver "^7.5.4" + toad-cache "^3.3.0" + +fastq@^1.17.1, fastq@^1.6.0: version "1.17.1" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47" integrity sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w== @@ -14174,6 +14304,15 @@ find-file-up@^0.1.2: fs-exists-sync "^0.1.0" resolve-dir "^0.1.0" +find-my-way@^8.0.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/find-my-way/-/find-my-way-8.2.0.tgz#ef1b83d008114a300118c9c707d8dc65947d9960" + integrity sha512-HdWXgFYc6b1BJcOBDBwjqWuHJj1WYiqrxSh25qtU4DabpMFdj/gSunNBQb83t+8Zt67D7CXEzJWTkxaShMTMOA== + dependencies: + fast-deep-equal "^3.1.3" + fast-querystring "^1.0.0" + safe-regex2 "^3.1.0" + find-pkg@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/find-pkg/-/find-pkg-0.1.2.tgz#1bdc22c06e36365532e2a248046854b9788da557" @@ -18212,6 +18351,13 @@ json-parse-even-better-errors@^3.0.0: resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.1.tgz#02bb29fb5da90b5444581749c22cedd3597c6cb0" integrity sha512-aatBvbL26wVUCLmbWdCpeu9iF5wOyWpagiKkInA+kfws3sWdBrTnsvN2CKcyCYyUrc7rebNBlK6+kteg7ksecg== +json-schema-ref-resolver@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-schema-ref-resolver/-/json-schema-ref-resolver-1.0.1.tgz#6586f483b76254784fc1d2120f717bdc9f0a99bf" + integrity sha512-EJAj1pgHc1hxF6vo2Z3s69fMjO1INq6eGHXZ8Z6wCQeldCuwxGK9Sxf4/cScGn3FZubCVUehfWtcDM/PLteCQw== + dependencies: + fast-deep-equal "^3.1.3" + json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" @@ -18544,6 +18690,15 @@ liftoff@^4.0.0: rechoir "^0.8.0" resolve "^1.20.0" +light-my-request@^5.11.0: + version "5.13.0" + resolved "https://registry.yarnpkg.com/light-my-request/-/light-my-request-5.13.0.tgz#b29905e55e8605b77fee2a946e17b219bca35113" + integrity sha512-9IjUN9ZyCS9pTG+KqTDEQo68Sui2lHsYBrfMyVUTTZ3XhH8PMZq7xO94Kr+eP9dhi/kcKsx4N41p2IXEBil1pQ== + dependencies: + cookie "^0.6.0" + process-warning "^3.0.0" + set-cookie-parser "^2.4.1" + lilconfig@^2.0.3, lilconfig@^2.0.6, lilconfig@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" @@ -21379,6 +21534,11 @@ ohash@^1.1.3: resolved "https://registry.yarnpkg.com/ohash/-/ohash-1.1.3.tgz#f12c3c50bfe7271ce3fd1097d42568122ccdcf07" integrity sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw== +on-exit-leak-free@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz#fed195c9ebddb7d9e4c3842f93f281ac8dadd3b8" + integrity sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA== + on-finished@2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" @@ -22172,6 +22332,36 @@ pinkie@^2.0.0: resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg== +pino-abstract-transport@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pino-abstract-transport/-/pino-abstract-transport-1.2.0.tgz#97f9f2631931e242da531b5c66d3079c12c9d1b5" + integrity sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q== + dependencies: + readable-stream "^4.0.0" + split2 "^4.0.0" + +pino-std-serializers@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/pino-std-serializers/-/pino-std-serializers-7.0.0.tgz#7c625038b13718dbbd84ab446bd673dc52259e3b" + integrity sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA== + +pino@^9.0.0: + version "9.3.2" + resolved "https://registry.yarnpkg.com/pino/-/pino-9.3.2.tgz#a530d6d28f1d954b6f54416a218cbb616f52f901" + integrity sha512-WtARBjgZ7LNEkrGWxMBN/jvlFiE17LTbBoH0konmBU684Kd0uIiDwBXlcTCW7iJnA6HfIKwUssS/2AC6cDEanw== + dependencies: + atomic-sleep "^1.0.0" + fast-redact "^3.1.1" + on-exit-leak-free "^2.1.0" + pino-abstract-transport "^1.2.0" + pino-std-serializers "^7.0.0" + process-warning "^4.0.0" + quick-format-unescaped "^4.0.3" + real-require "^0.2.0" + safe-stable-stringify "^2.3.1" + sonic-boom "^4.0.1" + thread-stream "^3.0.0" + pinpoint@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/pinpoint/-/pinpoint-1.1.0.tgz#0cf7757a6977f1bf7f6a32207b709e377388e874" @@ -23123,6 +23313,16 @@ process-on-spawn@^1.0.0: dependencies: fromentries "^1.2.0" +process-warning@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/process-warning/-/process-warning-3.0.0.tgz#96e5b88884187a1dce6f5c3166d611132058710b" + integrity sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ== + +process-warning@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/process-warning/-/process-warning-4.0.0.tgz#581e3a7a1fb456c5f4fd239f76bce75897682d5a" + integrity sha512-/MyYDxttz7DfGMMHiysAsFE4qF+pQYAA8ziO/3NcRVrQ5fSk+Mns4QZA/oRPFzvcqNoVJXQNWNAsdwBXLUkQKw== + process@^0.11.10: version "0.11.10" resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" @@ -23222,7 +23422,7 @@ protocols@^2.0.1: resolved "https://registry.yarnpkg.com/protocols/-/protocols-2.0.1.tgz#8f155da3fc0f32644e83c5782c8e8212ccf70a86" integrity sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q== -proxy-addr@~2.0.7: +proxy-addr@^2.0.7, proxy-addr@~2.0.7: version "2.0.7" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== @@ -23402,6 +23602,11 @@ queue@6.0.2: dependencies: inherits "~2.0.3" +quick-format-unescaped@^4.0.3: + version "4.0.4" + resolved "https://registry.yarnpkg.com/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz#93ef6dd8d3453cbc7970dd614fad4c5954d6b5a7" + integrity sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg== + quick-lru@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f" @@ -24151,6 +24356,17 @@ readable-stream@3, readable-stream@^3.0.0, readable-stream@^3.0.2, readable-stre string_decoder "^1.1.1" util-deprecate "^1.0.1" +readable-stream@^4.0.0: + version "4.5.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-4.5.2.tgz#9e7fc4c45099baeed934bff6eb97ba6cf2729e09" + integrity sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g== + dependencies: + abort-controller "^3.0.0" + buffer "^6.0.3" + events "^3.3.0" + process "^0.11.10" + string_decoder "^1.3.0" + readable-stream@~1.0.31: version "1.0.34" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" @@ -24197,6 +24413,11 @@ readline@^1.3.0: resolved "https://registry.yarnpkg.com/readline/-/readline-1.3.0.tgz#c580d77ef2cfc8752b132498060dc9793a7ac01c" integrity sha512-k2d6ACCkiNYz222Fs/iNze30rRJ1iIicW7JuX/7/cozvih6YCkFZH+J6mAFDVgv0dRBaAyr4jDqC95R2y4IADg== +real-require@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/real-require/-/real-require-0.2.0.tgz#209632dea1810be2ae063a6ac084fee7e33fba78" + integrity sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg== + recast@^0.20.3, recast@^0.20.4: version "0.20.5" resolved "https://registry.yarnpkg.com/recast/-/recast-0.20.5.tgz#8e2c6c96827a1b339c634dd232957d230553ceae" @@ -24733,6 +24954,11 @@ ret@~0.1.10: resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== +ret@~0.4.0: + version "0.4.3" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.4.3.tgz#5243fa30e704a2e78a9b9b1e86079e15891aa85c" + integrity sha512-0f4Memo5QP7WQyUEAYUO3esD/XjOc3Zjjg5CPsAq1p8sIu0XPeMbHJemKA0BO7tV0X7+A0FoEpbmHXWxPyD3wQ== + retry@0.12.0, retry@^0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" @@ -24748,6 +24974,11 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== +rfdc@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.4.1.tgz#778f76c4fb731d93414e8f925fbecf64cce7f6ca" + integrity sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA== + rfdc@^1.3.0: version "1.3.1" resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.1.tgz#2b6d4df52dffe8bb346992a10ea9451f24373a8f" @@ -24909,6 +25140,13 @@ safe-regex-test@^1.0.3: es-errors "^1.3.0" is-regex "^1.1.4" +safe-regex2@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/safe-regex2/-/safe-regex2-3.1.0.tgz#fd7ec23908e2c730e1ce7359a5b72883a87d2763" + integrity sha512-RAAZAGbap2kBfbVhvmnTFv73NWLMvDGOITFYTZBAaY8eR+Ir4ef7Up/e7amo+y1+AH+3PtLkrt9mvcTsG9LXug== + dependencies: + ret "~0.4.0" + safe-regex@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" @@ -24916,6 +25154,11 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" +safe-stable-stringify@^2.3.1: + version "2.4.3" + resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz#138c84b6f6edb3db5f8ef3ef7115b8f55ccbf886" + integrity sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g== + "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" @@ -25033,6 +25276,11 @@ secure-compare@3.0.1: resolved "https://registry.yarnpkg.com/secure-compare/-/secure-compare-3.0.1.tgz#f1a0329b308b221fae37b9974f3d578d0ca999e3" integrity sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw== +secure-json-parse@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/secure-json-parse/-/secure-json-parse-2.7.0.tgz#5a5f9cd6ae47df23dba3151edd06855d47e09862" + integrity sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw== + select-hose@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" @@ -25178,6 +25426,11 @@ set-blocking@^2.0.0, set-blocking@~2.0.0: resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== +set-cookie-parser@^2.4.1: + version "2.6.0" + resolved "https://registry.yarnpkg.com/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz#131921e50f62ff1a66a461d7d62d7b21d5d15a51" + integrity sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ== + set-function-length@^1.2.1: version "1.2.2" resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" @@ -25483,6 +25736,13 @@ socks@^2.3.3, socks@^2.6.2: ip-address "^9.0.5" smart-buffer "^4.2.0" +sonic-boom@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-4.0.1.tgz#515b7cef2c9290cb362c4536388ddeece07aed30" + integrity sha512-hTSD/6JMLyT4r9zeof6UtuBDpjJ9sO08/nmS5djaA9eozT9oOlNdpXSnzcgj4FTqpk3nkLrs61l4gip9r1HCrQ== + dependencies: + atomic-sleep "^1.0.0" + sort-keys@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" @@ -25691,6 +25951,11 @@ split2@^3.0.0: dependencies: readable-stream "^3.0.0" +split2@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4" + integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg== + split@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" @@ -25987,7 +26252,7 @@ string.prototype.trimstart@^1.0.8: define-properties "^1.2.1" es-object-atoms "^1.0.0" -string_decoder@^1.0.0, string_decoder@^1.1.1: +string_decoder@^1.0.0, string_decoder@^1.1.1, string_decoder@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== @@ -26746,6 +27011,13 @@ thenify-all@^1.0.0: dependencies: any-promise "^1.0.0" +thread-stream@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/thread-stream/-/thread-stream-3.1.0.tgz#4b2ef252a7c215064507d4ef70c05a5e2d34c4f1" + integrity sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A== + dependencies: + real-require "^0.2.0" + throat@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b" @@ -26872,6 +27144,11 @@ to-vfile@^7.0.0: is-buffer "^2.0.0" vfile "^5.1.0" +toad-cache@^3.3.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/toad-cache/-/toad-cache-3.7.0.tgz#b9b63304ea7c45ec34d91f1d2fa513517025c441" + integrity sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw== + tocbot@^4.20.1: version "4.25.0" resolved "https://registry.yarnpkg.com/tocbot/-/tocbot-4.25.0.tgz#bc38aea5ec8f076779bb39636f431b044129a237"