feat(smart-app): implement complete mobile app MVP

- App.tsx: full navigation (Auth stack + Main tabs with 5 screens)
- Auth: LoginScreen, RegisterScreen, ForgotPasswordScreen
- HomeScreen: dashboard with IoT metrics, weather widget, alerts, quick actions, sensors
- MapScreen: interactive map with layer toggles (6 layers)
- MarketplaceScreen: categories (6), products (5), search
- ChatScreen: AI chat with quick prompts (4), bot responses
- ProfileScreen: user info, stats, menu (9 items), logout
- AlertsScreen: alert list with severity, acknowledge
- SensorsScreen: sensor list with type filters (6 types), search
- ZonesScreen: zone cards with stats
- SettingsScreen: language picker (FR/EN/ES/DE), privacy, about
- Stores: iotStore (sensors, zones, alerts), notificationStore, uiStore + i18n
- Hooks: useSensors, useAlerts, useNotifications, useLocation
- Components: Card, Button, LoadingSpinner, ErrorBoundary, Header
- Services: iotService, notificationService (with axios API client)
- Utils: formatters (temp, AQI, noise, dates), validators (email, password, IBAN)
- Theme: colors.ts with full design system (Blue Ocean palette)
- Ditto: fixed MongoDB connection, new JWT secrets, official gateway image
This commit is contained in:
Eric FELIXINE
2026-06-01 18:00:35 -04:00
parent 08ca495bde
commit e30ae8ed09
35578 changed files with 3703534 additions and 43 deletions

View File

