From 54ba314badbb2ec146986813eb764522a1e9776b Mon Sep 17 00:00:00 2001 From: peopleinfo <49970466+peopleinfo@users.noreply.github.com> Date: Fri, 7 Nov 2025 09:27:13 +0700 Subject: [PATCH 1/9] up --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5acf514..d4724a3 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "engines": { "node": ">=20.11.0" }, - "packageManager": "pnpm@10.14.0", + "packageManager": "pnpm@10.20.0+sha512.cf9998222162dd85864d0a8102e7892e7ba4ceadebbf5a31f9c2fce48dfce317a9c53b9f6464d1ef9042cba2e02ae02a9f7c143a2b438cd93c91840f0192b9dd", "resolutions": { "lightningcss": "1.27.0" } From 42a10459d9234fe6e530f32998a4e0c68387107a Mon Sep 17 00:00:00 2001 From: peopleinfo <49970466+peopleinfo@users.noreply.github.com> Date: Fri, 7 Nov 2025 09:29:07 +0700 Subject: [PATCH 2/9] up turbo --- package.json | 4 ++-- pnpm-lock.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index d4724a3..5daa341 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "devDependencies": { "prettier": "^3.6.2", "prettier-plugin-tailwindcss": "^0.6.14", - "turbo": "^2.5.5", + "turbo": "^2.6.0", "typescript": "^5.8.3" }, "pnpm": { @@ -32,7 +32,7 @@ "engines": { "node": ">=20.11.0" }, - "packageManager": "pnpm@10.20.0+sha512.cf9998222162dd85864d0a8102e7892e7ba4ceadebbf5a31f9c2fce48dfce317a9c53b9f6464d1ef9042cba2e02ae02a9f7c143a2b438cd93c91840f0192b9dd", + "packageManager": "pnpm@10.20.0", "resolutions": { "lightningcss": "1.27.0" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d823188..75fdd69 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,7 +18,7 @@ importers: specifier: ^0.6.14 version: 0.6.14(prettier@3.6.2) turbo: - specifier: ^2.5.5 + specifier: ^2.6.0 version: 2.6.0 typescript: specifier: ^5.8.3 From e198750fdd291c2e86f5525ea108e52094338819 Mon Sep 17 00:00:00 2001 From: peopleinfo <49970466+peopleinfo@users.noreply.github.com> Date: Fri, 7 Nov 2025 10:04:52 +0700 Subject: [PATCH 3/9] rename lib --- .github/pull_request_template.md | 2 +- .vercel/project.json | 1 + apps/docs/components/blocks.tsx | 2 +- apps/docs/components/examples.tsx | 2 +- .../docs/blocks/example-block/example.mdx | 4 ++-- .../docs/components/example-component.mdx | 8 ++++---- apps/docs/content/docs/components/form.mdx | 10 +++++----- apps/docs/content/docs/usage.mdx | 18 +++++++++--------- apps/docs/lib/file-generator.ts | 4 ++-- apps/docs/next.config.mjs | 2 +- apps/docs/package.json | 2 +- apps/docs/public/r/example-block.json | 4 ++-- apps/docs/public/r/example-component.json | 2 +- apps/docs/public/r/form.json | 2 +- apps/docs/registry.json | 6 +++--- apps/docs/tsconfig.json | 4 ++-- apps/showcase/app/components/example-block.tsx | 2 +- .../app/components/example-component.tsx | 2 +- apps/showcase/app/components/form.tsx | 2 +- apps/showcase/package.json | 2 +- apps/showcase/public/r/example-block.json | 4 ++-- apps/showcase/public/r/example-component.json | 2 +- apps/showcase/public/r/form.json | 2 +- apps/showcase/registry.json | 6 +++--- apps/showcase/tsconfig.json | 4 ++-- package.json | 8 +++++++- .../components.json | 0 .../nativewind-env.d.ts | 0 .../{example-library => rnr-ui}/package.json | 2 +- .../reusables/components/ui/button.tsx | 0 .../reusables/components/ui/card.tsx | 0 .../reusables/components/ui/label.tsx | 0 .../reusables/components/ui/text.tsx | 0 .../reusables/global.css | 0 .../reusables/lib/theme.ts | 0 .../reusables/lib/utils.ts | 0 .../src/blocks/index.ts | 0 .../src/blocks/multiple-buttons.tsx | 2 +- .../src/components/ui/forms.tsx | 0 .../src/components/ui/red-button.tsx | 0 .../src/examples/form/form-basic.tsx | 2 +- .../src/examples/form/form-with-validation.tsx | 2 +- .../src/examples/form/index.ts | 0 .../src/examples/index.ts | 0 .../src/examples/red-button/index.ts | 0 .../examples/red-button/red-button-primary.tsx | 2 +- .../red-button/red-button-secondary.tsx | 2 +- .../tailwind.config.js | 0 .../{example-library => rnr-ui}/tsconfig.json | 2 +- pnpm-lock.yaml | 10 +++++----- 50 files changed, 69 insertions(+), 62 deletions(-) create mode 100644 .vercel/project.json rename packages/{example-library => rnr-ui}/components.json (100%) rename packages/{example-library => rnr-ui}/nativewind-env.d.ts (100%) rename packages/{example-library => rnr-ui}/package.json (96%) rename packages/{example-library => rnr-ui}/reusables/components/ui/button.tsx (100%) rename packages/{example-library => rnr-ui}/reusables/components/ui/card.tsx (100%) rename packages/{example-library => rnr-ui}/reusables/components/ui/label.tsx (100%) rename packages/{example-library => rnr-ui}/reusables/components/ui/text.tsx (100%) rename packages/{example-library => rnr-ui}/reusables/global.css (100%) rename packages/{example-library => rnr-ui}/reusables/lib/theme.ts (100%) rename packages/{example-library => rnr-ui}/reusables/lib/utils.ts (100%) rename packages/{example-library => rnr-ui}/src/blocks/index.ts (100%) rename packages/{example-library => rnr-ui}/src/blocks/multiple-buttons.tsx (94%) rename packages/{example-library => rnr-ui}/src/components/ui/forms.tsx (100%) rename packages/{example-library => rnr-ui}/src/components/ui/red-button.tsx (100%) rename packages/{example-library => rnr-ui}/src/examples/form/form-basic.tsx (96%) rename packages/{example-library => rnr-ui}/src/examples/form/form-with-validation.tsx (97%) rename packages/{example-library => rnr-ui}/src/examples/form/index.ts (100%) rename packages/{example-library => rnr-ui}/src/examples/index.ts (100%) rename packages/{example-library => rnr-ui}/src/examples/red-button/index.ts (100%) rename packages/{example-library => rnr-ui}/src/examples/red-button/red-button-primary.tsx (53%) rename packages/{example-library => rnr-ui}/src/examples/red-button/red-button-secondary.tsx (62%) rename packages/{example-library => rnr-ui}/tailwind.config.js (100%) rename packages/{example-library => rnr-ui}/tsconfig.json (87%) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 393d9c1..2999f05 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -20,7 +20,7 @@ Fixes issue # - [ ] apps/docs - [ ] apps/showcase -- [ ] packages/example-library +- [ ] packages/rnr-ui ### Screenshots: diff --git a/.vercel/project.json b/.vercel/project.json new file mode 100644 index 0000000..812014f --- /dev/null +++ b/.vercel/project.json @@ -0,0 +1 @@ +{"neverMindDeployCard":true} \ No newline at end of file diff --git a/apps/docs/components/blocks.tsx b/apps/docs/components/blocks.tsx index 957ded3..547c535 100644 --- a/apps/docs/components/blocks.tsx +++ b/apps/docs/components/blocks.tsx @@ -1,3 +1,3 @@ 'use client'; -export * from '@/example-library/blocks'; +export * from '@/rnr-ui/blocks'; diff --git a/apps/docs/components/examples.tsx b/apps/docs/components/examples.tsx index 9346288..8e7f795 100644 --- a/apps/docs/components/examples.tsx +++ b/apps/docs/components/examples.tsx @@ -1,4 +1,4 @@ 'use client'; -export * from '@/example-library/examples'; +export * from '@/rnr-ui/examples'; export * from './utils'; diff --git a/apps/docs/content/docs/blocks/example-block/example.mdx b/apps/docs/content/docs/blocks/example-block/example.mdx index fbcacf1..fed0405 100644 --- a/apps/docs/content/docs/blocks/example-block/example.mdx +++ b/apps/docs/content/docs/blocks/example-block/example.mdx @@ -50,7 +50,7 @@ import { MultipleButtons } from '@docs/components/blocks'; ```json doc-gen:file { - "file": "./node_modules/@rnr/example-library/reusables/components/ui/card.tsx", + "file": "./node_modules/@rnr/rnr-ui/reusables/components/ui/card.tsx", "codeblock": { "lang": "tsx", "meta": "title=\"@/components/ui/card.tsx\"" @@ -60,7 +60,7 @@ import { MultipleButtons } from '@docs/components/blocks'; ```json doc-gen:file { - "file": "./node_modules/@rnr/example-library/src/blocks/multiple-buttons.tsx", + "file": "./node_modules/@rnr/rnr-ui/src/blocks/multiple-buttons.tsx", "codeblock": { "lang": "tsx", "meta": "title=\"@/components/blocks/multiple-buttons.tsx\"" diff --git a/apps/docs/content/docs/components/example-component.mdx b/apps/docs/content/docs/components/example-component.mdx index 9c5cef5..b950ed1 100644 --- a/apps/docs/content/docs/components/example-component.mdx +++ b/apps/docs/content/docs/components/example-component.mdx @@ -27,7 +27,7 @@ import { RedButtonPreview, RedButtonSecondaryPreview } from '@docs/components/ex ```json doc-gen:file { - "file": "./node_modules/@rnr/example-library/src/examples/red-button/red-button-primary.tsx", + "file": "./node_modules/@rnr/rnr-ui/src/examples/red-button/red-button-primary.tsx", "codeblock": { "lang": "tsx" } @@ -61,7 +61,7 @@ import { RedButtonPreview, RedButtonSecondaryPreview } from '@docs/components/ex ```json doc-gen:file { - "file": "./node_modules/@rnr/example-library/reusables/components/ui/text.tsx", + "file": "./node_modules/@rnr/rnr-ui/reusables/components/ui/text.tsx", "codeblock": { "lang": "tsx", "meta": "title=\"@/components/ui/text.tsx\"" @@ -71,7 +71,7 @@ import { RedButtonPreview, RedButtonSecondaryPreview } from '@docs/components/ex ```json doc-gen:file { - "file": "./node_modules/@rnr/example-library/reusables/components/ui/button.tsx", + "file": "./node_modules/@rnr/rnr-ui/reusables/components/ui/button.tsx", "codeblock": { "lang": "tsx", "meta": "title=\"@/components/ui/button.tsx\"" @@ -81,7 +81,7 @@ import { RedButtonPreview, RedButtonSecondaryPreview } from '@docs/components/ex ```json doc-gen:file { - "file": "./node_modules/@rnr/example-library/src/components/ui/red-button.tsx", + "file": "./node_modules/@rnr/rnr-ui/src/components/ui/red-button.tsx", "codeblock": { "lang": "tsx", "meta": "title=\"@/components/ui/red-button.tsx\"" diff --git a/apps/docs/content/docs/components/form.mdx b/apps/docs/content/docs/components/form.mdx index a344728..6dfe3b5 100644 --- a/apps/docs/content/docs/components/form.mdx +++ b/apps/docs/content/docs/components/form.mdx @@ -27,7 +27,7 @@ import { FormBasicPreview, FormWithValidationPreview } from '@docs/components/ex ```json doc-gen:file { - "file": "./node_modules/@rnr/example-library/src/examples/form/form-basic.tsx", + "file": "./node_modules/@rnr/rnr-ui/src/examples/form/form-basic.tsx", "codeblock": { "lang": "tsx" } @@ -61,7 +61,7 @@ import { FormBasicPreview, FormWithValidationPreview } from '@docs/components/ex ```json doc-gen:file { - "file": "./node_modules/@rnr/example-library/reusables/components/ui/text.tsx", + "file": "./node_modules/@rnr/rnr-ui/reusables/components/ui/text.tsx", "codeblock": { "lang": "tsx", "meta": "title=\"@/components/ui/text.tsx\"" @@ -71,7 +71,7 @@ import { FormBasicPreview, FormWithValidationPreview } from '@docs/components/ex ```json doc-gen:file { - "file": "./node_modules/@rnr/example-library/reusables/components/ui/label.tsx", + "file": "./node_modules/@rnr/rnr-ui/reusables/components/ui/label.tsx", "codeblock": { "lang": "tsx", "meta": "title=\"@/components/ui/label.tsx\"" @@ -81,7 +81,7 @@ import { FormBasicPreview, FormWithValidationPreview } from '@docs/components/ex ```json doc-gen:file { - "file": "./node_modules/@rnr/example-library/src/components/ui/forms.tsx", + "file": "./node_modules/@rnr/rnr-ui/src/components/ui/forms.tsx", "codeblock": { "lang": "tsx", "meta": "title=\"@/components/ui/forms.tsx\"" @@ -133,7 +133,7 @@ const [form] = Form.useForm(); ```json doc-gen:file { - "file": "./node_modules/@rnr/example-library/src/examples/form/form-with-validation.tsx", + "file": "./node_modules/@rnr/rnr-ui/src/examples/form/form-with-validation.tsx", "codeblock": { "lang": "tsx" } diff --git a/apps/docs/content/docs/usage.mdx b/apps/docs/content/docs/usage.mdx index 4c034ba..e1f31f7 100644 --- a/apps/docs/content/docs/usage.mdx +++ b/apps/docs/content/docs/usage.mdx @@ -5,23 +5,23 @@ description: How to use the React Native Reusables Registry Template ## Using the template -- The example components are found in the `packages/example-library` folder. +- The example components are found in the `packages/rnr-ui` folder. - The template includes the necessary config to use [react-native-reusables](https://reactnativereusables.com) components as dependencies. - **Note:** The Reusables UI is installed in `packages/example-library/reusables`. + **Note:** The Reusables UI is installed in `packages/rnr-ui/reusables`. If you want to use more `react-native-reusables` components as dependencies, you have to install them - through the [CLI](https://reactnativereusables.com/docs/cli) inside `packages/example-library`. + through the [CLI](https://reactnativereusables.com/docs/cli) inside `packages/rnr-ui`. ## Building your own library -You can start by changing the `packages/example-library` folder name and replace all the references to it through the codebase. +You can start by changing the `packages/rnr-ui` folder name and replace all the references to it through the codebase. - All `package.json` files start with `@rnr/...` and you will need to update them with your own library name too. - - All the imports throughout the codebase use aliases defined in `tsconfig.json` files. You can search by `@/example-library` and replace it with the new name of the folder. + - All the imports throughout the codebase use aliases defined in `tsconfig.json` files. You can search by `@/rnr-ui` and replace it with the new name of the folder. ## References @@ -49,8 +49,8 @@ You can start by changing the `packages/example-library` folder name and replace ### Component Library -- `packages/example-library/package.json` to update the package name -- `packages/example-library/src/components/ui/*` to create your components -- `packages/example-library/src/examples/*` to update the example components -- `packages/example-library/src/blocks/*` to update the examples blocks +- `packages/rnr-ui/package.json` to update the package name +- `packages/rnr-ui/src/components/ui/*` to create your components +- `packages/rnr-ui/src/examples/*` to update the example components +- `packages/rnr-ui/src/blocks/*` to update the examples blocks diff --git a/apps/docs/lib/file-generator.ts b/apps/docs/lib/file-generator.ts index 3af9481..424b6c0 100644 --- a/apps/docs/lib/file-generator.ts +++ b/apps/docs/lib/file-generator.ts @@ -57,7 +57,7 @@ export function fileGenerator(): DocGenerator { function fixImports(value: string) { return value - .replaceAll('@/example-library/', '@/') - .replaceAll('@/example-library/blocks/', '@/components/') + .replaceAll('@/rnr-ui/', '@/') + .replaceAll('@/rnr-ui/blocks/', '@/components/') .replaceAll('~/', '@/'); } diff --git a/apps/docs/next.config.mjs b/apps/docs/next.config.mjs index 6aedd8a..2732afb 100644 --- a/apps/docs/next.config.mjs +++ b/apps/docs/next.config.mjs @@ -7,7 +7,7 @@ const config = { reactStrictMode: true, pageExtensions: ['js', 'jsx', 'mdx', 'ts', 'tsx'], transpilePackages: [ - '@rnr/example-library', + '@rnr/rnr-ui', 'react-native', 'react-native-web', 'expo', diff --git a/apps/docs/package.json b/apps/docs/package.json index 67b01e5..78ad28e 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -14,7 +14,7 @@ "@radix-ui/react-select": "^2.2.5", "@radix-ui/react-slot": "^1.2.3", "@radix-ui/react-tabs": "^1.1.12", - "@rnr/example-library": "workspace:*", + "@rnr/rnr-ui": "workspace:*", "@rnr/utils": "workspace:*", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", diff --git a/apps/docs/public/r/example-block.json b/apps/docs/public/r/example-block.json index a9d8323..8d62bed 100644 --- a/apps/docs/public/r/example-block.json +++ b/apps/docs/public/r/example-block.json @@ -12,8 +12,8 @@ ], "files": [ { - "path": "./node_modules/@rnr/example-library/src/blocks/multiple-buttons.tsx", - "content": "import { View } from 'react-native';\nimport { RedButton } from '@/example-library/components/ui/red-button';\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from '~/components/ui/card';\n\nexport function MultipleButtons() {\n return (\n \n \n \n Multiple Buttons\n \n Multiple buttons with different variants\n \n \n \n \n {}} label=\"Primary Red Button\" />\n {}} label=\"Secondary Red Button\" />\n {}} label=\"Outline Red Button\" />\n {}} label=\"Ghost Red Button\" />\n {}} label=\"Red Button Link\" />\n \n \n \n \n );\n}\n", + "path": "./node_modules/@rnr/rnr-ui/src/blocks/multiple-buttons.tsx", + "content": "import { View } from 'react-native';\nimport { RedButton } from '@/rnr-ui/components/ui/red-button';\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from '~/components/ui/card';\n\nexport function MultipleButtons() {\n return (\n \n \n \n Multiple Buttons\n \n Multiple buttons with different variants\n \n \n \n \n {}} label=\"Primary Red Button\" />\n {}} label=\"Secondary Red Button\" />\n {}} label=\"Outline Red Button\" />\n {}} label=\"Ghost Red Button\" />\n {}} label=\"Red Button Link\" />\n \n \n \n \n );\n}\n", "type": "registry:block" } ] diff --git a/apps/docs/public/r/example-component.json b/apps/docs/public/r/example-component.json index 30ec90f..c4212a6 100644 --- a/apps/docs/public/r/example-component.json +++ b/apps/docs/public/r/example-component.json @@ -11,7 +11,7 @@ ], "files": [ { - "path": "./node_modules/@rnr/example-library/src/components/ui/red-button.tsx", + "path": "./node_modules/@rnr/rnr-ui/src/components/ui/red-button.tsx", "content": "import { cva } from 'class-variance-authority';\nimport { Platform } from 'react-native';\nimport { Button, type ButtonProps } from '~/components/ui/button';\nimport { Text } from '~/components/ui/text';\nimport { cn } from '~/lib/utils';\n\nconst redButtonVariants = cva('', {\n variants: {\n variant: {\n default: cn(\n 'bg-red-500 active:bg-red-500/90',\n Platform.select({\n web: 'hover:bg-red-500/90',\n })\n ),\n destructive: cn(\n 'bg-red-700 active:bg-red-700/90',\n Platform.select({\n web: 'hover:bg-red-700/90',\n })\n ),\n outline: 'border-red-400 dark:border-red-400',\n secondary: cn(\n 'bg-red-200 active:bg-red-200/80',\n Platform.select({\n web: 'hover:bg-red-200/80',\n })\n ),\n ghost: 'active:bg-red-500/10 dark:active:bg-red-500/10',\n link: '',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n});\n\nconst redButtonTextVariants = cva('', {\n variants: {\n variant: {\n default: '',\n destructive: '',\n outline: cn(\n 'group-active:text-red-400',\n Platform.select({ web: 'group-hover:text-red-400' })\n ),\n secondary: 'text-black',\n ghost: '',\n link: 'text-red-400',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n});\n\ntype RedButtonProps = ButtonProps & {\n label: string;\n};\n\nfunction RedButton({ label, className, ...props }: RedButtonProps) {\n return (\n \n );\n}\n\nexport { RedButton, redButtonVariants, redButtonTextVariants };\nexport type { RedButtonProps };\n", "type": "registry:component" } diff --git a/apps/docs/public/r/form.json b/apps/docs/public/r/form.json index 197659d..61339a2 100644 --- a/apps/docs/public/r/form.json +++ b/apps/docs/public/r/form.json @@ -11,7 +11,7 @@ ], "files": [ { - "path": "./node_modules/@rnr/example-library/src/components/ui/forms.tsx", + "path": "./node_modules/@rnr/rnr-ui/src/components/ui/forms.tsx", "content": "import FormRc, { Field } from 'rc-field-form';\nimport { FieldProps } from 'rc-field-form/es/Field';\nimport React from 'react';\nimport { View } from 'react-native';\nimport { Label } from '~/components/ui/label';\nimport { Text } from '~/components/ui/text';\n\nfunction FormItem({\n name,\n label,\n children,\n ...restProps\n}: FieldProps & {\n label?: string;\n}) {\n const hasRequired = restProps.rules?.some((rule: any) => rule.required);\n return (\n \n {(control, meta, form) => {\n const hasError = meta.errors && meta.errors.length > 0;\n const errorMessage = meta.errors?.[0];\n\n // Handle function children - pass control, meta, form exactly like rc-field-form\n const childNode =\n typeof children === 'function'\n ? children(control, meta, form)\n : React.isValidElement(children)\n ? React.cloneElement(\n children as React.ReactElement,\n {\n ...control,\n // Map React Native TextInput props\n value: control.value ?? '',\n onChangeText: (text: string) => control.onChange(text),\n onBlur: control.onBlur,\n // Add error styling if needed\n className: hasError\n ? `${(children as any).props?.className || ''} border-destructive`.trim()\n : (children as any).props?.className,\n } as any\n )\n : children;\n\n // Only add UI wrapper if label or error exists\n if (!label && !errorMessage) {\n return childNode;\n }\n\n return (\n \n {label && (\n \n )}\n {childNode}\n {errorMessage && (\n \n {errorMessage}\n \n )}\n \n );\n }}\n \n );\n}\n\n// Create Form component with Item attached\nconst Form = FormRc as typeof FormRc & {\n Item: typeof FormItem;\n useForm: typeof FormRc.useForm;\n};\n\nForm.Item = FormItem;\nForm.useForm = FormRc.useForm;\n\nexport { Form };\n", "type": "registry:component" } diff --git a/apps/docs/registry.json b/apps/docs/registry.json index a816daf..336a5a6 100644 --- a/apps/docs/registry.json +++ b/apps/docs/registry.json @@ -11,7 +11,7 @@ "author": "@gabimoncha", "files": [ { - "path": "./node_modules/@rnr/example-library/src/components/ui/red-button.tsx", + "path": "./node_modules/@rnr/rnr-ui/src/components/ui/red-button.tsx", "type": "registry:component" } ], @@ -28,7 +28,7 @@ "author": "@gabimoncha", "files": [ { - "path": "./node_modules/@rnr/example-library/src/blocks/multiple-buttons.tsx", + "path": "./node_modules/@rnr/rnr-ui/src/blocks/multiple-buttons.tsx", "type": "registry:block" } ], @@ -46,7 +46,7 @@ "author": "@gabimoncha", "files": [ { - "path": "./node_modules/@rnr/example-library/src/components/ui/forms.tsx", + "path": "./node_modules/@rnr/rnr-ui/src/components/ui/forms.tsx", "type": "registry:component" } ], diff --git a/apps/docs/tsconfig.json b/apps/docs/tsconfig.json index 2004f62..a72aa9c 100644 --- a/apps/docs/tsconfig.json +++ b/apps/docs/tsconfig.json @@ -18,8 +18,8 @@ "incremental": true, "paths": { "@docs/*": ["./*"], - "~/*": ["../../packages/example-library/reusables/*"], - "@/example-library/*": ["../../packages/example-library/src/*"] + "~/*": ["../../packages/rnr-ui/reusables/*"], + "@/rnr-ui/*": ["../../packages/rnr-ui/src/*"] }, "plugins": [ { diff --git a/apps/showcase/app/components/example-block.tsx b/apps/showcase/app/components/example-block.tsx index 4bbe013..f068a47 100644 --- a/apps/showcase/app/components/example-block.tsx +++ b/apps/showcase/app/components/example-block.tsx @@ -1,6 +1,6 @@ import { PreviewCarousel } from '@showcase/components/preview-carousel'; import * as React from 'react'; -import { MultipleButtons } from '@/example-library/blocks/multiple-buttons'; +import { MultipleButtons } from '@/rnr-ui/blocks/multiple-buttons'; const exampleBlockPreviews = [{ name: 'Multiple Buttons', component: MultipleButtons }]; diff --git a/apps/showcase/app/components/example-component.tsx b/apps/showcase/app/components/example-component.tsx index 2269a73..37f2763 100644 --- a/apps/showcase/app/components/example-component.tsx +++ b/apps/showcase/app/components/example-component.tsx @@ -1,6 +1,6 @@ import { PreviewCarousel } from '@showcase/components/preview-carousel'; import * as React from 'react'; -import { RedButtonPreview, RedButtonSecondaryPreview } from '@/example-library/examples/red-button'; +import { RedButtonPreview, RedButtonSecondaryPreview } from '@/rnr-ui/examples/red-button'; const exampleComponentPreviews = [ { name: 'Default', component: RedButtonPreview }, diff --git a/apps/showcase/app/components/form.tsx b/apps/showcase/app/components/form.tsx index 9b6507c..0cf232d 100644 --- a/apps/showcase/app/components/form.tsx +++ b/apps/showcase/app/components/form.tsx @@ -1,6 +1,6 @@ import { PreviewCarousel } from '@showcase/components/preview-carousel'; import * as React from 'react'; -import { FormBasicPreview, FormWithValidationPreview } from '@/example-library/examples'; +import { FormBasicPreview, FormWithValidationPreview } from '@/rnr-ui/examples'; const formPreviews = [ { name: 'Basic', component: FormBasicPreview }, diff --git a/apps/showcase/package.json b/apps/showcase/package.json index 3e1a22f..669aba2 100644 --- a/apps/showcase/package.json +++ b/apps/showcase/package.json @@ -16,7 +16,7 @@ "@expo-google-fonts/geist": "^0.4.0", "@react-navigation/native": "^7.0.0", "@rn-primitives/slot": "~1.2.0", - "@rnr/example-library": "workspace:*", + "@rnr/rnr-ui": "workspace:*", "@rnr/utils": "workspace:*", "@shopify/flash-list": "1.7.6", "class-variance-authority": "^0.7.0", diff --git a/apps/showcase/public/r/example-block.json b/apps/showcase/public/r/example-block.json index a9d8323..8d62bed 100644 --- a/apps/showcase/public/r/example-block.json +++ b/apps/showcase/public/r/example-block.json @@ -12,8 +12,8 @@ ], "files": [ { - "path": "./node_modules/@rnr/example-library/src/blocks/multiple-buttons.tsx", - "content": "import { View } from 'react-native';\nimport { RedButton } from '@/example-library/components/ui/red-button';\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from '~/components/ui/card';\n\nexport function MultipleButtons() {\n return (\n \n \n \n Multiple Buttons\n \n Multiple buttons with different variants\n \n \n \n \n {}} label=\"Primary Red Button\" />\n {}} label=\"Secondary Red Button\" />\n {}} label=\"Outline Red Button\" />\n {}} label=\"Ghost Red Button\" />\n {}} label=\"Red Button Link\" />\n \n \n \n \n );\n}\n", + "path": "./node_modules/@rnr/rnr-ui/src/blocks/multiple-buttons.tsx", + "content": "import { View } from 'react-native';\nimport { RedButton } from '@/rnr-ui/components/ui/red-button';\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from '~/components/ui/card';\n\nexport function MultipleButtons() {\n return (\n \n \n \n Multiple Buttons\n \n Multiple buttons with different variants\n \n \n \n \n {}} label=\"Primary Red Button\" />\n {}} label=\"Secondary Red Button\" />\n {}} label=\"Outline Red Button\" />\n {}} label=\"Ghost Red Button\" />\n {}} label=\"Red Button Link\" />\n \n \n \n \n );\n}\n", "type": "registry:block" } ] diff --git a/apps/showcase/public/r/example-component.json b/apps/showcase/public/r/example-component.json index 30ec90f..c4212a6 100644 --- a/apps/showcase/public/r/example-component.json +++ b/apps/showcase/public/r/example-component.json @@ -11,7 +11,7 @@ ], "files": [ { - "path": "./node_modules/@rnr/example-library/src/components/ui/red-button.tsx", + "path": "./node_modules/@rnr/rnr-ui/src/components/ui/red-button.tsx", "content": "import { cva } from 'class-variance-authority';\nimport { Platform } from 'react-native';\nimport { Button, type ButtonProps } from '~/components/ui/button';\nimport { Text } from '~/components/ui/text';\nimport { cn } from '~/lib/utils';\n\nconst redButtonVariants = cva('', {\n variants: {\n variant: {\n default: cn(\n 'bg-red-500 active:bg-red-500/90',\n Platform.select({\n web: 'hover:bg-red-500/90',\n })\n ),\n destructive: cn(\n 'bg-red-700 active:bg-red-700/90',\n Platform.select({\n web: 'hover:bg-red-700/90',\n })\n ),\n outline: 'border-red-400 dark:border-red-400',\n secondary: cn(\n 'bg-red-200 active:bg-red-200/80',\n Platform.select({\n web: 'hover:bg-red-200/80',\n })\n ),\n ghost: 'active:bg-red-500/10 dark:active:bg-red-500/10',\n link: '',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n});\n\nconst redButtonTextVariants = cva('', {\n variants: {\n variant: {\n default: '',\n destructive: '',\n outline: cn(\n 'group-active:text-red-400',\n Platform.select({ web: 'group-hover:text-red-400' })\n ),\n secondary: 'text-black',\n ghost: '',\n link: 'text-red-400',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n});\n\ntype RedButtonProps = ButtonProps & {\n label: string;\n};\n\nfunction RedButton({ label, className, ...props }: RedButtonProps) {\n return (\n \n );\n}\n\nexport { RedButton, redButtonVariants, redButtonTextVariants };\nexport type { RedButtonProps };\n", "type": "registry:component" } diff --git a/apps/showcase/public/r/form.json b/apps/showcase/public/r/form.json index 197659d..61339a2 100644 --- a/apps/showcase/public/r/form.json +++ b/apps/showcase/public/r/form.json @@ -11,7 +11,7 @@ ], "files": [ { - "path": "./node_modules/@rnr/example-library/src/components/ui/forms.tsx", + "path": "./node_modules/@rnr/rnr-ui/src/components/ui/forms.tsx", "content": "import FormRc, { Field } from 'rc-field-form';\nimport { FieldProps } from 'rc-field-form/es/Field';\nimport React from 'react';\nimport { View } from 'react-native';\nimport { Label } from '~/components/ui/label';\nimport { Text } from '~/components/ui/text';\n\nfunction FormItem({\n name,\n label,\n children,\n ...restProps\n}: FieldProps & {\n label?: string;\n}) {\n const hasRequired = restProps.rules?.some((rule: any) => rule.required);\n return (\n \n {(control, meta, form) => {\n const hasError = meta.errors && meta.errors.length > 0;\n const errorMessage = meta.errors?.[0];\n\n // Handle function children - pass control, meta, form exactly like rc-field-form\n const childNode =\n typeof children === 'function'\n ? children(control, meta, form)\n : React.isValidElement(children)\n ? React.cloneElement(\n children as React.ReactElement,\n {\n ...control,\n // Map React Native TextInput props\n value: control.value ?? '',\n onChangeText: (text: string) => control.onChange(text),\n onBlur: control.onBlur,\n // Add error styling if needed\n className: hasError\n ? `${(children as any).props?.className || ''} border-destructive`.trim()\n : (children as any).props?.className,\n } as any\n )\n : children;\n\n // Only add UI wrapper if label or error exists\n if (!label && !errorMessage) {\n return childNode;\n }\n\n return (\n \n {label && (\n \n )}\n {childNode}\n {errorMessage && (\n \n {errorMessage}\n \n )}\n \n );\n }}\n \n );\n}\n\n// Create Form component with Item attached\nconst Form = FormRc as typeof FormRc & {\n Item: typeof FormItem;\n useForm: typeof FormRc.useForm;\n};\n\nForm.Item = FormItem;\nForm.useForm = FormRc.useForm;\n\nexport { Form };\n", "type": "registry:component" } diff --git a/apps/showcase/registry.json b/apps/showcase/registry.json index a816daf..336a5a6 100644 --- a/apps/showcase/registry.json +++ b/apps/showcase/registry.json @@ -11,7 +11,7 @@ "author": "@gabimoncha", "files": [ { - "path": "./node_modules/@rnr/example-library/src/components/ui/red-button.tsx", + "path": "./node_modules/@rnr/rnr-ui/src/components/ui/red-button.tsx", "type": "registry:component" } ], @@ -28,7 +28,7 @@ "author": "@gabimoncha", "files": [ { - "path": "./node_modules/@rnr/example-library/src/blocks/multiple-buttons.tsx", + "path": "./node_modules/@rnr/rnr-ui/src/blocks/multiple-buttons.tsx", "type": "registry:block" } ], @@ -46,7 +46,7 @@ "author": "@gabimoncha", "files": [ { - "path": "./node_modules/@rnr/example-library/src/components/ui/forms.tsx", + "path": "./node_modules/@rnr/rnr-ui/src/components/ui/forms.tsx", "type": "registry:component" } ], diff --git a/apps/showcase/tsconfig.json b/apps/showcase/tsconfig.json index dc8e63a..2d4784c 100644 --- a/apps/showcase/tsconfig.json +++ b/apps/showcase/tsconfig.json @@ -4,8 +4,8 @@ "baseUrl": ".", "paths": { "@showcase/*": ["./*"], - "~/*": ["../../packages/example-library/reusables/*"], - "@/example-library/*": ["../../packages/example-library/src/*"] + "~/*": ["../../packages/rnr-ui/reusables/*"], + "@/rnr-ui/*": ["../../packages/rnr-ui/src/*"] }, "jsx": "react-native", "types": ["nativewind/types"], diff --git a/package.json b/package.json index 5daa341..8ef670c 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,13 @@ "expo-modules-*", "typescript" ] - } + }, + "onlyBuiltDependencies": [ + "esbuild", + "msw", + "sharp", + "unrs-resolver" + ] }, "engines": { "node": ">=20.11.0" diff --git a/packages/example-library/components.json b/packages/rnr-ui/components.json similarity index 100% rename from packages/example-library/components.json rename to packages/rnr-ui/components.json diff --git a/packages/example-library/nativewind-env.d.ts b/packages/rnr-ui/nativewind-env.d.ts similarity index 100% rename from packages/example-library/nativewind-env.d.ts rename to packages/rnr-ui/nativewind-env.d.ts diff --git a/packages/example-library/package.json b/packages/rnr-ui/package.json similarity index 96% rename from packages/example-library/package.json rename to packages/rnr-ui/package.json index 8ec824e..235207d 100644 --- a/packages/example-library/package.json +++ b/packages/rnr-ui/package.json @@ -1,5 +1,5 @@ { - "name": "@rnr/example-library", + "name": "@rnr/rnr-ui", "description": "Example library for React Native Reusables Registry Template", "license": "MIT", "scripts": { diff --git a/packages/example-library/reusables/components/ui/button.tsx b/packages/rnr-ui/reusables/components/ui/button.tsx similarity index 100% rename from packages/example-library/reusables/components/ui/button.tsx rename to packages/rnr-ui/reusables/components/ui/button.tsx diff --git a/packages/example-library/reusables/components/ui/card.tsx b/packages/rnr-ui/reusables/components/ui/card.tsx similarity index 100% rename from packages/example-library/reusables/components/ui/card.tsx rename to packages/rnr-ui/reusables/components/ui/card.tsx diff --git a/packages/example-library/reusables/components/ui/label.tsx b/packages/rnr-ui/reusables/components/ui/label.tsx similarity index 100% rename from packages/example-library/reusables/components/ui/label.tsx rename to packages/rnr-ui/reusables/components/ui/label.tsx diff --git a/packages/example-library/reusables/components/ui/text.tsx b/packages/rnr-ui/reusables/components/ui/text.tsx similarity index 100% rename from packages/example-library/reusables/components/ui/text.tsx rename to packages/rnr-ui/reusables/components/ui/text.tsx diff --git a/packages/example-library/reusables/global.css b/packages/rnr-ui/reusables/global.css similarity index 100% rename from packages/example-library/reusables/global.css rename to packages/rnr-ui/reusables/global.css diff --git a/packages/example-library/reusables/lib/theme.ts b/packages/rnr-ui/reusables/lib/theme.ts similarity index 100% rename from packages/example-library/reusables/lib/theme.ts rename to packages/rnr-ui/reusables/lib/theme.ts diff --git a/packages/example-library/reusables/lib/utils.ts b/packages/rnr-ui/reusables/lib/utils.ts similarity index 100% rename from packages/example-library/reusables/lib/utils.ts rename to packages/rnr-ui/reusables/lib/utils.ts diff --git a/packages/example-library/src/blocks/index.ts b/packages/rnr-ui/src/blocks/index.ts similarity index 100% rename from packages/example-library/src/blocks/index.ts rename to packages/rnr-ui/src/blocks/index.ts diff --git a/packages/example-library/src/blocks/multiple-buttons.tsx b/packages/rnr-ui/src/blocks/multiple-buttons.tsx similarity index 94% rename from packages/example-library/src/blocks/multiple-buttons.tsx rename to packages/rnr-ui/src/blocks/multiple-buttons.tsx index 7839fd3..0e76c4e 100644 --- a/packages/example-library/src/blocks/multiple-buttons.tsx +++ b/packages/rnr-ui/src/blocks/multiple-buttons.tsx @@ -1,5 +1,5 @@ import { View } from 'react-native'; -import { RedButton } from '@/example-library/components/ui/red-button'; +import { RedButton } from '@/rnr-ui/components/ui/red-button'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '~/components/ui/card'; export function MultipleButtons() { diff --git a/packages/example-library/src/components/ui/forms.tsx b/packages/rnr-ui/src/components/ui/forms.tsx similarity index 100% rename from packages/example-library/src/components/ui/forms.tsx rename to packages/rnr-ui/src/components/ui/forms.tsx diff --git a/packages/example-library/src/components/ui/red-button.tsx b/packages/rnr-ui/src/components/ui/red-button.tsx similarity index 100% rename from packages/example-library/src/components/ui/red-button.tsx rename to packages/rnr-ui/src/components/ui/red-button.tsx diff --git a/packages/example-library/src/examples/form/form-basic.tsx b/packages/rnr-ui/src/examples/form/form-basic.tsx similarity index 96% rename from packages/example-library/src/examples/form/form-basic.tsx rename to packages/rnr-ui/src/examples/form/form-basic.tsx index 7f492a2..d70e34e 100644 --- a/packages/example-library/src/examples/form/form-basic.tsx +++ b/packages/rnr-ui/src/examples/form/form-basic.tsx @@ -1,4 +1,4 @@ -import { Form } from '@/example-library/components/ui/forms'; +import { Form } from '@/rnr-ui/components/ui/forms'; import { TextInput } from 'react-native'; import { View } from 'react-native'; import { Button } from '~/components/ui/button'; diff --git a/packages/example-library/src/examples/form/form-with-validation.tsx b/packages/rnr-ui/src/examples/form/form-with-validation.tsx similarity index 97% rename from packages/example-library/src/examples/form/form-with-validation.tsx rename to packages/rnr-ui/src/examples/form/form-with-validation.tsx index 17797bf..24ab4f5 100644 --- a/packages/example-library/src/examples/form/form-with-validation.tsx +++ b/packages/rnr-ui/src/examples/form/form-with-validation.tsx @@ -1,4 +1,4 @@ -import { Form } from '@/example-library/components/ui/forms'; +import { Form } from '@/rnr-ui/components/ui/forms'; import { TextInput } from 'react-native'; import { View } from 'react-native'; import { Button } from '~/components/ui/button'; diff --git a/packages/example-library/src/examples/form/index.ts b/packages/rnr-ui/src/examples/form/index.ts similarity index 100% rename from packages/example-library/src/examples/form/index.ts rename to packages/rnr-ui/src/examples/form/index.ts diff --git a/packages/example-library/src/examples/index.ts b/packages/rnr-ui/src/examples/index.ts similarity index 100% rename from packages/example-library/src/examples/index.ts rename to packages/rnr-ui/src/examples/index.ts diff --git a/packages/example-library/src/examples/red-button/index.ts b/packages/rnr-ui/src/examples/red-button/index.ts similarity index 100% rename from packages/example-library/src/examples/red-button/index.ts rename to packages/rnr-ui/src/examples/red-button/index.ts diff --git a/packages/example-library/src/examples/red-button/red-button-primary.tsx b/packages/rnr-ui/src/examples/red-button/red-button-primary.tsx similarity index 53% rename from packages/example-library/src/examples/red-button/red-button-primary.tsx rename to packages/rnr-ui/src/examples/red-button/red-button-primary.tsx index afb1884..6ee5729 100644 --- a/packages/example-library/src/examples/red-button/red-button-primary.tsx +++ b/packages/rnr-ui/src/examples/red-button/red-button-primary.tsx @@ -1,4 +1,4 @@ -import { RedButton } from '@/example-library/components/ui/red-button'; +import { RedButton } from '@/rnr-ui/components/ui/red-button'; export function RedButtonPreview() { return ; diff --git a/packages/example-library/src/examples/red-button/red-button-secondary.tsx b/packages/rnr-ui/src/examples/red-button/red-button-secondary.tsx similarity index 62% rename from packages/example-library/src/examples/red-button/red-button-secondary.tsx rename to packages/rnr-ui/src/examples/red-button/red-button-secondary.tsx index 3570664..74cc13d 100644 --- a/packages/example-library/src/examples/red-button/red-button-secondary.tsx +++ b/packages/rnr-ui/src/examples/red-button/red-button-secondary.tsx @@ -1,4 +1,4 @@ -import { RedButton } from '@/example-library/components/ui/red-button'; +import { RedButton } from '@/rnr-ui/components/ui/red-button'; export function RedButtonSecondaryPreview() { return ; diff --git a/packages/example-library/tailwind.config.js b/packages/rnr-ui/tailwind.config.js similarity index 100% rename from packages/example-library/tailwind.config.js rename to packages/rnr-ui/tailwind.config.js diff --git a/packages/example-library/tsconfig.json b/packages/rnr-ui/tsconfig.json similarity index 87% rename from packages/example-library/tsconfig.json rename to packages/rnr-ui/tsconfig.json index 49b49c8..4a89766 100644 --- a/packages/example-library/tsconfig.json +++ b/packages/rnr-ui/tsconfig.json @@ -6,7 +6,7 @@ "baseUrl": ".", "paths": { "~/*": ["reusables/*"], - "@/example-library/*": ["src/*"] + "@/rnr-ui/*": ["src/*"] } }, "exclude": ["node_modules"] diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 75fdd69..c8f0b53 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -35,9 +35,9 @@ importers: '@radix-ui/react-tabs': specifier: ^1.1.12 version: 1.1.13(@types/react-dom@19.1.5(@types/react@19.0.14))(@types/react@19.0.14)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@rnr/example-library': + '@rnr/rnr-ui': specifier: workspace:* - version: link:../../packages/example-library + version: link:../../packages/rnr-ui '@rnr/utils': specifier: workspace:* version: link:../../packages/utils @@ -147,9 +147,9 @@ importers: '@rn-primitives/slot': specifier: ~1.2.0 version: 1.2.0(react-native-web@0.21.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react-native@0.79.5(@babel/core@7.28.5)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0) - '@rnr/example-library': + '@rnr/rnr-ui': specifier: workspace:* - version: link:../../packages/example-library + version: link:../../packages/rnr-ui '@rnr/utils': specifier: workspace:* version: link:../../packages/utils @@ -242,7 +242,7 @@ importers: specifier: ^5.8.3 version: 5.9.3 - packages/example-library: + packages/rnr-ui: dependencies: '@react-navigation/native': specifier: ^7.0.0 From de4549eec17f1c17a82552c32bd2c329c0122708 Mon Sep 17 00:00:00 2001 From: peopleinfo <49970466+peopleinfo@users.noreply.github.com> Date: Fri, 7 Nov 2025 10:59:05 +0700 Subject: [PATCH 4/9] config --- apps/docs/.eslintrc.json | 2 +- apps/docs/package.json | 1 + package.json | 1 + packages/config/eslint/next.cjs | 4 + packages/config/index.js | 2 + packages/config/package.json | 20 + packages/config/prettier/index.cjs | 10 + packages/config/vitest/base.ts | 13 + packages/utils/coverage/lcov-report/base.css | 224 +++++ .../coverage/lcov-report/block-navigation.js | 87 ++ .../utils/coverage/lcov-report/favicon.png | Bin 0 -> 445 bytes .../utils/coverage/lcov-report/index.html | 116 +++ .../utils/coverage/lcov-report/object.ts.html | 268 ++++++ .../utils/coverage/lcov-report/prettify.css | 1 + .../utils/coverage/lcov-report/prettify.js | 2 + .../lcov-report/sort-arrow-sprite.png | Bin 0 -> 138 bytes packages/utils/coverage/lcov-report/sorter.js | 210 ++++ packages/utils/coverage/lcov.info | 67 ++ packages/utils/package.json | 9 +- packages/utils/src/__tests__/object.test.ts | 93 ++ packages/utils/src/index.ts | 1 + packages/utils/src/object.ts | 61 ++ packages/utils/tsconfig.json | 1 + packages/utils/vitest.config.ts | 18 + pnpm-lock.yaml | 900 ++++++++++++++++++ prettier.config.cjs | 2 + 26 files changed, 2110 insertions(+), 3 deletions(-) create mode 100644 packages/config/eslint/next.cjs create mode 100644 packages/config/index.js create mode 100644 packages/config/package.json create mode 100644 packages/config/prettier/index.cjs create mode 100644 packages/config/vitest/base.ts create mode 100644 packages/utils/coverage/lcov-report/base.css create mode 100644 packages/utils/coverage/lcov-report/block-navigation.js create mode 100644 packages/utils/coverage/lcov-report/favicon.png create mode 100644 packages/utils/coverage/lcov-report/index.html create mode 100644 packages/utils/coverage/lcov-report/object.ts.html create mode 100644 packages/utils/coverage/lcov-report/prettify.css create mode 100644 packages/utils/coverage/lcov-report/prettify.js create mode 100644 packages/utils/coverage/lcov-report/sort-arrow-sprite.png create mode 100644 packages/utils/coverage/lcov-report/sorter.js create mode 100644 packages/utils/coverage/lcov.info create mode 100644 packages/utils/src/__tests__/object.test.ts create mode 100644 packages/utils/src/object.ts create mode 100644 packages/utils/vitest.config.ts create mode 100644 prettier.config.cjs diff --git a/apps/docs/.eslintrc.json b/apps/docs/.eslintrc.json index 3722418..15ecaa1 100644 --- a/apps/docs/.eslintrc.json +++ b/apps/docs/.eslintrc.json @@ -1,3 +1,3 @@ { - "extends": ["next/core-web-vitals", "next/typescript"] + "extends": ["@rnr/config/eslint/next"] } diff --git a/apps/docs/package.json b/apps/docs/package.json index 78ad28e..b539390 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -38,6 +38,7 @@ "tailwindcss-animate": "^1.0.7" }, "devDependencies": { + "@rnr/config": "workspace:*", "@types/mdx": "^2.0.13", "@types/node": "22.10.5", "@types/react": "19.0.14", diff --git a/package.json b/package.json index 8ef670c..3db0463 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "clean": "turbo clean && rm -rf .turbo node_modules" }, "devDependencies": { + "@rnr/config": "workspace:*", "prettier": "^3.6.2", "prettier-plugin-tailwindcss": "^0.6.14", "turbo": "^2.6.0", diff --git a/packages/config/eslint/next.cjs b/packages/config/eslint/next.cjs new file mode 100644 index 0000000..d8f1049 --- /dev/null +++ b/packages/config/eslint/next.cjs @@ -0,0 +1,4 @@ +module.exports = { + extends: ['next/core-web-vitals', 'next/typescript'], +}; + diff --git a/packages/config/index.js b/packages/config/index.js new file mode 100644 index 0000000..cb73d58 --- /dev/null +++ b/packages/config/index.js @@ -0,0 +1,2 @@ +export {}; + diff --git a/packages/config/package.json b/packages/config/package.json new file mode 100644 index 0000000..48e6028 --- /dev/null +++ b/packages/config/package.json @@ -0,0 +1,20 @@ +{ + "name": "@rnr/config", + "version": "0.0.0", + "private": true, + "type": "module", + "main": "./index.js", + "exports": { + "./eslint/next": "./eslint/next.cjs", + "./prettier": "./prettier/index.cjs", + "./vitest/base": "./vitest/base.ts" + }, + "peerDependencies": { + "eslint": "^8 || ^9", + "eslint-config-next": "*", + "prettier": "^3", + "prettier-plugin-tailwindcss": "*", + "vitest": "^2" + } +} + diff --git a/packages/config/prettier/index.cjs b/packages/config/prettier/index.cjs new file mode 100644 index 0000000..983e0d5 --- /dev/null +++ b/packages/config/prettier/index.cjs @@ -0,0 +1,10 @@ +/** @type {import('prettier').Config} */ +module.exports = { + arrowParens: 'always', + printWidth: 100, + semi: true, + singleQuote: true, + trailingComma: 'all', + plugins: ['prettier-plugin-tailwindcss'], +}; + diff --git a/packages/config/vitest/base.ts b/packages/config/vitest/base.ts new file mode 100644 index 0000000..19869df --- /dev/null +++ b/packages/config/vitest/base.ts @@ -0,0 +1,13 @@ +import { defineConfig } from 'vitest/config'; + +export const vitestBaseConfig = defineConfig({ + test: { + coverage: { + provider: 'v8', + reporter: ['text', 'lcov'], + }, + }, +}); + +export default vitestBaseConfig; + diff --git a/packages/utils/coverage/lcov-report/base.css b/packages/utils/coverage/lcov-report/base.css new file mode 100644 index 0000000..f418035 --- /dev/null +++ b/packages/utils/coverage/lcov-report/base.css @@ -0,0 +1,224 @@ +body, html { + margin:0; padding: 0; + height: 100%; +} +body { + font-family: Helvetica Neue, Helvetica, Arial; + font-size: 14px; + color:#333; +} +.small { font-size: 12px; } +*, *:after, *:before { + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + box-sizing:border-box; + } +h1 { font-size: 20px; margin: 0;} +h2 { font-size: 14px; } +pre { + font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace; + margin: 0; + padding: 0; + -moz-tab-size: 2; + -o-tab-size: 2; + tab-size: 2; +} +a { color:#0074D9; text-decoration:none; } +a:hover { text-decoration:underline; } +.strong { font-weight: bold; } +.space-top1 { padding: 10px 0 0 0; } +.pad2y { padding: 20px 0; } +.pad1y { padding: 10px 0; } +.pad2x { padding: 0 20px; } +.pad2 { padding: 20px; } +.pad1 { padding: 10px; } +.space-left2 { padding-left:55px; } +.space-right2 { padding-right:20px; } +.center { text-align:center; } +.clearfix { display:block; } +.clearfix:after { + content:''; + display:block; + height:0; + clear:both; + visibility:hidden; + } +.fl { float: left; } +@media only screen and (max-width:640px) { + .col3 { width:100%; max-width:100%; } + .hide-mobile { display:none!important; } +} + +.quiet { + color: #7f7f7f; + color: rgba(0,0,0,0.5); +} +.quiet a { opacity: 0.7; } + +.fraction { + font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; + font-size: 10px; + color: #555; + background: #E8E8E8; + padding: 4px 5px; + border-radius: 3px; + vertical-align: middle; +} + +div.path a:link, div.path a:visited { color: #333; } +table.coverage { + border-collapse: collapse; + margin: 10px 0 0 0; + padding: 0; +} + +table.coverage td { + margin: 0; + padding: 0; + vertical-align: top; +} +table.coverage td.line-count { + text-align: right; + padding: 0 5px 0 20px; +} +table.coverage td.line-coverage { + text-align: right; + padding-right: 10px; + min-width:20px; +} + +table.coverage td span.cline-any { + display: inline-block; + padding: 0 5px; + width: 100%; +} +.missing-if-branch { + display: inline-block; + margin-right: 5px; + border-radius: 3px; + position: relative; + padding: 0 4px; + background: #333; + color: yellow; +} + +.skip-if-branch { + display: none; + margin-right: 10px; + position: relative; + padding: 0 4px; + background: #ccc; + color: white; +} +.missing-if-branch .typ, .skip-if-branch .typ { + color: inherit !important; +} +.coverage-summary { + border-collapse: collapse; + width: 100%; +} +.coverage-summary tr { border-bottom: 1px solid #bbb; } +.keyline-all { border: 1px solid #ddd; } +.coverage-summary td, .coverage-summary th { padding: 10px; } +.coverage-summary tbody { border: 1px solid #bbb; } +.coverage-summary td { border-right: 1px solid #bbb; } +.coverage-summary td:last-child { border-right: none; } +.coverage-summary th { + text-align: left; + font-weight: normal; + white-space: nowrap; +} +.coverage-summary th.file { border-right: none !important; } +.coverage-summary th.pct { } +.coverage-summary th.pic, +.coverage-summary th.abs, +.coverage-summary td.pct, +.coverage-summary td.abs { text-align: right; } +.coverage-summary td.file { white-space: nowrap; } +.coverage-summary td.pic { min-width: 120px !important; } +.coverage-summary tfoot td { } + +.coverage-summary .sorter { + height: 10px; + width: 7px; + display: inline-block; + margin-left: 0.5em; + background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent; +} +.coverage-summary .sorted .sorter { + background-position: 0 -20px; +} +.coverage-summary .sorted-desc .sorter { + background-position: 0 -10px; +} +.status-line { height: 10px; } +/* yellow */ +.cbranch-no { background: yellow !important; color: #111; } +/* dark red */ +.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 } +.low .chart { border:1px solid #C21F39 } +.highlighted, +.highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{ + background: #C21F39 !important; +} +/* medium red */ +.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE } +/* light red */ +.low, .cline-no { background:#FCE1E5 } +/* light green */ +.high, .cline-yes { background:rgb(230,245,208) } +/* medium green */ +.cstat-yes { background:rgb(161,215,106) } +/* dark green */ +.status-line.high, .high .cover-fill { background:rgb(77,146,33) } +.high .chart { border:1px solid rgb(77,146,33) } +/* dark yellow (gold) */ +.status-line.medium, .medium .cover-fill { background: #f9cd0b; } +.medium .chart { border:1px solid #f9cd0b; } +/* light yellow */ +.medium { background: #fff4c2; } + +.cstat-skip { background: #ddd; color: #111; } +.fstat-skip { background: #ddd; color: #111 !important; } +.cbranch-skip { background: #ddd !important; color: #111; } + +span.cline-neutral { background: #eaeaea; } + +.coverage-summary td.empty { + opacity: .5; + padding-top: 4px; + padding-bottom: 4px; + line-height: 1; + color: #888; +} + +.cover-fill, .cover-empty { + display:inline-block; + height: 12px; +} +.chart { + line-height: 0; +} +.cover-empty { + background: white; +} +.cover-full { + border-right: none !important; +} +pre.prettyprint { + border: none !important; + padding: 0 !important; + margin: 0 !important; +} +.com { color: #999 !important; } +.ignore-none { color: #999; font-weight: normal; } + +.wrapper { + min-height: 100%; + height: auto !important; + height: 100%; + margin: 0 auto -48px; +} +.footer, .push { + height: 48px; +} diff --git a/packages/utils/coverage/lcov-report/block-navigation.js b/packages/utils/coverage/lcov-report/block-navigation.js new file mode 100644 index 0000000..530d1ed --- /dev/null +++ b/packages/utils/coverage/lcov-report/block-navigation.js @@ -0,0 +1,87 @@ +/* eslint-disable */ +var jumpToCode = (function init() { + // Classes of code we would like to highlight in the file view + var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no']; + + // Elements to highlight in the file listing view + var fileListingElements = ['td.pct.low']; + + // We don't want to select elements that are direct descendants of another match + var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > ` + + // Selector that finds elements on the page to which we can jump + var selector = + fileListingElements.join(', ') + + ', ' + + notSelector + + missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b` + + // The NodeList of matching elements + var missingCoverageElements = document.querySelectorAll(selector); + + var currentIndex; + + function toggleClass(index) { + missingCoverageElements + .item(currentIndex) + .classList.remove('highlighted'); + missingCoverageElements.item(index).classList.add('highlighted'); + } + + function makeCurrent(index) { + toggleClass(index); + currentIndex = index; + missingCoverageElements.item(index).scrollIntoView({ + behavior: 'smooth', + block: 'center', + inline: 'center' + }); + } + + function goToPrevious() { + var nextIndex = 0; + if (typeof currentIndex !== 'number' || currentIndex === 0) { + nextIndex = missingCoverageElements.length - 1; + } else if (missingCoverageElements.length > 1) { + nextIndex = currentIndex - 1; + } + + makeCurrent(nextIndex); + } + + function goToNext() { + var nextIndex = 0; + + if ( + typeof currentIndex === 'number' && + currentIndex < missingCoverageElements.length - 1 + ) { + nextIndex = currentIndex + 1; + } + + makeCurrent(nextIndex); + } + + return function jump(event) { + if ( + document.getElementById('fileSearch') === document.activeElement && + document.activeElement != null + ) { + // if we're currently focused on the search input, we don't want to navigate + return; + } + + switch (event.which) { + case 78: // n + case 74: // j + goToNext(); + break; + case 66: // b + case 75: // k + case 80: // p + goToPrevious(); + break; + } + }; +})(); +window.addEventListener('keydown', jumpToCode); diff --git a/packages/utils/coverage/lcov-report/favicon.png b/packages/utils/coverage/lcov-report/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..c1525b811a167671e9de1fa78aab9f5c0b61cef7 GIT binary patch literal 445 zcmV;u0Yd(XP))rP{nL}Ln%S7`m{0DjX9TLF* zFCb$4Oi7vyLOydb!7n&^ItCzb-%BoB`=x@N2jll2Nj`kauio%aw_@fe&*}LqlFT43 z8doAAe))z_%=P%v^@JHp3Hjhj^6*Kr_h|g_Gr?ZAa&y>wxHE99Gk>A)2MplWz2xdG zy8VD2J|Uf#EAw*bo5O*PO_}X2Tob{%bUoO2G~T`@%S6qPyc}VkhV}UifBuRk>%5v( z)x7B{I~z*k<7dv#5tC+m{km(D087J4O%+<<;K|qwefb6@GSX45wCK}Sn*> + + + + Code coverage report for All files + + + + + + + + + +
+
+

All files

+
+ +
+ 100% + Statements + 38/38 +
+ + +
+ 100% + Branches + 16/16 +
+ + +
+ 100% + Functions + 2/2 +
+ + +
+ 100% + Lines + 38/38 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
object.ts +
+
100%38/38100%16/16100%2/2100%38/38
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/packages/utils/coverage/lcov-report/object.ts.html b/packages/utils/coverage/lcov-report/object.ts.html new file mode 100644 index 0000000..b7e8aa2 --- /dev/null +++ b/packages/utils/coverage/lcov-report/object.ts.html @@ -0,0 +1,268 @@ + + + + + + Code coverage report for object.ts + + + + + + + + + +
+
+

All files object.ts

+
+ +
+ 100% + Statements + 38/38 +
+ + +
+ 100% + Branches + 16/16 +
+ + +
+ 100% + Functions + 2/2 +
+ + +
+ 100% + Lines + 38/38 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +621x +  +  +  +  +  +  +  +  +1x +6x +6x +6x +6x +2x +2x +  +6x +1x +1x +  +3x +  +6x +5x +4x +4x +5x +  +3x +3x +  +  +  +  +  +  +1x +7x +7x +7x +7x +2x +2x +  +7x +1x +1x +  +4x +4x +  +7x +10x +6x +6x +10x +  +4x +4x +  + 
const hasOwn = Object.prototype.hasOwnProperty;
+ 
+type AnyRecord = Record<PropertyKey, unknown>;
+ 
+/**
+ * Pick a subset of properties from an object.
+ * @param source - The source object to pick properties from.
+ * @param keys - The property keys to include in the resulting object.
+ */
+export function pick<T extends AnyRecord, const K extends readonly (keyof T)[] | []>(
+  source: T | null | undefined,
+  keys: K,
+): Pick<T, K[number]> {
+  if (!source) {
+    return {} as Pick<T, K[number]>;
+  }
+ 
+  if (keys.length === 0) {
+    return {} as Pick<T, K[number]>;
+  }
+ 
+  const result: Partial<Pick<T, K[number]>> = {};
+ 
+  for (const key of keys) {
+    if (hasOwn.call(source, key)) {
+      result[key] = source[key];
+    }
+  }
+ 
+  return result as Pick<T, K[number]>;
+}
+ 
+/**
+ * Omit a subset of properties from an object.
+ * @param source - The source object to omit properties from.
+ * @param keys - The property keys to remove from the resulting object.
+ */
+export function omit<T extends AnyRecord, const K extends readonly (keyof T)[] | []>(
+  source: T | null | undefined,
+  keys: K,
+): Omit<T, K[number]> {
+  if (!source) {
+    return {} as Omit<T, K[number]>;
+  }
+ 
+  if (keys.length === 0) {
+    return { ...source } as Omit<T, K[number]>;
+  }
+ 
+  const keysToOmit = new Set<PropertyKey>(keys as readonly PropertyKey[]);
+  const result: Partial<Omit<T, K[number]>> = {};
+ 
+  for (const key of Reflect.ownKeys(source) as (keyof T)[]) {
+    if (!keysToOmit.has(key)) {
+      result[key] = source[key];
+    }
+  }
+ 
+  return result as Omit<T, K[number]>;
+}
+ 
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/packages/utils/coverage/lcov-report/prettify.css b/packages/utils/coverage/lcov-report/prettify.css new file mode 100644 index 0000000..b317a7c --- /dev/null +++ b/packages/utils/coverage/lcov-report/prettify.css @@ -0,0 +1 @@ +.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} diff --git a/packages/utils/coverage/lcov-report/prettify.js b/packages/utils/coverage/lcov-report/prettify.js new file mode 100644 index 0000000..b322523 --- /dev/null +++ b/packages/utils/coverage/lcov-report/prettify.js @@ -0,0 +1,2 @@ +/* eslint-disable */ +window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;arat[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); diff --git a/packages/utils/coverage/lcov-report/sort-arrow-sprite.png b/packages/utils/coverage/lcov-report/sort-arrow-sprite.png new file mode 100644 index 0000000000000000000000000000000000000000..6ed68316eb3f65dec9063332d2f69bf3093bbfab GIT binary patch literal 138 zcmeAS@N?(olHy`uVBq!ia0vp^>_9Bd!3HEZxJ@+%Qh}Z>jv*C{$p!i!8j}?a+@3A= zIAGwzjijN=FBi!|L1t?LM;Q;gkwn>2cAy-KV{dn nf0J1DIvEHQu*n~6U}x}qyky7vi4|9XhBJ7&`njxgN@xNA8m%nc literal 0 HcmV?d00001 diff --git a/packages/utils/coverage/lcov-report/sorter.js b/packages/utils/coverage/lcov-report/sorter.js new file mode 100644 index 0000000..4ed70ae --- /dev/null +++ b/packages/utils/coverage/lcov-report/sorter.js @@ -0,0 +1,210 @@ +/* eslint-disable */ +var addSorting = (function() { + 'use strict'; + var cols, + currentSort = { + index: 0, + desc: false + }; + + // returns the summary table element + function getTable() { + return document.querySelector('.coverage-summary'); + } + // returns the thead element of the summary table + function getTableHeader() { + return getTable().querySelector('thead tr'); + } + // returns the tbody element of the summary table + function getTableBody() { + return getTable().querySelector('tbody'); + } + // returns the th element for nth column + function getNthColumn(n) { + return getTableHeader().querySelectorAll('th')[n]; + } + + function onFilterInput() { + const searchValue = document.getElementById('fileSearch').value; + const rows = document.getElementsByTagName('tbody')[0].children; + + // Try to create a RegExp from the searchValue. If it fails (invalid regex), + // it will be treated as a plain text search + let searchRegex; + try { + searchRegex = new RegExp(searchValue, 'i'); // 'i' for case-insensitive + } catch (error) { + searchRegex = null; + } + + for (let i = 0; i < rows.length; i++) { + const row = rows[i]; + let isMatch = false; + + if (searchRegex) { + // If a valid regex was created, use it for matching + isMatch = searchRegex.test(row.textContent); + } else { + // Otherwise, fall back to the original plain text search + isMatch = row.textContent + .toLowerCase() + .includes(searchValue.toLowerCase()); + } + + row.style.display = isMatch ? '' : 'none'; + } + } + + // loads the search box + function addSearchBox() { + var template = document.getElementById('filterTemplate'); + var templateClone = template.content.cloneNode(true); + templateClone.getElementById('fileSearch').oninput = onFilterInput; + template.parentElement.appendChild(templateClone); + } + + // loads all columns + function loadColumns() { + var colNodes = getTableHeader().querySelectorAll('th'), + colNode, + cols = [], + col, + i; + + for (i = 0; i < colNodes.length; i += 1) { + colNode = colNodes[i]; + col = { + key: colNode.getAttribute('data-col'), + sortable: !colNode.getAttribute('data-nosort'), + type: colNode.getAttribute('data-type') || 'string' + }; + cols.push(col); + if (col.sortable) { + col.defaultDescSort = col.type === 'number'; + colNode.innerHTML = + colNode.innerHTML + ''; + } + } + return cols; + } + // attaches a data attribute to every tr element with an object + // of data values keyed by column name + function loadRowData(tableRow) { + var tableCols = tableRow.querySelectorAll('td'), + colNode, + col, + data = {}, + i, + val; + for (i = 0; i < tableCols.length; i += 1) { + colNode = tableCols[i]; + col = cols[i]; + val = colNode.getAttribute('data-value'); + if (col.type === 'number') { + val = Number(val); + } + data[col.key] = val; + } + return data; + } + // loads all row data + function loadData() { + var rows = getTableBody().querySelectorAll('tr'), + i; + + for (i = 0; i < rows.length; i += 1) { + rows[i].data = loadRowData(rows[i]); + } + } + // sorts the table using the data for the ith column + function sortByIndex(index, desc) { + var key = cols[index].key, + sorter = function(a, b) { + a = a.data[key]; + b = b.data[key]; + return a < b ? -1 : a > b ? 1 : 0; + }, + finalSorter = sorter, + tableBody = document.querySelector('.coverage-summary tbody'), + rowNodes = tableBody.querySelectorAll('tr'), + rows = [], + i; + + if (desc) { + finalSorter = function(a, b) { + return -1 * sorter(a, b); + }; + } + + for (i = 0; i < rowNodes.length; i += 1) { + rows.push(rowNodes[i]); + tableBody.removeChild(rowNodes[i]); + } + + rows.sort(finalSorter); + + for (i = 0; i < rows.length; i += 1) { + tableBody.appendChild(rows[i]); + } + } + // removes sort indicators for current column being sorted + function removeSortIndicators() { + var col = getNthColumn(currentSort.index), + cls = col.className; + + cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); + col.className = cls; + } + // adds sort indicators for current column being sorted + function addSortIndicators() { + getNthColumn(currentSort.index).className += currentSort.desc + ? ' sorted-desc' + : ' sorted'; + } + // adds event listeners for all sorter widgets + function enableUI() { + var i, + el, + ithSorter = function ithSorter(i) { + var col = cols[i]; + + return function() { + var desc = col.defaultDescSort; + + if (currentSort.index === i) { + desc = !currentSort.desc; + } + sortByIndex(i, desc); + removeSortIndicators(); + currentSort.index = i; + currentSort.desc = desc; + addSortIndicators(); + }; + }; + for (i = 0; i < cols.length; i += 1) { + if (cols[i].sortable) { + // add the click event handler on the th so users + // dont have to click on those tiny arrows + el = getNthColumn(i).querySelector('.sorter').parentElement; + if (el.addEventListener) { + el.addEventListener('click', ithSorter(i)); + } else { + el.attachEvent('onclick', ithSorter(i)); + } + } + } + } + // adds sorting functionality to the UI + return function() { + if (!getTable()) { + return; + } + cols = loadColumns(); + loadData(); + addSearchBox(); + addSortIndicators(); + enableUI(); + }; +})(); + +window.addEventListener('load', addSorting); diff --git a/packages/utils/coverage/lcov.info b/packages/utils/coverage/lcov.info new file mode 100644 index 0000000..3e084a9 --- /dev/null +++ b/packages/utils/coverage/lcov.info @@ -0,0 +1,67 @@ +TN: +SF:src\object.ts +FN:10,pick +FN:38,omit +FNF:2 +FNH:2 +FNDA:6,pick +FNDA:7,omit +DA:1,1 +DA:10,1 +DA:11,6 +DA:12,6 +DA:13,6 +DA:14,6 +DA:15,2 +DA:16,2 +DA:18,6 +DA:19,1 +DA:20,1 +DA:22,3 +DA:24,6 +DA:25,5 +DA:26,4 +DA:27,4 +DA:28,5 +DA:30,3 +DA:31,3 +DA:38,1 +DA:39,7 +DA:40,7 +DA:41,7 +DA:42,7 +DA:43,2 +DA:44,2 +DA:46,7 +DA:47,1 +DA:48,1 +DA:50,4 +DA:51,4 +DA:53,7 +DA:54,10 +DA:55,6 +DA:56,6 +DA:57,10 +DA:59,4 +DA:60,4 +LF:38 +LH:38 +BRDA:10,0,0,6 +BRDA:14,1,0,2 +BRDA:16,2,0,4 +BRDA:18,3,0,1 +BRDA:20,4,0,3 +BRDA:24,5,0,5 +BRDA:25,6,0,4 +BRDA:28,7,0,3 +BRDA:38,8,0,7 +BRDA:42,9,0,2 +BRDA:44,10,0,5 +BRDA:46,11,0,1 +BRDA:48,12,0,4 +BRDA:53,13,0,10 +BRDA:54,14,0,6 +BRDA:57,15,0,4 +BRF:16 +BRH:16 +end_of_record diff --git a/packages/utils/package.json b/packages/utils/package.json index cb7d076..4dbf71a 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -3,7 +3,8 @@ "description": "Utility functions for React Native Reusables", "license": "MIT", "scripts": { - "clean": "rm -rf node_modules" + "clean": "rm -rf node_modules", + "test": "vitest run --coverage" }, "version": "0.0.0", "type": "module", @@ -22,10 +23,14 @@ ] }, "devDependencies": { + "@rnr/config": "workspace:*", "@tsconfig/recommended": "^1.0.1", + "@types/node": "^22.10.1", "@types/react": "~19.0.14", + "@vitest/coverage-v8": "^2.1.4", "react": "19.0.0", - "react-native": "0.79.5" + "react-native": "0.79.5", + "vitest": "^2.1.4" }, "peerDependencies": { "react": "*", diff --git a/packages/utils/src/__tests__/object.test.ts b/packages/utils/src/__tests__/object.test.ts new file mode 100644 index 0000000..9b851d1 --- /dev/null +++ b/packages/utils/src/__tests__/object.test.ts @@ -0,0 +1,93 @@ +import { describe, expect, it } from 'vitest'; + +import { omit, pick } from '../object'; + +describe('pick', () => { + it('returns only the requested properties', () => { + const source = { id: 1, name: 'Alice', age: 30 }; + + const result = pick(source, ['id', 'name'] as const); + + expect(result).toStrictEqual({ id: 1, name: 'Alice' }); + expect(Object.keys(result)).toHaveLength(2); + }); + + it('ignores missing keys and prototype properties', () => { + const proto = { inherited: true }; + const source = Object.create(proto, { + present: { + value: 42, + enumerable: true, + }, + }) as { present: number; missing?: string }; + + const result = pick(source, ['present', 'missing'] as const); + + expect(result).toStrictEqual({ present: 42 }); + expect('inherited' in result).toBe(false); + }); + + it('handles nullish input gracefully', () => { + expect(pick(null, ['a'] as const)).toStrictEqual({}); + expect(pick(undefined, ['a'] as const)).toStrictEqual({}); + }); + + it('returns an empty object when no keys are provided', () => { + const source = { id: 1, name: 'Alice' }; + + const result = pick(source, [] as const); + + expect(result).toStrictEqual({}); + }); +}); + +describe('omit', () => { + it('removes specified keys', () => { + const source = { id: 1, secret: 'hidden', role: 'admin' }; + + const result = omit(source, ['secret'] as const); + + expect(result).toStrictEqual({ id: 1, role: 'admin' }); + }); + + it('preserves symbol keys unless omitted', () => { + const sym = Symbol('token'); + const source = { id: 1, [sym]: 'value' }; + + expect(omit(source, ['id'] as const)).toStrictEqual({ [sym]: 'value' }); + expect(omit(source, [sym] as const)).toStrictEqual({ id: 1 }); + }); + + it('returns a shallow clone when no keys are omitted', () => { + const source = { id: 1, count: 2 }; + + const result = omit(source, [] as const); + + expect(result).toStrictEqual(source); + expect(result).not.toBe(source); + }); + + it('handles nullish input gracefully', () => { + expect(omit(null, ['a'] as const)).toStrictEqual({}); + expect(omit(undefined, ['a'] as const)).toStrictEqual({}); + }); +}); + +describe('type inference', () => { + it('narrows the resulting type for pick and omit', () => { + const source = { id: 1, name: 'Alice', active: true }; + + const picked = pick(source, ['id'] as const); + const omitted = omit(source, ['active'] as const); + + type Picked = typeof picked; + type Omitted = typeof omitted; + + const expectPicked: Picked = { id: 1 }; + const expectOmitted: Omitted = { id: 1, name: 'Alice' }; + + expect(expectPicked).toStrictEqual({ id: 1 }); + expect(expectOmitted).toStrictEqual({ id: 1, name: 'Alice' }); + }); +}); + diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index 7cefe5d..8239311 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -1,2 +1,3 @@ export * from './hello'; export * from './types'; +export * from './object'; diff --git a/packages/utils/src/object.ts b/packages/utils/src/object.ts new file mode 100644 index 0000000..42c7ccf --- /dev/null +++ b/packages/utils/src/object.ts @@ -0,0 +1,61 @@ +const hasOwn = Object.prototype.hasOwnProperty; + +type AnyRecord = Record; + +/** + * Pick a subset of properties from an object. + * @param source - The source object to pick properties from. + * @param keys - The property keys to include in the resulting object. + */ +export function pick( + source: T | null | undefined, + keys: K, +): Pick { + if (!source) { + return {} as Pick; + } + + if (keys.length === 0) { + return {} as Pick; + } + + const result: Partial> = {}; + + for (const key of keys) { + if (hasOwn.call(source, key)) { + result[key] = source[key]; + } + } + + return result as Pick; +} + +/** + * Omit a subset of properties from an object. + * @param source - The source object to omit properties from. + * @param keys - The property keys to remove from the resulting object. + */ +export function omit( + source: T | null | undefined, + keys: K, +): Omit { + if (!source) { + return {} as Omit; + } + + if (keys.length === 0) { + return { ...source } as Omit; + } + + const keysToOmit = new Set(keys as readonly PropertyKey[]); + const result: Partial> = {}; + + for (const key of Reflect.ownKeys(source) as (keyof T)[]) { + if (!keysToOmit.has(key)) { + result[key] = source[key]; + } + } + + return result as Omit; +} + diff --git a/packages/utils/tsconfig.json b/packages/utils/tsconfig.json index 7572364..b0a58f6 100644 --- a/packages/utils/tsconfig.json +++ b/packages/utils/tsconfig.json @@ -4,6 +4,7 @@ "compilerOptions": { "jsx": "react-jsx", "baseUrl": ".", + "types": ["vitest/globals"], "paths": { "@/utils/*": ["src/*"] } diff --git a/packages/utils/vitest.config.ts b/packages/utils/vitest.config.ts new file mode 100644 index 0000000..67aca16 --- /dev/null +++ b/packages/utils/vitest.config.ts @@ -0,0 +1,18 @@ +import baseConfig from '@rnr/config/vitest/base'; +import { defineConfig, mergeConfig } from 'vitest/config'; + +export default mergeConfig( + baseConfig, + defineConfig({ + test: { + coverage: { + lines: 100, + functions: 100, + statements: 100, + branches: 100, + include: ['src/object.ts'], + }, + }, + }), +); + diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c8f0b53..c595031 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,6 +11,9 @@ importers: .: devDependencies: + '@rnr/config': + specifier: workspace:* + version: link:packages/config prettier: specifier: ^3.6.2 version: 3.6.2 @@ -102,6 +105,9 @@ importers: specifier: ^1.0.7 version: 1.0.7(tailwindcss@3.4.18) devDependencies: + '@rnr/config': + specifier: workspace:* + version: link:../../packages/config '@types/mdx': specifier: ^2.0.13 version: 2.0.13 @@ -242,6 +248,24 @@ importers: specifier: ^5.8.3 version: 5.9.3 + packages/config: + dependencies: + eslint: + specifier: ^8 || ^9 + version: 8.57.1 + eslint-config-next: + specifier: '*' + version: 15.4.5(eslint@8.57.1)(typescript@5.9.3) + prettier: + specifier: ^3 + version: 3.6.2 + prettier-plugin-tailwindcss: + specifier: '*' + version: 0.6.14(prettier@3.6.2) + vitest: + specifier: ^2 + version: 2.1.9(@types/node@22.10.5)(lightningcss@1.27.0)(msw@2.12.0(@types/node@22.10.5)(typescript@5.9.3))(terser@5.44.1) + packages/rnr-ui: dependencies: '@react-navigation/native': @@ -296,18 +320,30 @@ importers: packages/utils: devDependencies: + '@rnr/config': + specifier: workspace:* + version: link:../config '@tsconfig/recommended': specifier: ^1.0.1 version: 1.0.11 + '@types/node': + specifier: ^22.10.1 + version: 22.10.5 '@types/react': specifier: ~19.0.14 version: 19.0.14 + '@vitest/coverage-v8': + specifier: ^2.1.4 + version: 2.1.9(vitest@2.1.9(@types/node@22.10.5)(lightningcss@1.27.0)(msw@2.12.0(@types/node@22.10.5)(typescript@5.9.3))(terser@5.44.1)) react: specifier: 19.0.0 version: 19.0.0 react-native: specifier: 0.79.5 version: 0.79.5(@babel/core@7.28.5)(@types/react@19.0.14)(react@19.0.0) + vitest: + specifier: ^2.1.4 + version: 2.1.9(@types/node@22.10.5)(lightningcss@1.27.0)(msw@2.12.0(@types/node@22.10.5)(typescript@5.9.3))(terser@5.44.1) packages: @@ -323,6 +359,10 @@ packages: resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + '@antfu/ni@23.3.1': resolution: {integrity: sha512-C90iyzm/jLV7Lomv2UzwWUzRv9WZr1oRsFRKsX5HjQL4EXrbi9H/RtBkjCP+NF+ABZXUKpAa4F1dkoTaea4zHg==} hasBin: true @@ -824,6 +864,9 @@ packages: resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} engines: {node: '>=6.9.0'} + '@bcoe/v8-coverage@0.2.3': + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + '@egjs/hammerjs@2.0.17': resolution: {integrity: sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==} engines: {node: '>=0.8.0'} @@ -837,102 +880,204 @@ packages: '@emnapi/wasi-threads@1.1.0': resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + '@esbuild/aix-ppc64@0.25.12': resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm64@0.25.12': resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} engines: {node: '>=18'} cpu: [arm64] os: [android] + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + '@esbuild/android-arm@0.25.12': resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} engines: {node: '>=18'} cpu: [arm] os: [android] + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + '@esbuild/android-x64@0.25.12': resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} engines: {node: '>=18'} cpu: [x64] os: [android] + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-arm64@0.25.12': resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + '@esbuild/darwin-x64@0.25.12': resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} engines: {node: '>=18'} cpu: [x64] os: [darwin] + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-arm64@0.25.12': resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + '@esbuild/freebsd-x64@0.25.12': resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm64@0.25.12': resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} engines: {node: '>=18'} cpu: [arm64] os: [linux] + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + '@esbuild/linux-arm@0.25.12': resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} engines: {node: '>=18'} cpu: [arm] os: [linux] + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-ia32@0.25.12': resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} engines: {node: '>=18'} cpu: [ia32] os: [linux] + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-loong64@0.25.12': resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} engines: {node: '>=18'} cpu: [loong64] os: [linux] + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-mips64el@0.25.12': resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-ppc64@0.25.12': resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-riscv64@0.25.12': resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-s390x@0.25.12': resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} engines: {node: '>=18'} cpu: [s390x] os: [linux] + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + '@esbuild/linux-x64@0.25.12': resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} engines: {node: '>=18'} @@ -945,6 +1090,12 @@ packages: cpu: [arm64] os: [netbsd] + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + '@esbuild/netbsd-x64@0.25.12': resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} engines: {node: '>=18'} @@ -957,6 +1108,12 @@ packages: cpu: [arm64] os: [openbsd] + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + '@esbuild/openbsd-x64@0.25.12': resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} engines: {node: '>=18'} @@ -969,24 +1126,48 @@ packages: cpu: [arm64] os: [openharmony] + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + '@esbuild/sunos-x64@0.25.12': resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} engines: {node: '>=18'} cpu: [x64] os: [sunos] + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-arm64@0.25.12': resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} engines: {node: '>=18'} cpu: [arm64] os: [win32] + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-ia32@0.25.12': resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} engines: {node: '>=18'} cpu: [ia32] os: [win32] + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + '@esbuild/win32-x64@0.25.12': resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} engines: {node: '>=18'} @@ -2126,6 +2307,116 @@ packages: react-native-web: optional: true + '@rollup/rollup-android-arm-eabi@4.52.5': + resolution: {integrity: sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.52.5': + resolution: {integrity: sha512-mQGfsIEFcu21mvqkEKKu2dYmtuSZOBMmAl5CFlPGLY94Vlcm+zWApK7F/eocsNzp8tKmbeBP8yXyAbx0XHsFNA==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.52.5': + resolution: {integrity: sha512-takF3CR71mCAGA+v794QUZ0b6ZSrgJkArC+gUiG6LB6TQty9T0Mqh3m2ImRBOxS2IeYBo4lKWIieSvnEk2OQWA==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.52.5': + resolution: {integrity: sha512-W901Pla8Ya95WpxDn//VF9K9u2JbocwV/v75TE0YIHNTbhqUTv9w4VuQ9MaWlNOkkEfFwkdNhXgcLqPSmHy0fA==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.52.5': + resolution: {integrity: sha512-QofO7i7JycsYOWxe0GFqhLmF6l1TqBswJMvICnRUjqCx8b47MTo46W8AoeQwiokAx3zVryVnxtBMcGcnX12LvA==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.52.5': + resolution: {integrity: sha512-jr21b/99ew8ujZubPo9skbrItHEIE50WdV86cdSoRkKtmWa+DDr6fu2c/xyRT0F/WazZpam6kk7IHBerSL7LDQ==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.52.5': + resolution: {integrity: sha512-PsNAbcyv9CcecAUagQefwX8fQn9LQ4nZkpDboBOttmyffnInRy8R8dSg6hxxl2Re5QhHBf6FYIDhIj5v982ATQ==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.52.5': + resolution: {integrity: sha512-Fw4tysRutyQc/wwkmcyoqFtJhh0u31K+Q6jYjeicsGJJ7bbEq8LwPWV/w0cnzOqR2m694/Af6hpFayLJZkG2VQ==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.52.5': + resolution: {integrity: sha512-a+3wVnAYdQClOTlyapKmyI6BLPAFYs0JM8HRpgYZQO02rMR09ZcV9LbQB+NL6sljzG38869YqThrRnfPMCDtZg==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.52.5': + resolution: {integrity: sha512-AvttBOMwO9Pcuuf7m9PkC1PUIKsfaAJ4AYhy944qeTJgQOqJYJ9oVl2nYgY7Rk0mkbsuOpCAYSs6wLYB2Xiw0Q==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loong64-gnu@4.52.5': + resolution: {integrity: sha512-DkDk8pmXQV2wVrF6oq5tONK6UHLz/XcEVow4JTTerdeV1uqPeHxwcg7aFsfnSm9L+OO8WJsWotKM2JJPMWrQtA==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-ppc64-gnu@4.52.5': + resolution: {integrity: sha512-W/b9ZN/U9+hPQVvlGwjzi+Wy4xdoH2I8EjaCkMvzpI7wJUs8sWJ03Rq96jRnHkSrcHTpQe8h5Tg3ZzUPGauvAw==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.52.5': + resolution: {integrity: sha512-sjQLr9BW7R/ZiXnQiWPkErNfLMkkWIoCz7YMn27HldKsADEKa5WYdobaa1hmN6slu9oWQbB6/jFpJ+P2IkVrmw==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.52.5': + resolution: {integrity: sha512-hq3jU/kGyjXWTvAh2awn8oHroCbrPm8JqM7RUpKjalIRWWXE01CQOf/tUNWNHjmbMHg/hmNCwc/Pz3k1T/j/Lg==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.52.5': + resolution: {integrity: sha512-gn8kHOrku8D4NGHMK1Y7NA7INQTRdVOntt1OCYypZPRt6skGbddska44K8iocdpxHTMMNui5oH4elPH4QOLrFQ==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.52.5': + resolution: {integrity: sha512-hXGLYpdhiNElzN770+H2nlx+jRog8TyynpTVzdlc6bndktjKWyZyiCsuDAlpd+j+W+WNqfcyAWz9HxxIGfZm1Q==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.52.5': + resolution: {integrity: sha512-arCGIcuNKjBoKAXD+y7XomR9gY6Mw7HnFBv5Rw7wQRvwYLR7gBAgV7Mb2QTyjXfTveBNFAtPt46/36vV9STLNg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-openharmony-arm64@4.52.5': + resolution: {integrity: sha512-QoFqB6+/9Rly/RiPjaomPLmR/13cgkIGfA40LHly9zcH1S0bN2HVFYk3a1eAyHQyjs3ZJYlXvIGtcCs5tko9Cw==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.52.5': + resolution: {integrity: sha512-w0cDWVR6MlTstla1cIfOGyl8+qb93FlAVutcor14Gf5Md5ap5ySfQ7R9S/NjNaMLSFdUnKGEasmVnu3lCMqB7w==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.52.5': + resolution: {integrity: sha512-Aufdpzp7DpOTULJCuvzqcItSGDH73pF3ko/f+ckJhxQyHtp67rHw3HMNxoIdDMUITJESNE6a8uh4Lo4SLouOUg==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.52.5': + resolution: {integrity: sha512-UGBUGPFp1vkj6p8wCRraqNhqwX/4kNQPS57BCFc8wYh0g94iVIW33wJtQAx3G7vrjjNtRaxiMUylM0ktp/TRSQ==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.52.5': + resolution: {integrity: sha512-TAcgQh2sSkykPRWLrdyy2AiceMckNf5loITqXxFI5VuQjS5tSuw3WlwdN8qv8vzjLAUTvYaH/mVjSFpbkFbpTg==} + cpu: [x64] + os: [win32] + '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} @@ -2444,6 +2735,44 @@ packages: peerDependencies: '@urql/core': ^5.0.0 + '@vitest/coverage-v8@2.1.9': + resolution: {integrity: sha512-Z2cOr0ksM00MpEfyVE8KXIYPEcBFxdbLSs56L8PO0QQMxt/6bDj45uQfxoc96v05KW3clk7vvgP0qfDit9DmfQ==} + peerDependencies: + '@vitest/browser': 2.1.9 + vitest: 2.1.9 + peerDependenciesMeta: + '@vitest/browser': + optional: true + + '@vitest/expect@2.1.9': + resolution: {integrity: sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==} + + '@vitest/mocker@2.1.9': + resolution: {integrity: sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg==} + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@2.1.9': + resolution: {integrity: sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==} + + '@vitest/runner@2.1.9': + resolution: {integrity: sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==} + + '@vitest/snapshot@2.1.9': + resolution: {integrity: sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==} + + '@vitest/spy@2.1.9': + resolution: {integrity: sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ==} + + '@vitest/utils@2.1.9': + resolution: {integrity: sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==} + '@webassemblyjs/ast@1.14.1': resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} @@ -2663,6 +2992,10 @@ packages: asap@2.0.6: resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + ast-types-flow@0.0.8: resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} @@ -2837,6 +3170,10 @@ packages: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + call-bind-apply-helpers@1.0.2: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} @@ -2883,6 +3220,10 @@ packages: ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + chai@5.3.3: + resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} + engines: {node: '>=18'} + chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} @@ -2907,6 +3248,10 @@ packages: character-reference-invalid@2.0.1: resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + check-error@2.1.1: + resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} + engines: {node: '>= 16'} + chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} @@ -3178,6 +3523,10 @@ packages: resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} engines: {node: '>=0.10'} + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + deep-extend@0.6.0: resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} engines: {node: '>=4.0.0'} @@ -3363,6 +3712,11 @@ packages: esast-util-from-js@2.0.1: resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==} + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + esbuild@0.25.12: resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} engines: {node: '>=18'} @@ -3567,6 +3921,10 @@ packages: resolution: {integrity: sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==} engines: {node: ^14.18.0 || ^16.14.0 || >=18.0.0} + expect-type@1.2.2: + resolution: {integrity: sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==} + engines: {node: '>=12.0.0'} + expo-asset@11.1.7: resolution: {integrity: sha512-b5P8GpjUh08fRCf6m5XPVAh7ra42cQrHBIMgH2UXP+xsj4Wufl6pLy6jRF5w6U7DranUMbsXm8TOyq4EHy7ADg==} peerDependencies: @@ -4060,6 +4418,9 @@ packages: resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} engines: {node: ^16.14.0 || >=18.0.0} + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + html-void-elements@3.0.0: resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} @@ -4335,6 +4696,18 @@ packages: resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} engines: {node: '>=8'} + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-lib-source-maps@5.0.6: + resolution: {integrity: sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==} + engines: {node: '>=10'} + + istanbul-reports@3.2.0: + resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} + engines: {node: '>=8'} + iterator.prototype@1.1.5: resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} engines: {node: '>= 0.4'} @@ -4586,6 +4959,9 @@ packages: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true + loupe@3.2.1: + resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} + lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} @@ -4613,6 +4989,16 @@ packages: peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + magicast@0.3.5: + resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} + + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + makeerror@1.0.12: resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} @@ -5258,6 +5644,13 @@ packages: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + + pathval@2.0.1: + resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} + engines: {node: '>= 14.16'} + performance-now@2.1.0: resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} @@ -5849,6 +6242,11 @@ packages: deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true + rollup@4.52.5: + resolution: {integrity: sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + router@2.2.0: resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} engines: {node: '>= 18'} @@ -5999,6 +6397,9 @@ packages: resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} engines: {node: '>= 0.4'} + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} @@ -6059,6 +6460,9 @@ packages: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + stackframe@1.3.4: resolution: {integrity: sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==} @@ -6078,6 +6482,9 @@ packages: resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} engines: {node: '>= 0.8'} + std-env@3.10.0: + resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + stdin-discarder@0.1.0: resolution: {integrity: sha512-xhV7w8S+bUwlPTb4bAOUQhv8/cSS5offJuX8GQGq32ONF0ZtDWKfkdomM3HMRA+LhX6um/FZ0COqlwsjD53LeQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -6270,6 +6677,10 @@ packages: resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} engines: {node: '>=8'} + test-exclude@7.0.1: + resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==} + engines: {node: '>=18'} + text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} @@ -6286,6 +6697,12 @@ packages: tiny-invariant@1.3.3: resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + tinyexec@1.0.2: resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} engines: {node: '>=18'} @@ -6294,6 +6711,18 @@ packages: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} + tinypool@1.1.1: + resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} + engines: {node: ^18.0.0 || >=20.0.0} + + tinyrainbow@1.2.0: + resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} + engines: {node: '>=14.0.0'} + + tinyspy@3.0.2: + resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} + engines: {node: '>=14.0.0'} + tldts-core@7.0.17: resolution: {integrity: sha512-DieYoGrP78PWKsrXr8MZwtQ7GLCUeLxihtjC1jZsW1DnvSMdKPitJSe8OSYDM2u5H6g3kWJZpePqkp43TfLh0g==} @@ -6571,6 +7000,67 @@ packages: vfile@6.0.3: resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + vite-node@2.1.9: + resolution: {integrity: sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + + vite@5.4.21: + resolution: {integrity: sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: 1.27.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vitest@2.1.9: + resolution: {integrity: sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 2.1.9 + '@vitest/ui': 2.1.9 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + vlq@1.0.1: resolution: {integrity: sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==} @@ -6643,6 +7133,11 @@ packages: engines: {node: '>= 8'} hasBin: true + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + wonka@6.3.5: resolution: {integrity: sha512-SSil+ecw6B4/Dm7Pf2sAshKQ5hWFvfyGlfPbEd6A14dOH6VDjrmbY86u6nZvy9omGwwIPFR8V41+of1EezgoUw==} @@ -6769,6 +7264,11 @@ snapshots: '@alloc/quick-lru@5.2.0': {} + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + '@antfu/ni@23.3.1': {} '@babel/code-frame@7.10.4': @@ -7373,6 +7873,8 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 + '@bcoe/v8-coverage@0.2.3': {} + '@egjs/hammerjs@2.0.17': dependencies: '@types/hammerjs': 2.0.46 @@ -7393,81 +7895,150 @@ snapshots: tslib: 2.8.1 optional: true + '@esbuild/aix-ppc64@0.21.5': + optional: true + '@esbuild/aix-ppc64@0.25.12': optional: true + '@esbuild/android-arm64@0.21.5': + optional: true + '@esbuild/android-arm64@0.25.12': optional: true + '@esbuild/android-arm@0.21.5': + optional: true + '@esbuild/android-arm@0.25.12': optional: true + '@esbuild/android-x64@0.21.5': + optional: true + '@esbuild/android-x64@0.25.12': optional: true + '@esbuild/darwin-arm64@0.21.5': + optional: true + '@esbuild/darwin-arm64@0.25.12': optional: true + '@esbuild/darwin-x64@0.21.5': + optional: true + '@esbuild/darwin-x64@0.25.12': optional: true + '@esbuild/freebsd-arm64@0.21.5': + optional: true + '@esbuild/freebsd-arm64@0.25.12': optional: true + '@esbuild/freebsd-x64@0.21.5': + optional: true + '@esbuild/freebsd-x64@0.25.12': optional: true + '@esbuild/linux-arm64@0.21.5': + optional: true + '@esbuild/linux-arm64@0.25.12': optional: true + '@esbuild/linux-arm@0.21.5': + optional: true + '@esbuild/linux-arm@0.25.12': optional: true + '@esbuild/linux-ia32@0.21.5': + optional: true + '@esbuild/linux-ia32@0.25.12': optional: true + '@esbuild/linux-loong64@0.21.5': + optional: true + '@esbuild/linux-loong64@0.25.12': optional: true + '@esbuild/linux-mips64el@0.21.5': + optional: true + '@esbuild/linux-mips64el@0.25.12': optional: true + '@esbuild/linux-ppc64@0.21.5': + optional: true + '@esbuild/linux-ppc64@0.25.12': optional: true + '@esbuild/linux-riscv64@0.21.5': + optional: true + '@esbuild/linux-riscv64@0.25.12': optional: true + '@esbuild/linux-s390x@0.21.5': + optional: true + '@esbuild/linux-s390x@0.25.12': optional: true + '@esbuild/linux-x64@0.21.5': + optional: true + '@esbuild/linux-x64@0.25.12': optional: true '@esbuild/netbsd-arm64@0.25.12': optional: true + '@esbuild/netbsd-x64@0.21.5': + optional: true + '@esbuild/netbsd-x64@0.25.12': optional: true '@esbuild/openbsd-arm64@0.25.12': optional: true + '@esbuild/openbsd-x64@0.21.5': + optional: true + '@esbuild/openbsd-x64@0.25.12': optional: true '@esbuild/openharmony-arm64@0.25.12': optional: true + '@esbuild/sunos-x64@0.21.5': + optional: true + '@esbuild/sunos-x64@0.25.12': optional: true + '@esbuild/win32-arm64@0.21.5': + optional: true + '@esbuild/win32-arm64@0.25.12': optional: true + '@esbuild/win32-ia32@0.21.5': + optional: true + '@esbuild/win32-ia32@0.25.12': optional: true + '@esbuild/win32-x64@0.21.5': + optional: true + '@esbuild/win32-x64@0.25.12': optional: true @@ -8843,6 +9414,72 @@ snapshots: react-native: 0.79.5(@babel/core@7.28.5)(@types/react@19.0.14)(react@19.0.0) react-native-web: 0.21.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + '@rollup/rollup-android-arm-eabi@4.52.5': + optional: true + + '@rollup/rollup-android-arm64@4.52.5': + optional: true + + '@rollup/rollup-darwin-arm64@4.52.5': + optional: true + + '@rollup/rollup-darwin-x64@4.52.5': + optional: true + + '@rollup/rollup-freebsd-arm64@4.52.5': + optional: true + + '@rollup/rollup-freebsd-x64@4.52.5': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.52.5': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.52.5': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.52.5': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.52.5': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.52.5': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.52.5': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.52.5': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.52.5': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.52.5': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.52.5': + optional: true + + '@rollup/rollup-linux-x64-musl@4.52.5': + optional: true + + '@rollup/rollup-openharmony-arm64@4.52.5': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.52.5': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.52.5': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.52.5': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.52.5': + optional: true + '@rtsao/scc@1.1.0': {} '@rushstack/eslint-patch@1.14.1': {} @@ -9199,6 +9836,65 @@ snapshots: '@urql/core': 5.2.0(graphql@16.12.0) wonka: 6.3.5 + '@vitest/coverage-v8@2.1.9(vitest@2.1.9(@types/node@22.10.5)(lightningcss@1.27.0)(msw@2.12.0(@types/node@22.10.5)(typescript@5.9.3))(terser@5.44.1))': + dependencies: + '@ampproject/remapping': 2.3.0 + '@bcoe/v8-coverage': 0.2.3 + debug: 4.4.3 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 5.0.6 + istanbul-reports: 3.2.0 + magic-string: 0.30.21 + magicast: 0.3.5 + std-env: 3.10.0 + test-exclude: 7.0.1 + tinyrainbow: 1.2.0 + vitest: 2.1.9(@types/node@22.10.5)(lightningcss@1.27.0)(msw@2.12.0(@types/node@22.10.5)(typescript@5.9.3))(terser@5.44.1) + transitivePeerDependencies: + - supports-color + + '@vitest/expect@2.1.9': + dependencies: + '@vitest/spy': 2.1.9 + '@vitest/utils': 2.1.9 + chai: 5.3.3 + tinyrainbow: 1.2.0 + + '@vitest/mocker@2.1.9(msw@2.12.0(@types/node@22.10.5)(typescript@5.9.3))(vite@5.4.21(@types/node@22.10.5)(lightningcss@1.27.0)(terser@5.44.1))': + dependencies: + '@vitest/spy': 2.1.9 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + msw: 2.12.0(@types/node@22.10.5)(typescript@5.9.3) + vite: 5.4.21(@types/node@22.10.5)(lightningcss@1.27.0)(terser@5.44.1) + + '@vitest/pretty-format@2.1.9': + dependencies: + tinyrainbow: 1.2.0 + + '@vitest/runner@2.1.9': + dependencies: + '@vitest/utils': 2.1.9 + pathe: 1.1.2 + + '@vitest/snapshot@2.1.9': + dependencies: + '@vitest/pretty-format': 2.1.9 + magic-string: 0.30.21 + pathe: 1.1.2 + + '@vitest/spy@2.1.9': + dependencies: + tinyspy: 3.0.2 + + '@vitest/utils@2.1.9': + dependencies: + '@vitest/pretty-format': 2.1.9 + loupe: 3.2.1 + tinyrainbow: 1.2.0 + '@webassemblyjs/ast@1.14.1': dependencies: '@webassemblyjs/helper-numbers': 1.13.2 @@ -9456,6 +10152,8 @@ snapshots: asap@2.0.6: {} + assertion-error@2.0.1: {} + ast-types-flow@0.0.8: {} ast-types@0.16.1: @@ -9695,6 +10393,8 @@ snapshots: bytes@3.1.2: {} + cac@6.7.14: {} + call-bind-apply-helpers@1.0.2: dependencies: es-errors: 1.3.0 @@ -9734,6 +10434,14 @@ snapshots: ccount@2.0.1: {} + chai@5.3.3: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.2.1 + pathval: 2.0.1 + chalk@2.4.2: dependencies: ansi-styles: 3.2.1 @@ -9755,6 +10463,8 @@ snapshots: character-reference-invalid@2.0.1: {} + check-error@2.1.1: {} + chokidar@3.6.0: dependencies: anymatch: 3.1.3 @@ -10024,6 +10734,8 @@ snapshots: decode-uri-component@0.2.2: {} + deep-eql@5.0.2: {} + deep-extend@0.6.0: {} deep-is@0.1.4: {} @@ -10261,6 +10973,32 @@ snapshots: esast-util-from-estree: 2.0.0 vfile-message: 4.0.3 + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + esbuild@0.25.12: optionalDependencies: '@esbuild/aix-ppc64': 0.25.12 @@ -10572,6 +11310,8 @@ snapshots: signal-exit: 3.0.7 strip-final-newline: 3.0.0 + expect-type@1.2.2: {} + expo-asset@11.1.7(expo@53.0.23(@babel/core@7.28.5)(@expo/metro-runtime@5.0.5(react-native@0.79.5(@babel/core@7.28.5)(@types/react@19.0.14)(react@19.0.0)))(graphql@16.12.0)(react-native@0.79.5(@babel/core@7.28.5)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0))(react-native@0.79.5(@babel/core@7.28.5)(@types/react@19.0.14)(react@19.0.0))(react@19.0.0): dependencies: '@expo/image-utils': 0.7.6 @@ -11228,6 +11968,8 @@ snapshots: dependencies: lru-cache: 10.4.3 + html-escaper@2.0.2: {} + html-void-elements@3.0.0: {} http-errors@2.0.0: @@ -11488,6 +12230,25 @@ snapshots: transitivePeerDependencies: - supports-color + istanbul-lib-report@3.0.1: + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + + istanbul-lib-source-maps@5.0.6: + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + debug: 4.4.3 + istanbul-lib-coverage: 3.2.2 + transitivePeerDependencies: + - supports-color + + istanbul-reports@3.2.0: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + iterator.prototype@1.1.5: dependencies: define-data-property: 1.1.4 @@ -11747,6 +12508,8 @@ snapshots: dependencies: js-tokens: 4.0.0 + loupe@3.2.1: {} + lru-cache@10.4.3: {} lru-cache@11.2.2: {} @@ -11769,6 +12532,20 @@ snapshots: dependencies: react: 19.0.0 + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + magicast@0.3.5: + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + source-map-js: 1.2.1 + + make-dir@4.0.0: + dependencies: + semver: 7.7.3 + makeerror@1.0.12: dependencies: tmpl: 1.0.5 @@ -12804,6 +13581,10 @@ snapshots: path-type@4.0.0: {} + pathe@1.1.2: {} + + pathval@2.0.1: {} + performance-now@2.1.0: {} picocolors@1.1.1: {} @@ -13435,6 +14216,34 @@ snapshots: dependencies: glob: 7.2.3 + rollup@4.52.5: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.52.5 + '@rollup/rollup-android-arm64': 4.52.5 + '@rollup/rollup-darwin-arm64': 4.52.5 + '@rollup/rollup-darwin-x64': 4.52.5 + '@rollup/rollup-freebsd-arm64': 4.52.5 + '@rollup/rollup-freebsd-x64': 4.52.5 + '@rollup/rollup-linux-arm-gnueabihf': 4.52.5 + '@rollup/rollup-linux-arm-musleabihf': 4.52.5 + '@rollup/rollup-linux-arm64-gnu': 4.52.5 + '@rollup/rollup-linux-arm64-musl': 4.52.5 + '@rollup/rollup-linux-loong64-gnu': 4.52.5 + '@rollup/rollup-linux-ppc64-gnu': 4.52.5 + '@rollup/rollup-linux-riscv64-gnu': 4.52.5 + '@rollup/rollup-linux-riscv64-musl': 4.52.5 + '@rollup/rollup-linux-s390x-gnu': 4.52.5 + '@rollup/rollup-linux-x64-gnu': 4.52.5 + '@rollup/rollup-linux-x64-musl': 4.52.5 + '@rollup/rollup-openharmony-arm64': 4.52.5 + '@rollup/rollup-win32-arm64-msvc': 4.52.5 + '@rollup/rollup-win32-ia32-msvc': 4.52.5 + '@rollup/rollup-win32-x64-gnu': 4.52.5 + '@rollup/rollup-win32-x64-msvc': 4.52.5 + fsevents: 2.3.3 + router@2.2.0: dependencies: debug: 4.4.3 @@ -13717,6 +14526,8 @@ snapshots: side-channel-map: 1.0.1 side-channel-weakmap: 1.0.2 + siginfo@2.0.0: {} + signal-exit@3.0.7: {} signal-exit@4.1.0: {} @@ -13762,6 +14573,8 @@ snapshots: dependencies: escape-string-regexp: 2.0.0 + stackback@0.0.2: {} + stackframe@1.3.4: {} stacktrace-parser@0.1.11: @@ -13774,6 +14587,8 @@ snapshots: statuses@2.0.2: {} + std-env@3.10.0: {} + stdin-discarder@0.1.0: dependencies: bl: 5.1.0 @@ -14007,6 +14822,12 @@ snapshots: glob: 7.2.3 minimatch: 3.1.2 + test-exclude@7.0.1: + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 10.4.5 + minimatch: 9.0.5 + text-table@0.2.0: {} thenify-all@1.6.0: @@ -14021,6 +14842,10 @@ snapshots: tiny-invariant@1.3.3: {} + tinybench@2.9.0: {} + + tinyexec@0.3.2: {} + tinyexec@1.0.2: {} tinyglobby@0.2.15: @@ -14028,6 +14853,12 @@ snapshots: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 + tinypool@1.1.1: {} + + tinyrainbow@1.2.0: {} + + tinyspy@3.0.2: {} + tldts-core@7.0.17: {} tldts@7.0.17: @@ -14312,6 +15143,70 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 + vite-node@2.1.9(@types/node@22.10.5)(lightningcss@1.27.0)(terser@5.44.1): + dependencies: + cac: 6.7.14 + debug: 4.4.3 + es-module-lexer: 1.7.0 + pathe: 1.1.2 + vite: 5.4.21(@types/node@22.10.5)(lightningcss@1.27.0)(terser@5.44.1) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + vite@5.4.21(@types/node@22.10.5)(lightningcss@1.27.0)(terser@5.44.1): + dependencies: + esbuild: 0.21.5 + postcss: 8.5.6 + rollup: 4.52.5 + optionalDependencies: + '@types/node': 22.10.5 + fsevents: 2.3.3 + lightningcss: 1.27.0 + terser: 5.44.1 + + vitest@2.1.9(@types/node@22.10.5)(lightningcss@1.27.0)(msw@2.12.0(@types/node@22.10.5)(typescript@5.9.3))(terser@5.44.1): + dependencies: + '@vitest/expect': 2.1.9 + '@vitest/mocker': 2.1.9(msw@2.12.0(@types/node@22.10.5)(typescript@5.9.3))(vite@5.4.21(@types/node@22.10.5)(lightningcss@1.27.0)(terser@5.44.1)) + '@vitest/pretty-format': 2.1.9 + '@vitest/runner': 2.1.9 + '@vitest/snapshot': 2.1.9 + '@vitest/spy': 2.1.9 + '@vitest/utils': 2.1.9 + chai: 5.3.3 + debug: 4.4.3 + expect-type: 1.2.2 + magic-string: 0.30.21 + pathe: 1.1.2 + std-env: 3.10.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinypool: 1.1.1 + tinyrainbow: 1.2.0 + vite: 5.4.21(@types/node@22.10.5)(lightningcss@1.27.0)(terser@5.44.1) + vite-node: 2.1.9(@types/node@22.10.5)(lightningcss@1.27.0)(terser@5.44.1) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 22.10.5 + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + vlq@1.0.1: {} walker@1.0.8: @@ -14427,6 +15322,11 @@ snapshots: dependencies: isexe: 2.0.0 + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + wonka@6.3.5: {} word-wrap@1.2.5: {} diff --git a/prettier.config.cjs b/prettier.config.cjs new file mode 100644 index 0000000..104e273 --- /dev/null +++ b/prettier.config.cjs @@ -0,0 +1,2 @@ +module.exports = require('@rnr/config/prettier'); + From 4b40698b8337eeed26d1602fa0a2408cc7cd1cac Mon Sep 17 00:00:00 2001 From: peopleinfo <49970466+peopleinfo@users.noreply.github.com> Date: Fri, 7 Nov 2025 11:13:05 +0700 Subject: [PATCH 5/9] up config --- packages/config/eslint/next.cjs | 7 +++--- packages/config/index.js | 3 +-- packages/config/package.json | 39 +++++++++++++++--------------- packages/config/prettier/index.cjs | 19 +++++++-------- packages/config/vitest/base.ts | 25 +++++++++---------- 5 files changed, 44 insertions(+), 49 deletions(-) diff --git a/packages/config/eslint/next.cjs b/packages/config/eslint/next.cjs index d8f1049..045a523 100644 --- a/packages/config/eslint/next.cjs +++ b/packages/config/eslint/next.cjs @@ -1,4 +1,3 @@ -module.exports = { - extends: ['next/core-web-vitals', 'next/typescript'], -}; - +module.exports = { + extends: ['next/core-web-vitals', 'next/typescript'], +}; diff --git a/packages/config/index.js b/packages/config/index.js index cb73d58..cb0ff5c 100644 --- a/packages/config/index.js +++ b/packages/config/index.js @@ -1,2 +1 @@ -export {}; - +export {}; diff --git a/packages/config/package.json b/packages/config/package.json index 48e6028..95b1f17 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -1,20 +1,19 @@ -{ - "name": "@rnr/config", - "version": "0.0.0", - "private": true, - "type": "module", - "main": "./index.js", - "exports": { - "./eslint/next": "./eslint/next.cjs", - "./prettier": "./prettier/index.cjs", - "./vitest/base": "./vitest/base.ts" - }, - "peerDependencies": { - "eslint": "^8 || ^9", - "eslint-config-next": "*", - "prettier": "^3", - "prettier-plugin-tailwindcss": "*", - "vitest": "^2" - } -} - +{ + "name": "@rnr/config", + "version": "0.0.0", + "private": true, + "type": "module", + "main": "./index.js", + "exports": { + "./eslint/next": "./eslint/next.cjs", + "./prettier": "./prettier/index.cjs", + "./vitest/base": "./vitest/base.ts" + }, + "peerDependencies": { + "eslint": "^8 || ^9", + "eslint-config-next": "*", + "prettier": "^3", + "prettier-plugin-tailwindcss": "*", + "vitest": "^2" + } +} diff --git a/packages/config/prettier/index.cjs b/packages/config/prettier/index.cjs index 983e0d5..e9c95c6 100644 --- a/packages/config/prettier/index.cjs +++ b/packages/config/prettier/index.cjs @@ -1,10 +1,9 @@ -/** @type {import('prettier').Config} */ -module.exports = { - arrowParens: 'always', - printWidth: 100, - semi: true, - singleQuote: true, - trailingComma: 'all', - plugins: ['prettier-plugin-tailwindcss'], -}; - +/** @type {import('prettier').Config} */ +module.exports = { + arrowParens: 'always', + printWidth: 100, + semi: true, + singleQuote: true, + trailingComma: 'all', + plugins: ['prettier-plugin-tailwindcss'], +}; diff --git a/packages/config/vitest/base.ts b/packages/config/vitest/base.ts index 19869df..a8165fe 100644 --- a/packages/config/vitest/base.ts +++ b/packages/config/vitest/base.ts @@ -1,13 +1,12 @@ -import { defineConfig } from 'vitest/config'; - -export const vitestBaseConfig = defineConfig({ - test: { - coverage: { - provider: 'v8', - reporter: ['text', 'lcov'], - }, - }, -}); - -export default vitestBaseConfig; - +import { defineConfig } from 'vitest/config'; + +export const vitestBaseConfig = defineConfig({ + test: { + coverage: { + provider: 'v8', + reporter: ['text', 'lcov'], + }, + }, +}); + +export default vitestBaseConfig; From 38fb711eb99bbf0b5d92f083195a9563c51af26d Mon Sep 17 00:00:00 2001 From: peopleinfo <49970466+peopleinfo@users.noreply.github.com> Date: Fri, 7 Nov 2025 11:43:26 +0700 Subject: [PATCH 6/9] up deps --- apps/docs/package.json | 2 +- package.json | 1 + packages/config/package.json | 2 +- .../utils/coverage/lcov-report/index.html | 2 +- .../utils/coverage/lcov-report/object.ts.html | 2 +- pnpm-lock.yaml | 310 ++++++++++-------- 6 files changed, 171 insertions(+), 148 deletions(-) diff --git a/apps/docs/package.json b/apps/docs/package.json index b539390..6b7095c 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -44,7 +44,7 @@ "@types/react": "19.0.14", "@types/react-dom": "19.1.5", "autoprefixer": "^10.4.20", - "eslint": "^8", + "eslint": "^9.39.1", "eslint-config-next": "15.4.5", "postcss": "^8.4.49", "raw-loader": "^4.0.2", diff --git a/package.json b/package.json index 3db0463..9205bc7 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ }, "devDependencies": { "@rnr/config": "workspace:*", + "eslint": "^9.39.1", "prettier": "^3.6.2", "prettier-plugin-tailwindcss": "^0.6.14", "turbo": "^2.6.0", diff --git a/packages/config/package.json b/packages/config/package.json index 95b1f17..2068e66 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -10,7 +10,7 @@ "./vitest/base": "./vitest/base.ts" }, "peerDependencies": { - "eslint": "^8 || ^9", + "eslint": "^9", "eslint-config-next": "*", "prettier": "^3", "prettier-plugin-tailwindcss": "*", diff --git a/packages/utils/coverage/lcov-report/index.html b/packages/utils/coverage/lcov-report/index.html index 6ea78c9..01fc9eb 100644 --- a/packages/utils/coverage/lcov-report/index.html +++ b/packages/utils/coverage/lcov-report/index.html @@ -101,7 +101,7 @@

All files

- - - - - - \ No newline at end of file diff --git a/packages/utils/coverage/lcov-report/object.ts.html b/packages/utils/coverage/lcov-report/object.ts.html deleted file mode 100644 index 9332932..0000000 --- a/packages/utils/coverage/lcov-report/object.ts.html +++ /dev/null @@ -1,268 +0,0 @@ - - - - - - Code coverage report for object.ts - - - - - - - - - -
-
-

All files object.ts

-
- -
- 100% - Statements - 38/38 -
- - -
- 100% - Branches - 16/16 -
- - -
- 100% - Functions - 2/2 -
- - -
- 100% - Lines - 38/38 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -621x -  -  -  -  -  -  -  -  -1x -6x -6x -6x -6x -2x -2x -  -6x -1x -1x -  -3x -  -6x -5x -4x -4x -5x -  -3x -3x -  -  -  -  -  -  -1x -7x -7x -7x -7x -2x -2x -  -7x -1x -1x -  -4x -4x -  -7x -10x -6x -6x -10x -  -4x -4x -  - 
const hasOwn = Object.prototype.hasOwnProperty;
- 
-type AnyRecord = Record<PropertyKey, unknown>;
- 
-/**
- * Pick a subset of properties from an object.
- * @param source - The source object to pick properties from.
- * @param keys - The property keys to include in the resulting object.
- */
-export function pick<T extends AnyRecord, const K extends readonly (keyof T)[] | []>(
-  source: T | null | undefined,
-  keys: K,
-): Pick<T, K[number]> {
-  if (!source) {
-    return {} as Pick<T, K[number]>;
-  }
- 
-  if (keys.length === 0) {
-    return {} as Pick<T, K[number]>;
-  }
- 
-  const result: Partial<Pick<T, K[number]>> = {};
- 
-  for (const key of keys) {
-    if (hasOwn.call(source, key)) {
-      result[key] = source[key];
-    }
-  }
- 
-  return result as Pick<T, K[number]>;
-}
- 
-/**
- * Omit a subset of properties from an object.
- * @param source - The source object to omit properties from.
- * @param keys - The property keys to remove from the resulting object.
- */
-export function omit<T extends AnyRecord, const K extends readonly (keyof T)[] | []>(
-  source: T | null | undefined,
-  keys: K,
-): Omit<T, K[number]> {
-  if (!source) {
-    return {} as Omit<T, K[number]>;
-  }
- 
-  if (keys.length === 0) {
-    return { ...source } as Omit<T, K[number]>;
-  }
- 
-  const keysToOmit = new Set<PropertyKey>(keys as readonly PropertyKey[]);
-  const result: Partial<Omit<T, K[number]>> = {};
- 
-  for (const key of Reflect.ownKeys(source) as (keyof T)[]) {
-    if (!keysToOmit.has(key)) {
-      result[key] = source[key];
-    }
-  }
- 
-  return result as Omit<T, K[number]>;
-}
- 
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/packages/utils/coverage/lcov-report/prettify.css b/packages/utils/coverage/lcov-report/prettify.css deleted file mode 100644 index b317a7c..0000000 --- a/packages/utils/coverage/lcov-report/prettify.css +++ /dev/null @@ -1 +0,0 @@ -.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} diff --git a/packages/utils/coverage/lcov-report/prettify.js b/packages/utils/coverage/lcov-report/prettify.js deleted file mode 100644 index b322523..0000000 --- a/packages/utils/coverage/lcov-report/prettify.js +++ /dev/null @@ -1,2 +0,0 @@ -/* eslint-disable */ -window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;arat[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); diff --git a/packages/utils/coverage/lcov-report/sort-arrow-sprite.png b/packages/utils/coverage/lcov-report/sort-arrow-sprite.png deleted file mode 100644 index 6ed68316eb3f65dec9063332d2f69bf3093bbfab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 138 zcmeAS@N?(olHy`uVBq!ia0vp^>_9Bd!3HEZxJ@+%Qh}Z>jv*C{$p!i!8j}?a+@3A= zIAGwzjijN=FBi!|L1t?LM;Q;gkwn>2cAy-KV{dn nf0J1DIvEHQu*n~6U}x}qyky7vi4|9XhBJ7&`njxgN@xNA8m%nc diff --git a/packages/utils/coverage/lcov-report/sorter.js b/packages/utils/coverage/lcov-report/sorter.js deleted file mode 100644 index 4ed70ae..0000000 --- a/packages/utils/coverage/lcov-report/sorter.js +++ /dev/null @@ -1,210 +0,0 @@ -/* eslint-disable */ -var addSorting = (function() { - 'use strict'; - var cols, - currentSort = { - index: 0, - desc: false - }; - - // returns the summary table element - function getTable() { - return document.querySelector('.coverage-summary'); - } - // returns the thead element of the summary table - function getTableHeader() { - return getTable().querySelector('thead tr'); - } - // returns the tbody element of the summary table - function getTableBody() { - return getTable().querySelector('tbody'); - } - // returns the th element for nth column - function getNthColumn(n) { - return getTableHeader().querySelectorAll('th')[n]; - } - - function onFilterInput() { - const searchValue = document.getElementById('fileSearch').value; - const rows = document.getElementsByTagName('tbody')[0].children; - - // Try to create a RegExp from the searchValue. If it fails (invalid regex), - // it will be treated as a plain text search - let searchRegex; - try { - searchRegex = new RegExp(searchValue, 'i'); // 'i' for case-insensitive - } catch (error) { - searchRegex = null; - } - - for (let i = 0; i < rows.length; i++) { - const row = rows[i]; - let isMatch = false; - - if (searchRegex) { - // If a valid regex was created, use it for matching - isMatch = searchRegex.test(row.textContent); - } else { - // Otherwise, fall back to the original plain text search - isMatch = row.textContent - .toLowerCase() - .includes(searchValue.toLowerCase()); - } - - row.style.display = isMatch ? '' : 'none'; - } - } - - // loads the search box - function addSearchBox() { - var template = document.getElementById('filterTemplate'); - var templateClone = template.content.cloneNode(true); - templateClone.getElementById('fileSearch').oninput = onFilterInput; - template.parentElement.appendChild(templateClone); - } - - // loads all columns - function loadColumns() { - var colNodes = getTableHeader().querySelectorAll('th'), - colNode, - cols = [], - col, - i; - - for (i = 0; i < colNodes.length; i += 1) { - colNode = colNodes[i]; - col = { - key: colNode.getAttribute('data-col'), - sortable: !colNode.getAttribute('data-nosort'), - type: colNode.getAttribute('data-type') || 'string' - }; - cols.push(col); - if (col.sortable) { - col.defaultDescSort = col.type === 'number'; - colNode.innerHTML = - colNode.innerHTML + ''; - } - } - return cols; - } - // attaches a data attribute to every tr element with an object - // of data values keyed by column name - function loadRowData(tableRow) { - var tableCols = tableRow.querySelectorAll('td'), - colNode, - col, - data = {}, - i, - val; - for (i = 0; i < tableCols.length; i += 1) { - colNode = tableCols[i]; - col = cols[i]; - val = colNode.getAttribute('data-value'); - if (col.type === 'number') { - val = Number(val); - } - data[col.key] = val; - } - return data; - } - // loads all row data - function loadData() { - var rows = getTableBody().querySelectorAll('tr'), - i; - - for (i = 0; i < rows.length; i += 1) { - rows[i].data = loadRowData(rows[i]); - } - } - // sorts the table using the data for the ith column - function sortByIndex(index, desc) { - var key = cols[index].key, - sorter = function(a, b) { - a = a.data[key]; - b = b.data[key]; - return a < b ? -1 : a > b ? 1 : 0; - }, - finalSorter = sorter, - tableBody = document.querySelector('.coverage-summary tbody'), - rowNodes = tableBody.querySelectorAll('tr'), - rows = [], - i; - - if (desc) { - finalSorter = function(a, b) { - return -1 * sorter(a, b); - }; - } - - for (i = 0; i < rowNodes.length; i += 1) { - rows.push(rowNodes[i]); - tableBody.removeChild(rowNodes[i]); - } - - rows.sort(finalSorter); - - for (i = 0; i < rows.length; i += 1) { - tableBody.appendChild(rows[i]); - } - } - // removes sort indicators for current column being sorted - function removeSortIndicators() { - var col = getNthColumn(currentSort.index), - cls = col.className; - - cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); - col.className = cls; - } - // adds sort indicators for current column being sorted - function addSortIndicators() { - getNthColumn(currentSort.index).className += currentSort.desc - ? ' sorted-desc' - : ' sorted'; - } - // adds event listeners for all sorter widgets - function enableUI() { - var i, - el, - ithSorter = function ithSorter(i) { - var col = cols[i]; - - return function() { - var desc = col.defaultDescSort; - - if (currentSort.index === i) { - desc = !currentSort.desc; - } - sortByIndex(i, desc); - removeSortIndicators(); - currentSort.index = i; - currentSort.desc = desc; - addSortIndicators(); - }; - }; - for (i = 0; i < cols.length; i += 1) { - if (cols[i].sortable) { - // add the click event handler on the th so users - // dont have to click on those tiny arrows - el = getNthColumn(i).querySelector('.sorter').parentElement; - if (el.addEventListener) { - el.addEventListener('click', ithSorter(i)); - } else { - el.attachEvent('onclick', ithSorter(i)); - } - } - } - } - // adds sorting functionality to the UI - return function() { - if (!getTable()) { - return; - } - cols = loadColumns(); - loadData(); - addSearchBox(); - addSortIndicators(); - enableUI(); - }; -})(); - -window.addEventListener('load', addSorting); diff --git a/packages/utils/coverage/lcov.info b/packages/utils/coverage/lcov.info deleted file mode 100644 index 3e084a9..0000000 --- a/packages/utils/coverage/lcov.info +++ /dev/null @@ -1,67 +0,0 @@ -TN: -SF:src\object.ts -FN:10,pick -FN:38,omit -FNF:2 -FNH:2 -FNDA:6,pick -FNDA:7,omit -DA:1,1 -DA:10,1 -DA:11,6 -DA:12,6 -DA:13,6 -DA:14,6 -DA:15,2 -DA:16,2 -DA:18,6 -DA:19,1 -DA:20,1 -DA:22,3 -DA:24,6 -DA:25,5 -DA:26,4 -DA:27,4 -DA:28,5 -DA:30,3 -DA:31,3 -DA:38,1 -DA:39,7 -DA:40,7 -DA:41,7 -DA:42,7 -DA:43,2 -DA:44,2 -DA:46,7 -DA:47,1 -DA:48,1 -DA:50,4 -DA:51,4 -DA:53,7 -DA:54,10 -DA:55,6 -DA:56,6 -DA:57,10 -DA:59,4 -DA:60,4 -LF:38 -LH:38 -BRDA:10,0,0,6 -BRDA:14,1,0,2 -BRDA:16,2,0,4 -BRDA:18,3,0,1 -BRDA:20,4,0,3 -BRDA:24,5,0,5 -BRDA:25,6,0,4 -BRDA:28,7,0,3 -BRDA:38,8,0,7 -BRDA:42,9,0,2 -BRDA:44,10,0,5 -BRDA:46,11,0,1 -BRDA:48,12,0,4 -BRDA:53,13,0,10 -BRDA:54,14,0,6 -BRDA:57,15,0,4 -BRF:16 -BRH:16 -end_of_record diff --git a/packages/utils/src/object.ts b/packages/utils/src/object.ts index 42c7ccf..f82ebe6 100644 --- a/packages/utils/src/object.ts +++ b/packages/utils/src/object.ts @@ -11,17 +11,14 @@ export function pick { - if (!source) { - return {} as Pick; - } + const result: Partial> = {}; - if (keys.length === 0) { - return {} as Pick; + if (!source) { + return result as Pick; } - const result: Partial> = {}; - - for (const key of keys) { + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; if (hasOwn.call(source, key)) { result[key] = source[key]; } @@ -43,19 +40,42 @@ export function omit; } - if (keys.length === 0) { + const keysLen = keys.length; + + // For 0-3 keys, direct comparison is faster than Set + if (keysLen === 0) { return { ...source } as Omit; } - const keysToOmit = new Set(keys as readonly PropertyKey[]); - const result: Partial> = {}; + const result: Partial = {}; - for (const key of Reflect.ownKeys(source) as (keyof T)[]) { - if (!keysToOmit.has(key)) { - result[key] = source[key]; + if (keysLen <= 3) { + // Fast path for small omit lists + const sourceKeys = Reflect.ownKeys(source) as (keyof T)[]; + for (let i = 0; i < sourceKeys.length; i++) { + const key = sourceKeys[i]; + let shouldOmit = false; + for (let j = 0; j < keysLen; j++) { + if (key === keys[j]) { + shouldOmit = true; + break; + } + } + if (!shouldOmit) { + result[key] = source[key]; + } + } + } else { + // Set is faster for larger omit lists + const keysToOmit = new Set(keys as readonly PropertyKey[]); + const sourceKeys = Reflect.ownKeys(source) as (keyof T)[]; + for (let i = 0; i < sourceKeys.length; i++) { + const key = sourceKeys[i]; + if (!keysToOmit.has(key)) { + result[key] = source[key]; + } } } return result as Omit; -} - +} \ No newline at end of file From 2ca833aaef367a3d7523fa76b05ef3270ddae0f3 Mon Sep 17 00:00:00 2001 From: peopleinfo <49970466+peopleinfo@users.noreply.github.com> Date: Fri, 7 Nov 2025 18:06:51 +0700 Subject: [PATCH 9/9] Update .gitignore, enhance utility components, and add playgrounds for interactive demos --- .gitignore | 1 + apps/docs/components/utils.tsx | 426 +++++++++++++++++--- apps/docs/content/docs/utils/hello-util.mdx | 2 + apps/docs/content/docs/utils/object.mdx | 8 + apps/docs/next.config.mjs | 1 + 5 files changed, 389 insertions(+), 49 deletions(-) diff --git a/.gitignore b/.gitignore index a5e18ac..8cc3d36 100644 --- a/.gitignore +++ b/.gitignore @@ -62,3 +62,4 @@ xcuserdata # VSCode .history/ +/coverage \ No newline at end of file diff --git a/apps/docs/components/utils.tsx b/apps/docs/components/utils.tsx index e718d70..7589658 100644 --- a/apps/docs/components/utils.tsx +++ b/apps/docs/components/utils.tsx @@ -1,65 +1,181 @@ 'use client'; -import { hello, helloAsync } from '@rnr/utils'; -import { useEffect, useState } from 'react'; -import { Text, View, Button } from 'react-native'; +import { hello, helloAsync, omit, pick } from '@rnr/utils'; +import type { ComponentProps, ReactNode } from 'react'; +import { useCallback, useEffect, useMemo, useState } from 'react'; +import { Button, Modal, Pressable, ScrollView, Text, TextInput, View } from 'react-native'; +import { Button as DocsButton } from './ui/button'; +import { Form } from '@/rnr-ui/components/ui/forms'; + +type BaseUtilityPlaygroundRenderProps = { + close: () => void; +}; + +type BaseUtilityPlaygroundProps = { + title: string; + description?: string; + triggerText: string; + triggerIcon?: ReactNode; + triggerVariant?: ComponentProps['variant']; + onOpen?: () => void; + children: ReactNode | ((helpers: BaseUtilityPlaygroundRenderProps) => ReactNode); +}; + +export function BaseUtilityPlayground({ + title, + description, + triggerText, + triggerIcon, + triggerVariant = 'outline', + onOpen, + children, +}: BaseUtilityPlaygroundProps) { + const [isOpen, setIsOpen] = useState(false); + + const closeModal = useCallback(() => { + setIsOpen(false); + }, []); + + const openModal = useCallback(() => { + setIsOpen(true); + onOpen?.(); + }, [onOpen]); + + const content = useMemo(() => { + return typeof children === 'function' ? children({ close: closeModal }) : children; + }, [children, closeModal]); + + return ( + <> + + {triggerIcon} + {triggerText} + + + + + event.stopPropagation()}> + + + + {triggerIcon} + {title} + + + Close + + + + + + {description ? ( + {description} + ) : null} + {content} + + + + + + + + ); +} + +const defaultHelloName = 'React Native'; export function HelloDemo() { - const [syncResult, setSyncResult] = useState(''); + const [name, setName] = useState(defaultHelloName); + const [syncResult, setSyncResult] = useState(() => hello(defaultHelloName)); const [asyncResult, setAsyncResult] = useState(''); const [loading, setLoading] = useState(false); - const runSyncExample = () => { - const result = hello('React Native'); - setSyncResult(result); - }; + const updateSyncResult = useCallback((value: string) => { + setSyncResult(hello(value)); + }, []); - const runAsyncExample = async () => { + const updateAsyncResult = useCallback(async (value: string) => { setLoading(true); - const result = await helloAsync('Developer'); - setAsyncResult(result); - setLoading(false); - }; + try { + const response = await helloAsync(value); + setAsyncResult(response); + } finally { + setLoading(false); + } + }, []); useEffect(() => { - runSyncExample(); - }, []); + updateSyncResult(defaultHelloName); + void updateAsyncResult(defaultHelloName); + }, [updateAsyncResult, updateSyncResult]); + + const handleRun = useCallback(() => { + const target = name.trim() || 'World'; + updateSyncResult(target); + void updateAsyncResult(target); + }, [name, updateAsyncResult, updateSyncResult]); + + const handleReset = useCallback(() => { + setName(defaultHelloName); + updateSyncResult(defaultHelloName); + void updateAsyncResult(defaultHelloName); + }, [updateAsyncResult, updateSyncResult]); return ( - - - - Synchronous Example: - - - - Input: hello('React Native') - - - Output: "{syncResult}" - - -