Skip to content

Commit

Permalink
fix: corrected externalErrors behaviour
Browse files Browse the repository at this point in the history
  • Loading branch information
victorgarciaesgi committed Nov 4, 2024
1 parent d0023c1 commit 9373d97
Show file tree
Hide file tree
Showing 27 changed files with 1,948 additions and 46 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ lib
.output
.DS_Store

docs/.vitepress/dist
docs/.vitepress/cache

# Coverage directory used by tools like istanbul
coverage
*.lcov
Expand Down
30 changes: 30 additions & 0 deletions docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { DefaultTheme, defineConfig } from 'vitepress';
import { transformerTwoslash } from '@shikijs/vitepress-twoslash';

const GUIDES: DefaultTheme.NavItemWithLink[] = [
{ text: 'Getting Started', link: '/guide/' },
{ text: 'Installation & Usage', link: '/guide/install' },
];

export default defineConfig({
title: 'Regle',
description: 'A reactive and declarative vue form library',
head: [['link', { rel: 'icon', href: '/favicon.ico' }]],
themeConfig: {
logo: '../../assets/logo.png',
nav: GUIDES,
search: {
provider: 'local',
},
sidebar: [
{
text: 'Guide',
items: GUIDES,
},
],
socialLinks: [{ icon: 'github', link: 'https://github.com/victorgarciaesgi/regle' }],
},
markdown: {
codeTransformers: [transformerTwoslash()],
},
});
5 changes: 5 additions & 0 deletions docs/.vitepress/theme/custom.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
:root {
--vp-c-brand-1: #4dd16b;
--vp-c-brand-2: #99cccc;
--vp-c-brand-3: rgb(33, 123, 55);
}
18 changes: 18 additions & 0 deletions docs/.vitepress/theme/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { h } from 'vue';
import type { Theme } from 'vitepress';
import DefaultTheme from 'vitepress/theme';
import './style.css';
import './custom.css';
import '@shikijs/vitepress-twoslash/style.css';
import TwoslashFloatingVue from '@shikijs/vitepress-twoslash/client';
import type { EnhanceAppContext } from 'vitepress';

export default {
extends: DefaultTheme,
Layout: () => {
return h(DefaultTheme.Layout, null, {});
},
enhanceApp({ app }: EnhanceAppContext) {
app.use(TwoslashFloatingVue as any);
},
} satisfies Theme;
139 changes: 139 additions & 0 deletions docs/.vitepress/theme/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/**
* Customize default theme styling by overriding CSS variables:
* https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css
*/

/**
* Colors
*
* Each colors have exact same color scale system with 3 levels of solid
* colors with different brightness, and 1 soft color.
*
* - `XXX-1`: The most solid color used mainly for colored text. It must
* satisfy the contrast ratio against when used on top of `XXX-soft`.
*
* - `XXX-2`: The color used mainly for hover state of the button.
*
* - `XXX-3`: The color for solid background, such as bg color of the button.
* It must satisfy the contrast ratio with pure white (#ffffff) text on
* top of it.
*
* - `XXX-soft`: The color used for subtle background such as custom container
* or badges. It must satisfy the contrast ratio when putting `XXX-1` colors
* on top of it.
*
* The soft color must be semi transparent alpha channel. This is crucial
* because it allows adding multiple "soft" colors on top of each other
* to create a accent, such as when having inline code block inside
* custom containers.
*
* - `default`: The color used purely for subtle indication without any
* special meanings attched to it such as bg color for menu hover state.
*
* - `brand`: Used for primary brand colors, such as link text, button with
* brand theme, etc.
*
* - `tip`: Used to indicate useful information. The default theme uses the
* brand color for this by default.
*
* - `warning`: Used to indicate warning to the users. Used in custom
* container, badges, etc.
*
* - `danger`: Used to show error, or dangerous message to the users. Used
* in custom container, badges, etc.
* -------------------------------------------------------------------------- */