@@ -0,0 +1,9 @@
(The MIT License)
Copyright 2022 Causaly, Inc <front-end@causaly.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,346 @@
# zod-validation-error
Wrap zod validation errors in user-friendly readable messages.
[![Build Status](https://github.com/causaly/zod-validation-error/actions/workflows/ci.yml/badge.svg)](https://github.com/causaly/zod-validation-error/actions/workflows/ci.yml) [![npm version](https://img.shields.io/npm/v/zod-validation-error.svg?color=0c0)](https://www.npmjs.com/package/zod-validation-error)
#### Features
- User-friendly readable messages, configurable via options;
- Maintain original errors under `error.details`;
- Extensive tests.
## Installation
```bash
npm install zod-validation-error
```
#### Requirements
- Node.js v.18+
- TypeScript v.4.5+
## Quick start
```typescript
import { z as zod } from 'zod';
import { fromZodError } from 'zod-validation-error';
// create zod schema
const zodSchema = zod.object({
id: zod.number().int().positive(),
email: zod.string().email(),
});
// parse some invalid value
try {
zodSchema.parse({
id: 1,
email: 'foobar', // note: invalid email
});
} catch (err) {
const validationError = fromZodError(err);
// the error now is readable by the user
// you may print it to console
// or return it via an API
console.log(validationError);
}
```
## Motivation
Zod errors are difficult to consume for the end-user. This library wraps Zod validation errors in user-friendly readable messages that can be exposed to the outer world, while maintaining the original errors in an array for _dev_ use.
### Example
#### Input (from Zod)
```json
[
{
"code": "too_small",
"inclusive": false,
"message": "Number must be greater than 0",
"minimum": 0,
"path": ["id"],
"type": "number"
},
{
"code": "invalid_string",
"message": "Invalid email",
"path": ["email"],
"validation": "email"
}
]
```
#### Output
```
Validation error: Number must be greater than 0 at "id"; Invalid email at "email"
```
## API
- [ValidationError(message[, details])](#validationerror)
- [errorMap](#errormap)
- [isValidationError(error)](#isvalidationerror)
- [isValidationErrorLike(error)](#isvalidationerrorlike)
- [fromZodIssue(zodIssue[, options])](#fromzodissue)
- [fromZodError(zodError[, options])](#fromzoderror)
- [toValidationError([options]) => (error) => ValidationError](#tovalidationerror)
### ValidationError
Main `ValidationError` class, extending native JavaScript `Error`.
#### Arguments
- `message` - _string_; error message (required)
- `details` - _Array<zod.ZodIssue>_; error details (optional)
#### Example
```typescript
const { ValidationError } = require('zod-validation-error');
const error = new ValidationError('foobar');
console.log(error instanceof Error); // prints true
```
### errorMap
A custom error map to use with zod's `setErrorMap` method and get user-friendly messages automatically.
#### Example
```typescript
import { z as zod } from 'zod';
import { errorMap } from 'zod-validation-error';
zod.setErrorMap(errorMap);
```
### isValidationError
A [type guard](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates) utility function, based on `instanceof` comparison.
#### Arguments
- `error` - error instance (required)
#### Example
```typescript
import { ValidationError, isValidationError } from 'zod-validation-error';
const err = new ValidationError('foobar', { details: [] });
isValidationError(err); // returns true
const invalidErr = new Error('foobar');
isValidationError(err); // returns false
```
### isValidationErrorLike
A [type guard](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates) utility function, based on heuristics comparison.
_Why do we need heuristics if we have `instanceof` comparison?_ Because of multi-version inconsistencies. For instance, it's possible that a dependency is using an older `zod-validation-error` version internally. In such case, the `instanceof` comparison will yield invalid results because module deduplication does not apply at npm/yarn level and the prototype is different.
In most cases, it is safer to use `isValidationErrorLike` than `isValidationError`.
#### Arguments
- `error` - error instance (required)
#### Example
```typescript
import { ValidationError, isValidationErrorLike } from 'zod-validation-error';
const err = new ValidationError('foobar', { details: [] });
isValidationErrorLike(err); // returns true
const invalidErr = new Error('foobar');
isValidationErrorLike(err); // returns false
```
### fromZodIssue
Converts a single zod issue to `ValidationError`.
#### Arguments
- `zodIssue` - _zod.ZodIssue_; a ZodIssue instance (required)
- `options` - _Object_; formatting options (optional)
- `issueSeparator` - _string_; used to concatenate issues in user-friendly message (optional, defaults to ";")
- `unionSeparator` - _string_; used to concatenate union-issues in user-friendly message (optional, defaults to ", or")
- `prefix` - _string_ or _null_; prefix to use in user-friendly message (optional, defaults to "Validation error"). Pass `null` to disable prefix completely.
- `prefixSeparator` - _string_; used to concatenate prefix with rest of the user-friendly message (optional, defaults to ": "). Not used when `prefix` is `null`.
- `includePath` - _boolean_; used to provide control on whether to include the erroneous property name suffix or not (optional, defaults to `true`).
### fromZodError
Converts zod error to `ValidationError`.
_Why is the difference between `ZodError` and `ZodIssue`?_ A `ZodError` is a collection of 1 or more `ZodIssue` instances. It's what you get when you call `zodSchema.parse()`.
#### Arguments
- `zodError` - _zod.ZodError_; a ZodError instance (required)
- `options` - _Object_; formatting options (optional)
- `maxIssuesInMessage` - _number_; max issues to include in user-friendly message (optional, defaults to 99)
- `issueSeparator` - _string_; used to concatenate issues in user-friendly message (optional, defaults to ";")
- `unionSeparator` - _string_; used to concatenate union-issues in user-friendly message (optional, defaults to ", or")
- `prefix` - _string_ or _null_; prefix to use in user-friendly message (optional, defaults to "Validation error"). Pass `null` to disable prefix completely.
- `prefixSeparator` - _string_; used to concatenate prefix with rest of the user-friendly message (optional, defaults to ": "). Not used when `prefix` is `null`.
- `includePath` - _boolean_; used to provide control on whether to include the erroneous property name suffix or not (optional, defaults to `true`).
### toValidationError
A curried version of `fromZodError` meant to be used for FP (Functional Programming). Note it first takes the options object if needed and returns a function that converts the `zodError` to a `ValidationError` object
```js
toValidationError(options) => (zodError) => ValidationError
```
#### Example using fp-ts
```typescript
import * as Either from 'fp-ts/Either';
import { z as zod } from 'zod';
import { toValidationError } from 'zod-validation-error';
// create zod schema
const zodSchema = zod
.object({
id: zod.number().int().positive(),
email: zod.string().email(),
})
.brand<'User'>();
export type User = zod.infer<typeof zodSchema>;
export function parse(
value: zod.input<typeof zodSchema>
): Either.Either<Error, User> {
return Either.tryCatch(() => schema.parse(value), toValidationError());
}
```
## FAQ
### How to distinguish between errors
Use the `isValidationErrorLike` type guard.
#### Example
Scenario: Distinguish between `ValidationError` VS generic `Error` in order to respond with 400 VS 500 HTTP status code respectively.
```typescript
import * as Either from 'fp-ts/Either';
import { z as zod } from 'zod';
import { isValidationErrorLike } from 'zod-validation-error';
try {
func(); // throws Error - or - ValidationError
} catch (err) {
if (isValidationErrorLike(err)) {
return 400; // Bad Data (this is a client error)
}
return 500; // Server Error
}
```
### How to use `ValidationError` outside `zod`
It's possible to implement custom validation logic outside `zod` and throw a `ValidationError`.
#### Example
```typescript
import { ValidationError } from 'zod-validation-error';
import { Buffer } from 'node:buffer';
function parseBuffer(buf: unknown): Buffer {
if (!Buffer.isBuffer(buf)) {
throw new ValidationError('Invalid argument; expected buffer');
}
return buf;
}
```
### How to use `ValidationError` with custom "error map"
Zod supports customizing error messages by providing a custom "error map". You may combine this with `zod-validation-error` to produce user-friendly messages.
#### Example 1: produce user-friendly error messages using the `errorMap` property
If all you need is to produce user-friendly error messages you may use the `errorMap` property.
```typescript
import { z as zod } from 'zod';
import { errorMap } from 'zod-validation-error';
zod.setErrorMap(errorMap);
```
#### Example 2: extra customization using `fromZodIssue`
If you need to customize some error code, you may use the `fromZodIssue` function.
```typescript
import { z as zod } from 'zod';
import { fromZodIssue } from 'zod-validation-error';
const customErrorMap: zod.ZodErrorMap = (issue, ctx) => {
switch (issue.code) {
case ZodIssueCode.invalid_type: {
return {
message:
'Custom error message of your preference for invalid_type errors',
};
}
default: {
const validationError = fromZodIssue({
...issue,
// fallback to the default error message
// when issue does not have a message
message: issue.message ?? ctx.defaultError,
});
return {
message: validationError.message,
};
}
}
};
zod.setErrorMap(customErrorMap);
```
### Does `zod-validation-error` support CommonJS
Yes, `zod-validation-error` supports CommonJS out-of-the-box. All you need to do is import it using `require`.
#### Example
```typescript
const { ValidationError } = require('zod-validation-error');
```
## Contribute
Source code contributions are most welcome. Please open a PR, ensure the linter is satisfied and all tests pass.
#### We are hiring
Causaly is building the world's largest biomedical knowledge platform, using technologies such as TypeScript, React and Node.js. Find out more about our openings at https://apply.workable.com/causaly/.
## License
MIT

View File

@@ -0,0 +1,145 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.errorMap = exports.isValidationErrorLike = exports.isValidationError = exports.toValidationError = exports.fromZodError = exports.fromZodIssue = exports.ValidationError = void 0;
const zod = __importStar(require("zod"));
const joinPath_1 = require("./utils/joinPath");
const NonEmptyArray_1 = require("./utils/NonEmptyArray");
const MAX_ISSUES_IN_MESSAGE = 99;
const ISSUE_SEPARATOR = '; ';
const UNION_SEPARATOR = ', or ';
const PREFIX = 'Validation error';
const PREFIX_SEPARATOR = ': ';
class ValidationError extends Error {
details;
name;
constructor(message, details = []) {
super(message);
this.details = details;
this.name = 'ZodValidationError';
}
toString() {
return this.message;
}
}
exports.ValidationError = ValidationError;
function getMessageFromZodIssue(props) {
const { issue, issueSeparator, unionSeparator, includePath } = props;
if (issue.code === 'invalid_union') {
return issue.unionErrors
.reduce((acc, zodError) => {
const newIssues = zodError.issues
.map((issue) => getMessageFromZodIssue({
issue,
issueSeparator,
unionSeparator,
includePath,
}))
.join(issueSeparator);
if (!acc.includes(newIssues)) {
acc.push(newIssues);
}
return acc;
}, [])
.join(unionSeparator);
}
if (includePath && (0, NonEmptyArray_1.isNonEmptyArray)(issue.path)) {
if (issue.path.length === 1) {
const identifier = issue.path[0];
if (typeof identifier === 'number') {
return `${issue.message} at index ${identifier}`;
}
}
return `${issue.message} at "${(0, joinPath_1.joinPath)(issue.path)}"`;
}
return issue.message;
}
function conditionallyPrefixMessage(reason, prefix, prefixSeparator) {
if (prefix !== null) {
if (reason.length > 0) {
return [prefix, reason].join(prefixSeparator);
}
return prefix;
}
if (reason.length > 0) {
return reason;
}
return PREFIX;
}
function fromZodIssue(issue, options = {}) {
const { issueSeparator = ISSUE_SEPARATOR, unionSeparator = UNION_SEPARATOR, prefixSeparator = PREFIX_SEPARATOR, prefix = PREFIX, includePath = true, } = options;
const reason = getMessageFromZodIssue({
issue,
issueSeparator,
unionSeparator,
includePath,
});
const message = conditionallyPrefixMessage(reason, prefix, prefixSeparator);
return new ValidationError(message, [issue]);
}
exports.fromZodIssue = fromZodIssue;
function fromZodError(zodError, options = {}) {
const { maxIssuesInMessage = MAX_ISSUES_IN_MESSAGE, issueSeparator = ISSUE_SEPARATOR, unionSeparator = UNION_SEPARATOR, prefixSeparator = PREFIX_SEPARATOR, prefix = PREFIX, includePath = true, } = options;
const reason = zodError.errors
.slice(0, maxIssuesInMessage)
.map((issue) => getMessageFromZodIssue({
issue,
issueSeparator,
unionSeparator,
includePath,
}))
.join(issueSeparator);
const message = conditionallyPrefixMessage(reason, prefix, prefixSeparator);
return new ValidationError(message, zodError.errors);
}
exports.fromZodError = fromZodError;
const toValidationError = (options = {}) => (err) => {
if (err instanceof zod.ZodError) {
return fromZodError(err, options);
}
if (err instanceof Error) {
return new ValidationError(err.message);
}
return new ValidationError('Unknown error');
};
exports.toValidationError = toValidationError;
function isValidationError(err) {
return err instanceof ValidationError;
}
exports.isValidationError = isValidationError;
function isValidationErrorLike(err) {
return err instanceof Error && err.name === 'ZodValidationError';
}
exports.isValidationErrorLike = isValidationErrorLike;
const errorMap = (issue, ctx) => {
const error = fromZodIssue({
...issue,
message: issue.message ?? ctx.defaultError,
});
return {
message: error.message,
};
};
exports.errorMap = errorMap;

View File

@@ -0,0 +1,11 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.errorMap = exports.fromZodIssue = exports.fromZodError = exports.isValidationErrorLike = exports.isValidationError = exports.toValidationError = exports.ValidationError = void 0;
var ValidationError_1 = require("./ValidationError");
Object.defineProperty(exports, "ValidationError", { enumerable: true, get: function () { return ValidationError_1.ValidationError; } });
Object.defineProperty(exports, "toValidationError", { enumerable: true, get: function () { return ValidationError_1.toValidationError; } });
Object.defineProperty(exports, "isValidationError", { enumerable: true, get: function () { return ValidationError_1.isValidationError; } });
Object.defineProperty(exports, "isValidationErrorLike", { enumerable: true, get: function () { return ValidationError_1.isValidationErrorLike; } });
Object.defineProperty(exports, "fromZodError", { enumerable: true, get: function () { return ValidationError_1.fromZodError; } });
Object.defineProperty(exports, "fromZodIssue", { enumerable: true, get: function () { return ValidationError_1.fromZodIssue; } });
Object.defineProperty(exports, "errorMap", { enumerable: true, get: function () { return ValidationError_1.errorMap; } });

View File

@@ -0,0 +1,7 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isNonEmptyArray = void 0;
function isNonEmptyArray(value) {
return value.length !== 0;
}
exports.isNonEmptyArray = isNonEmptyArray;

View File

@@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.joinPath = void 0;
const identifierRegex = /[$_\p{ID_Start}][$\u200c\u200d\p{ID_Continue}]*/u;
function joinPath(path) {
if (path.length === 1) {
return path[0].toString();
}
return path.reduce((acc, item) => {
if (typeof item === 'number') {
return acc + '[' + item.toString() + ']';
}
if (item.includes('"')) {
return acc + '["' + escapeQuotes(item) + '"]';
}
if (!identifierRegex.test(item)) {
return acc + '["' + item + '"]';
}
const separator = acc.length === 0 ? '' : '.';
return acc + separator + item;
}, '');
}
exports.joinPath = joinPath;
function escapeQuotes(str) {
return str.replace(/"/g, '\\"');
}

View File

@@ -0,0 +1,112 @@
import * as zod from 'zod';
import { joinPath } from './utils/joinPath';
import { isNonEmptyArray } from './utils/NonEmptyArray';
const MAX_ISSUES_IN_MESSAGE = 99;
const ISSUE_SEPARATOR = '; ';
const UNION_SEPARATOR = ', or ';
const PREFIX = 'Validation error';
const PREFIX_SEPARATOR = ': ';
export class ValidationError extends Error {
details;
name;
constructor(message, details = []) {
super(message);
this.details = details;
this.name = 'ZodValidationError';
}
toString() {
return this.message;
}
}
function getMessageFromZodIssue(props) {
const { issue, issueSeparator, unionSeparator, includePath } = props;
if (issue.code === 'invalid_union') {
return issue.unionErrors
.reduce((acc, zodError) => {
const newIssues = zodError.issues
.map((issue) => getMessageFromZodIssue({
issue,
issueSeparator,
unionSeparator,
includePath,
}))
.join(issueSeparator);
if (!acc.includes(newIssues)) {
acc.push(newIssues);
}
return acc;
}, [])
.join(unionSeparator);
}
if (includePath && isNonEmptyArray(issue.path)) {
if (issue.path.length === 1) {
const identifier = issue.path[0];
if (typeof identifier === 'number') {
return `${issue.message} at index ${identifier}`;
}
}
return `${issue.message} at "${joinPath(issue.path)}"`;
}
return issue.message;
}
function conditionallyPrefixMessage(reason, prefix, prefixSeparator) {
if (prefix !== null) {
if (reason.length > 0) {
return [prefix, reason].join(prefixSeparator);
}
return prefix;
}
if (reason.length > 0) {
return reason;
}
return PREFIX;
}
export function fromZodIssue(issue, options = {}) {
const { issueSeparator = ISSUE_SEPARATOR, unionSeparator = UNION_SEPARATOR, prefixSeparator = PREFIX_SEPARATOR, prefix = PREFIX, includePath = true, } = options;
const reason = getMessageFromZodIssue({
issue,
issueSeparator,
unionSeparator,
includePath,
});
const message = conditionallyPrefixMessage(reason, prefix, prefixSeparator);
return new ValidationError(message, [issue]);
}
export function fromZodError(zodError, options = {}) {
const { maxIssuesInMessage = MAX_ISSUES_IN_MESSAGE, issueSeparator = ISSUE_SEPARATOR, unionSeparator = UNION_SEPARATOR, prefixSeparator = PREFIX_SEPARATOR, prefix = PREFIX, includePath = true, } = options;
const reason = zodError.errors
.slice(0, maxIssuesInMessage)
.map((issue) => getMessageFromZodIssue({
issue,
issueSeparator,
unionSeparator,
includePath,
}))
.join(issueSeparator);
const message = conditionallyPrefixMessage(reason, prefix, prefixSeparator);
return new ValidationError(message, zodError.errors);
}
export const toValidationError = (options = {}) => (err) => {
if (err instanceof zod.ZodError) {
return fromZodError(err, options);
}
if (err instanceof Error) {
return new ValidationError(err.message);
}
return new ValidationError('Unknown error');
};
export function isValidationError(err) {
return err instanceof ValidationError;
}
export function isValidationErrorLike(err) {
return err instanceof Error && err.name === 'ZodValidationError';
}
export const errorMap = (issue, ctx) => {
const error = fromZodIssue({
...issue,
message: issue.message ?? ctx.defaultError,
});
return {
message: error.message,
};
};

View File

@@ -0,0 +1 @@
export { ValidationError, toValidationError, isValidationError, isValidationErrorLike, fromZodError, fromZodIssue, errorMap, } from './ValidationError';

View File

@@ -0,0 +1,3 @@
export function isNonEmptyArray(value) {
return value.length !== 0;
}

View File

@@ -0,0 +1,22 @@
const identifierRegex = /[$_\p{ID_Start}][$\u200c\u200d\p{ID_Continue}]*/u;
export function joinPath(path) {
if (path.length === 1) {
return path[0].toString();
}
return path.reduce((acc, item) => {
if (typeof item === 'number') {
return acc + '[' + item.toString() + ']';
}
if (item.includes('"')) {
return acc + '["' + escapeQuotes(item) + '"]';
}
if (!identifierRegex.test(item)) {
return acc + '["' + item + '"]';
}
const separator = acc.length === 0 ? '' : '.';
return acc + separator + item;
}, '');
}
function escapeQuotes(str) {
return str.replace(/"/g, '\\"');
}

View File

@@ -0,0 +1,26 @@
import * as zod from 'zod';
export type ZodError = zod.ZodError;
export type ZodIssue = zod.ZodIssue;
export declare class ValidationError extends Error {
details: Array<zod.ZodIssue>;
name: 'ZodValidationError';
constructor(message: string, details?: Array<zod.ZodIssue> | undefined);
toString(): string;
}
export type FromZodIssueOptions = {
issueSeparator?: string;
unionSeparator?: string;
prefix?: string | null;
prefixSeparator?: string;
includePath?: boolean;
};
export declare function fromZodIssue(issue: ZodIssue, options?: FromZodIssueOptions): ValidationError;
export type FromZodErrorOptions = FromZodIssueOptions & {
maxIssuesInMessage?: number;
};
export declare function fromZodError(zodError: ZodError, options?: FromZodErrorOptions): ValidationError;
export declare const toValidationError: (options?: Parameters<typeof fromZodError>[1]) => (err: unknown) => ValidationError;
export declare function isValidationError(err: unknown): err is ValidationError;
export declare function isValidationErrorLike(err: unknown): err is ValidationError;
export declare const errorMap: zod.ZodErrorMap;
//# sourceMappingURL=ValidationError.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ValidationError.d.ts","sourceRoot":"","sources":["../../lib/ValidationError.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,KAAK,CAAC;AAW3B,MAAM,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC;AACpC,MAAM,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC;AAEpC,qBAAa,eAAgB,SAAQ,KAAK;IACxC,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC7B,IAAI,EAAE,oBAAoB,CAAC;gBAEf,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,SAAc;IAM1E,QAAQ,IAAI,MAAM;CAGnB;AAuED,MAAM,MAAM,mBAAmB,GAAG;IAChC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,wBAAgB,YAAY,CAC1B,KAAK,EAAE,QAAQ,EACf,OAAO,GAAE,mBAAwB,GAChC,eAAe,CAkBjB;AAED,MAAM,MAAM,mBAAmB,GAAG,mBAAmB,GAAG;IACtD,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B,CAAC;AAEF,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,QAAQ,EAClB,OAAO,GAAE,mBAAwB,GAChC,eAAe,CA4BjB;AAED,eAAO,MAAM,iBAAiB,aAClB,WAAW,mBAAmB,CAAC,CAAC,CAAC,CAAC,WACtC,OAAO,KAAG,eAUf,CAAC;AAEJ,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,eAAe,CAEtE;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,eAAe,CAE1E;AAED,eAAO,MAAM,QAAQ,EAAE,GAAG,CAAC,WAW1B,CAAC"}

View File

@@ -0,0 +1,2 @@
export { ValidationError, toValidationError, isValidationError, isValidationErrorLike, fromZodError, fromZodIssue, type ZodError, type ZodIssue, type FromZodErrorOptions, type FromZodIssueOptions, errorMap, } from './ValidationError';
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,qBAAqB,EACrB,YAAY,EACZ,YAAY,EACZ,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,QAAQ,GACT,MAAM,mBAAmB,CAAC"}

View File

@@ -0,0 +1,3 @@
export type NonEmptyArray<T> = [T, ...T[]];
export declare function isNonEmptyArray<T>(value: T[]): value is NonEmptyArray<T>;
//# sourceMappingURL=NonEmptyArray.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"NonEmptyArray.d.ts","sourceRoot":"","sources":["../../../lib/utils/NonEmptyArray.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;AAE3C,wBAAgB,eAAe,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,KAAK,IAAI,aAAa,CAAC,CAAC,CAAC,CAExE"}

View File

@@ -0,0 +1,3 @@
import { NonEmptyArray } from './NonEmptyArray';
export declare function joinPath(path: NonEmptyArray<string | number>): string;
//# sourceMappingURL=joinPath.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"joinPath.d.ts","sourceRoot":"","sources":["../../../lib/utils/joinPath.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAOhD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,MAAM,CAyBrE"}

View File

@@ -0,0 +1,87 @@
{
"name": "zod-validation-error",
"version": "2.1.0",
"description": "Wrap zod validation errors in user-friendly readable messages",
"keywords": [
"zod",
"error",
"validation"
],
"license": "MIT",
"repository": {
"type": "git",
"url": "git://github.com/causaly/zod-validation-error.git"
},
"author": {
"name": "Causaly Team",
"email": "front-end@causaly.com",
"url": "https://www.causaly.com"
},
"contributors": [
{
"name": "Dimitrios C. Michalakos",
"email": "dimitris@jmike.gr",
"url": "https://github.com/jmike"
}
],
"main": "./dist/cjs/index.js",
"module": "./dist/esm/index.js",
"types": "./dist/types/index.d.ts",
"files": [
"dist"
],
"publishConfig": {
"access": "public"
},
"sideEffects": false,
"engines": {
"node": ">=18.0.0"
},
"scripts": {
"typecheck": "tsc --noEmit",
"build:cjs": "tsc -p ./tsconfig.build-cjs.json",
"build:esm": "tsc -p ./tsconfig.build-esm.json",
"build:types": "tsc -p ./tsconfig.build-types.json",
"build": "rimraf dist && concurrently \"npm run build:types\" \"npm run build:esm\" \"npm run build:cjs\"",
"lint": "eslint lib --ext .ts",
"format": "prettier --config ./.prettierrc --ignore-path .gitignore -w .",
"test": "jest",
"coverage": "jest --coverage",
"changeset": "changeset",
"prerelease": "npm run build && npm run test",
"release": "changeset publish",
"prepare": "husky install"
},
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"eslint --fix",
"prettier --config ./.prettierrc --write"
]
},
"devDependencies": {
"@changesets/changelog-github": "^0.4.2",
"@changesets/cli": "^2.18.1",
"@commitlint/cli": "^18.0.0",
"@commitlint/config-conventional": "^18.0.0",
"@types/jest": "^29.2.4",
"@types/node": "^20.5.0",
"@typescript-eslint/eslint-plugin": "^6.4.1",
"@typescript-eslint/parser": "^6.4.1",
"concurrently": "^8.2.0",
"eslint": "^8.4.1",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-simple-import-sort": "^10.0.0",
"husky": "^8.0.3",
"jest": "^29.3.1",
"lint-staged": "^15.0.1",
"prettier": "^2.8.8",
"rimraf": "^5.0.1",
"ts-jest": "^29.0.3",
"typescript": "^5.1.6",
"zod": "^3.20.0"
},
"peerDependencies": {
"zod": "^3.18.0"
}
}