:root {
--vp-c-default-1: var(--vp-c-gray-1);
--vp-c-default-2: var(--vp-c-gray-2);
--vp-c-default-3: var(--vp-c-gray-3);
--vp-c-default-soft: var(--vp-c-gray-soft);

--vp-c-brand-1: var(--vp-c-indigo-1);
--vp-c-brand-2: var(--vp-c-indigo-2);
--vp-c-brand-3: var(--vp-c-indigo-3);
--vp-c-brand-soft: var(--vp-c-indigo-soft);

--vp-c-tip-1: var(--vp-c-brand-1);
--vp-c-tip-2: var(--vp-c-brand-2);
--vp-c-tip-3: var(--vp-c-brand-3);
--vp-c-tip-soft: var(--vp-c-brand-soft);

--vp-c-warning-1: var(--vp-c-yellow-1);
--vp-c-warning-2: var(--vp-c-yellow-2);
--vp-c-warning-3: var(--vp-c-yellow-3);
--vp-c-warning-soft: var(--vp-c-yellow-soft);

--vp-c-danger-1: var(--vp-c-red-1);
--vp-c-danger-2: var(--vp-c-red-2);
--vp-c-danger-3: var(--vp-c-red-3);
--vp-c-danger-soft: var(--vp-c-red-soft);
}

/**
* Component: Button
* -------------------------------------------------------------------------- */

:root {
--vp-button-brand-border: transparent;
--vp-button-brand-text: var(--vp-c-white);
--vp-button-brand-bg: var(--vp-c-brand-3);
--vp-button-brand-hover-border: transparent;
--vp-button-brand-hover-text: var(--vp-c-white);
--vp-button-brand-hover-bg: var(--vp-c-brand-2);
--vp-button-brand-active-border: transparent;
--vp-button-brand-active-text: var(--vp-c-white);
--vp-button-brand-active-bg: var(--vp-c-brand-1);
}

/**
* Component: Home
* -------------------------------------------------------------------------- */

:root {
--vp-home-hero-name-color: transparent;
--vp-home-hero-name-background: -webkit-linear-gradient(
120deg,
var(--vp-c-brand-1) 30%,
var(--vp-c-brand-2)
);

--vp-home-hero-image-background-image: linear-gradient(
-45deg,
var(--vp-c-brand-1) 50%,
var(--vp-c-brand-2) 50%
);
--vp-home-hero-image-filter: blur(44px);
}

@media (min-width: 640px) {
:root {
--vp-home-hero-image-filter: blur(56px);
}
}

@media (min-width: 960px) {
:root {
--vp-home-hero-image-filter: blur(68px);
}
}

/**
* Component: Custom Block
* -------------------------------------------------------------------------- */

:root {
--vp-custom-block-tip-border: transparent;
--vp-custom-block-tip-text: var(--vp-c-text-1);
--vp-custom-block-tip-bg: var(--vp-c-brand-soft);
--vp-custom-block-tip-code-bg: var(--vp-c-brand-soft);
}

/**
* Component: Algolia
* -------------------------------------------------------------------------- */

.DocSearch {
--docsearch-primary-color: var(--vp-c-brand-1) !important;
}

Binary file added docs/assets/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions docs/examples/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
title: Examples

---
28 changes: 28 additions & 0 deletions docs/guide/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@

# Introduction

Regle (French word for "rule") is a Typescript first form validation library made for Vue 3.
I'm a lover and long-time user of Vuelidate API, so Regle's one will be greatly inspired.


# Installation

::: code-group

```sh [pnpm]
pnpm add -D @regle/core @regle/validators
```

```sh [npm]
npm install -D @regle/core @regle/validators
```

```sh [yarn]
yarn add -D @regle/core @regle/validators
```

```sh [bun]
bun add -D @regle/core @regle/validators
```

:::
27 changes: 27 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
# https://vitepress.dev/reference/default-theme-home-page
layout: home

hero:
name: "Regle"
text: "TS first model-based validation library for Vue 3"
image:
src: ./assets/logo.png
alt: Regle
actions:
- theme: brand
text: Get Started
link: /guide
- theme: alt
text: Examples
link: /examples

features:
- title: Type safe
details: Lorem ipsum dolor sit amet, consectetur adipiscing elit
- title: Model based
details: Lorem ipsum dolor sit amet, consectetur adipiscing elit
- title: Zod compatible
details: Lorem ipsum dolor sit amet, consectetur adipiscing elit
---

Binary file added docs/public/favicon.ico
Binary file not shown.
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,21 @@
"test:dev": "vitest",
"release": "nr build && bumpp -r && pnpm run -r --filter='@regle/*' release && git push --follow-tags",
"play:vue3": "cd playground/vue3 && pnpm run dev",
"play:nuxt": "cd playground/nuxt && pnpm run dev"
"play:nuxt": "cd playground/nuxt && pnpm run dev",
"docs:dev": "vitepress dev docs",
"docs:build": "vitepress build docs",
"docs:preview": "vitepress preview docs"
},
"devDependencies": {
"@regle/core": "workspace:*",
"@regle/validators": "workspace:*",
"@regle/zod": "workspace:*",
"@types/prettier": "3.0.0",
"@typescript-eslint/eslint-plugin": "8.4.0",
"@typescript-eslint/parser": "8.4.0",
"@vitejs/plugin-vue": "5.1.3",
"@vitest/coverage-istanbul": "2.0.5",
"@vitest/coverage-v8": "2.0.5",
"@shikijs/vitepress-twoslash": "1.18.0",
"@vue/reactivity": "3.5.0",
"@vue/test-utils": "2.4.6",
"bumpp": "9.5.2",
Expand All @@ -38,6 +41,7 @@
"prettier": "3.3.3",
"typescript": "5.5.4",
"vitest": "2.0.5",
"vitepress": "1.3.4",
"vue": "3.5.0",
"vue-eslint-parser": "9.4.3",
"vue-tsc": "2.1.4"
Expand Down
17 changes: 17 additions & 0 deletions packages/core/src/core/useRegle/guards/rule.status.guards.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import type {
$InternalExternalRegleErrors,
$InternalRegleCollectionStatus,
$InternalRegleFieldStatus,
$InternalRegleRuleStatus,
$InternalRegleStatus,
$InternalRegleStatusType,
RegleExternalCollectionErrors,
RegleExternalErrorTree,
} from '../../../types';
import { isObject } from '../../../utils';

Expand All @@ -24,3 +27,17 @@ export function isFieldStatus(rule: $InternalRegleStatusType): rule is $Internal
export function isRuleStatus(rule: unknown): rule is $InternalRegleRuleStatus {
return isObject(rule) && '$type' in rule && '$message' in rule;
}

// -- ExternalErrors

export function isNestedExternalErrorStatus(
rule: $InternalExternalRegleErrors
): rule is RegleExternalErrorTree<any> {
return !!rule && '$each' in rule;
}

export function isCollectionExternalErrorStatus(
rule: $InternalExternalRegleErrors
): rule is RegleExternalCollectionErrors<any> {
return !!rule && '$each' in rule;
}
12 changes: 10 additions & 2 deletions packages/core/src/core/useRegle/useErrors.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
import { Ref, computed } from 'vue';
import { ComputedRef, Ref, computed } from 'vue';
import type {
$InternalRegleErrors,
$InternalRegleStatusType,
$InternalRegleStatus,
$InternalRegleRuleStatus,
$InternalRegleCollectionStatus,
$InternalExternalRegleErrors,
} from '../../types';
import { isCollectionRulesStatus, isFieldStatus, isNestedRulesStatus } from './guards';
import {
isCollectionExternalErrorStatus,
isCollectionRulesStatus,
isFieldStatus,
isNestedExternalErrorStatus,
isNestedRulesStatus,
} from './guards';
import { isObject } from '../../utils';

function extractRulesErrors(
rules: Record<string, $InternalRegleRuleStatus>,
Expand Down
7 changes: 5 additions & 2 deletions packages/core/src/core/useRegle/useRegle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import type {
Regle,
RegleBehaviourOptions,
RegleErrorTree,
RegleExternalErrorTree,
ReglePartialValidationTree,
RegleStatus,
ResolvedRegleBehaviourOptions,
Expand All @@ -31,6 +32,7 @@ export function createUseRegleComposable<TCustomRules extends Partial<AllRulesDe
function useRegle<
TState extends Record<string, any>,
TRules extends ReglePartialValidationTree<TState, Partial<AllRulesDeclarations> & TCustomRules>,
TExternal extends RegleExternalErrorTree<TState>,
TValid = keyof TRules extends keyof ReglePartialValidationTree<
TState,
Partial<AllRulesDeclarations> & TCustomRules
Expand All @@ -40,8 +42,9 @@ export function createUseRegleComposable<TCustomRules extends Partial<AllRulesDe
>(
state: Ref<TState> | DeepReactiveState<TState>,
rulesFactory: TValid extends true ? TRules | (() => TRules) | ComputedRef<TRules> : never,
options?: Partial<DeepMaybeRef<RegleBehaviourOptions>> & LocalRegleBehaviourOptions<TState>
): Regle<TState, TRules> {
options?: Partial<DeepMaybeRef<RegleBehaviourOptions>> &
LocalRegleBehaviourOptions<TState, TExternal>
): Regle<TState, TRules, TExternal> {
const scopeRules = isRef(rulesFactory)
? rulesFactory
: computed(
Expand Down
Loading

0 comments on commit 9373d97

Please sign in to comment.