@cosmneo/onion-lasagna-valibot 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +126 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +97 -0
- package/dist/index.d.ts +97 -0
- package/dist/index.js +88 -0
- package/dist/index.js.map +1 -0
- package/package.json +50 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var src_exports = {};
|
|
32
|
+
__export(src_exports, {
|
|
33
|
+
pagination: () => pagination,
|
|
34
|
+
valibotSchema: () => valibotSchema
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(src_exports);
|
|
37
|
+
|
|
38
|
+
// src/valibot.adapter.ts
|
|
39
|
+
var v = __toESM(require("valibot"), 1);
|
|
40
|
+
var import_to_json_schema = require("@valibot/to-json-schema");
|
|
41
|
+
function valibotSchema(schema) {
|
|
42
|
+
return {
|
|
43
|
+
validate(data) {
|
|
44
|
+
const result = v.safeParse(schema, data);
|
|
45
|
+
if (result.success) {
|
|
46
|
+
return { success: true, data: result.output };
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
success: false,
|
|
50
|
+
issues: result.issues.map((issue) => ({
|
|
51
|
+
path: (issue.path ?? []).map((item) => String(item.key)),
|
|
52
|
+
message: issue.message,
|
|
53
|
+
code: issue.type,
|
|
54
|
+
expected: issue.expected ?? void 0,
|
|
55
|
+
received: issue.received
|
|
56
|
+
}))
|
|
57
|
+
};
|
|
58
|
+
},
|
|
59
|
+
toJsonSchema(_options) {
|
|
60
|
+
const result = (0, import_to_json_schema.toJsonSchema)(schema, {
|
|
61
|
+
errorMode: "ignore"
|
|
62
|
+
});
|
|
63
|
+
const { $schema, ...schemaWithoutMeta } = result;
|
|
64
|
+
return schemaWithoutMeta;
|
|
65
|
+
},
|
|
66
|
+
_output: void 0,
|
|
67
|
+
_input: void 0,
|
|
68
|
+
_schema: schema
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// src/schemas/pagination.ts
|
|
73
|
+
var v2 = __toESM(require("valibot"), 1);
|
|
74
|
+
var pagination = {
|
|
75
|
+
/**
|
|
76
|
+
* Query params schema for paginated list requests.
|
|
77
|
+
*
|
|
78
|
+
* Coerces string query params to numbers via `v.transform(Number)`,
|
|
79
|
+
* validates constraints, and applies defaults.
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```typescript
|
|
83
|
+
* // Direct use
|
|
84
|
+
* valibotSchema(pagination.input)
|
|
85
|
+
*
|
|
86
|
+
* // Extended with filters
|
|
87
|
+
* valibotSchema(v.object({
|
|
88
|
+
* ...pagination.input.entries,
|
|
89
|
+
* searchTerm: v.optional(v.string()),
|
|
90
|
+
* }))
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
input: v2.object({
|
|
94
|
+
page: v2.optional(
|
|
95
|
+
v2.pipe(v2.unknown(), v2.transform(Number), v2.number(), v2.integer(), v2.minValue(1)),
|
|
96
|
+
1
|
|
97
|
+
),
|
|
98
|
+
pageSize: v2.optional(
|
|
99
|
+
v2.pipe(
|
|
100
|
+
v2.unknown(),
|
|
101
|
+
v2.transform(Number),
|
|
102
|
+
v2.number(),
|
|
103
|
+
v2.integer(),
|
|
104
|
+
v2.minValue(1),
|
|
105
|
+
v2.maxValue(100)
|
|
106
|
+
),
|
|
107
|
+
10
|
|
108
|
+
)
|
|
109
|
+
}),
|
|
110
|
+
/**
|
|
111
|
+
* Factory for paginated response schemas.
|
|
112
|
+
*
|
|
113
|
+
* @param itemSchema - Valibot schema for individual items in the list
|
|
114
|
+
* @returns Valibot schema for `{ items: T[], total: number }`
|
|
115
|
+
*/
|
|
116
|
+
response: (itemSchema) => v2.object({
|
|
117
|
+
items: v2.array(itemSchema),
|
|
118
|
+
total: v2.number()
|
|
119
|
+
})
|
|
120
|
+
};
|
|
121
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
122
|
+
0 && (module.exports = {
|
|
123
|
+
pagination,
|
|
124
|
+
valibotSchema
|
|
125
|
+
});
|
|
126
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/valibot.adapter.ts","../src/schemas/pagination.ts"],"sourcesContent":["export { valibotSchema } from './valibot.adapter';\nexport { pagination } from './schemas/pagination';\n","/**\n * @fileoverview Valibot schema adapter for the unified route system.\n *\n * This adapter wraps Valibot schemas to provide a consistent interface\n * for validation and JSON Schema generation. Uses `@valibot/to-json-schema`\n * for JSON Schema conversion.\n *\n * Valibot offers the smallest bundle size among TypeScript validation\n * libraries (~0.7-1.4 kB gzipped for typical usage) through its fully\n * tree-shakeable modular API, making it ideal for serverless and edge\n * deployments.\n *\n * @module unified/schema/adapters/valibot\n */\n\nimport * as v from 'valibot';\nimport type { GenericSchema } from 'valibot';\nimport { toJsonSchema } from '@valibot/to-json-schema';\nimport type {\n JsonSchema,\n JsonSchemaOptions,\n SchemaAdapter,\n ValidationResult,\n} from '@cosmneo/onion-lasagna/http/schema/types';\n\n/**\n * Creates a SchemaAdapter from a Valibot schema.\n *\n * Wraps a Valibot schema to provide validation via `v.safeParse()` and\n * JSON Schema generation via `@valibot/to-json-schema`. Valibot's modular\n * architecture ensures only the validators you use are included in the bundle.\n *\n * @param schema - A Valibot schema to wrap\n * @returns A SchemaAdapter that validates using Valibot and generates JSON Schema\n *\n * @example Basic usage\n * ```typescript\n * import * as v from 'valibot';\n * import { valibotSchema } from '@cosmneo/onion-lasagna-valibot';\n *\n * const userSchema = valibotSchema(v.object({\n * name: v.pipe(v.string(), v.minLength(1), v.maxLength(100)),\n * email: v.pipe(v.string(), v.email()),\n * age: v.optional(v.pipe(v.number(), v.integer(), v.minValue(0), v.maxValue(150))),\n * }));\n *\n * // Validate data\n * const result = userSchema.validate({\n * name: 'John Doe',\n * email: 'john@example.com',\n * });\n *\n * // Generate JSON Schema\n * const jsonSchema = userSchema.toJsonSchema();\n * ```\n */\nexport function valibotSchema<T extends GenericSchema>(\n schema: T,\n): SchemaAdapter<v.InferOutput<T>, v.InferInput<T>> {\n type TOutput = v.InferOutput<T>;\n type TInput = v.InferInput<T>;\n\n return {\n validate(data: unknown): ValidationResult<TOutput> {\n const result = v.safeParse(schema, data);\n\n if (result.success) {\n return { success: true, data: result.output as TOutput };\n }\n\n return {\n success: false,\n issues: result.issues.map((issue) => ({\n path: (issue.path ?? []).map((item) => String(item.key)),\n message: issue.message,\n code: issue.type,\n expected: issue.expected ?? undefined,\n received: issue.received,\n })),\n };\n },\n\n toJsonSchema(_options?: JsonSchemaOptions): JsonSchema {\n const result = toJsonSchema(schema, {\n errorMode: 'ignore',\n });\n\n // Remove $schema to avoid conflicts with OpenAPI\n // eslint-disable-next-line @typescript-eslint/no-unused-vars, unused-imports/no-unused-vars\n const { $schema, ...schemaWithoutMeta } = result as Record<string, unknown>;\n\n return schemaWithoutMeta as JsonSchema;\n },\n\n _output: undefined as TOutput,\n _input: undefined as TInput,\n _schema: schema,\n };\n}\n","/**\n * @fileoverview Pre-built Valibot pagination schemas.\n *\n * Provides reusable schemas for paginated list endpoints,\n * matching the core `PaginationInput` and `PaginatedData<T>` types.\n *\n * @module schemas/pagination\n */\n\nimport * as v from 'valibot';\nimport type { GenericSchema } from 'valibot';\n\nexport const pagination = {\n /**\n * Query params schema for paginated list requests.\n *\n * Coerces string query params to numbers via `v.transform(Number)`,\n * validates constraints, and applies defaults.\n *\n * @example\n * ```typescript\n * // Direct use\n * valibotSchema(pagination.input)\n *\n * // Extended with filters\n * valibotSchema(v.object({\n * ...pagination.input.entries,\n * searchTerm: v.optional(v.string()),\n * }))\n * ```\n */\n input: v.object({\n page: v.optional(\n v.pipe(v.unknown(), v.transform(Number), v.number(), v.integer(), v.minValue(1)),\n 1,\n ),\n pageSize: v.optional(\n v.pipe(\n v.unknown(),\n v.transform(Number),\n v.number(),\n v.integer(),\n v.minValue(1),\n v.maxValue(100),\n ),\n 10,\n ),\n }),\n\n /**\n * Factory for paginated response schemas.\n *\n * @param itemSchema - Valibot schema for individual items in the list\n * @returns Valibot schema for `{ items: T[], total: number }`\n */\n response: <T extends GenericSchema>(itemSchema: T) =>\n v.object({\n items: v.array(itemSchema),\n total: v.number(),\n }),\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACeA,QAAmB;AAEnB,4BAA6B;AAuCtB,SAAS,cACd,QACkD;AAIlD,SAAO;AAAA,IACL,SAAS,MAA0C;AACjD,YAAM,SAAW,YAAU,QAAQ,IAAI;AAEvC,UAAI,OAAO,SAAS;AAClB,eAAO,EAAE,SAAS,MAAM,MAAM,OAAO,OAAkB;AAAA,MACzD;AAEA,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ,OAAO,OAAO,IAAI,CAAC,WAAW;AAAA,UACpC,OAAO,MAAM,QAAQ,CAAC,GAAG,IAAI,CAAC,SAAS,OAAO,KAAK,GAAG,CAAC;AAAA,UACvD,SAAS,MAAM;AAAA,UACf,MAAM,MAAM;AAAA,UACZ,UAAU,MAAM,YAAY;AAAA,UAC5B,UAAU,MAAM;AAAA,QAClB,EAAE;AAAA,MACJ;AAAA,IACF;AAAA,IAEA,aAAa,UAA0C;AACrD,YAAM,aAAS,oCAAa,QAAQ;AAAA,QAClC,WAAW;AAAA,MACb,CAAC;AAID,YAAM,EAAE,SAAS,GAAG,kBAAkB,IAAI;AAE1C,aAAO;AAAA,IACT;AAAA,IAEA,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,SAAS;AAAA,EACX;AACF;;;ACzFA,IAAAA,KAAmB;AAGZ,IAAM,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBxB,OAAS,UAAO;AAAA,IACd,MAAQ;AAAA,MACJ,QAAO,WAAQ,GAAK,aAAU,MAAM,GAAK,UAAO,GAAK,WAAQ,GAAK,YAAS,CAAC,CAAC;AAAA,MAC/E;AAAA,IACF;AAAA,IACA,UAAY;AAAA,MACR;AAAA,QACE,WAAQ;AAAA,QACR,aAAU,MAAM;AAAA,QAChB,UAAO;AAAA,QACP,WAAQ;AAAA,QACR,YAAS,CAAC;AAAA,QACV,YAAS,GAAG;AAAA,MAChB;AAAA,MACA;AAAA,IACF;AAAA,EACF,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQD,UAAU,CAA0B,eAChC,UAAO;AAAA,IACP,OAAS,SAAM,UAAU;AAAA,IACzB,OAAS,UAAO;AAAA,EAClB,CAAC;AACL;","names":["v"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import * as v from 'valibot';
|
|
2
|
+
import { GenericSchema } from 'valibot';
|
|
3
|
+
import { SchemaAdapter } from '@cosmneo/onion-lasagna/http/schema/types';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @fileoverview Valibot schema adapter for the unified route system.
|
|
7
|
+
*
|
|
8
|
+
* This adapter wraps Valibot schemas to provide a consistent interface
|
|
9
|
+
* for validation and JSON Schema generation. Uses `@valibot/to-json-schema`
|
|
10
|
+
* for JSON Schema conversion.
|
|
11
|
+
*
|
|
12
|
+
* Valibot offers the smallest bundle size among TypeScript validation
|
|
13
|
+
* libraries (~0.7-1.4 kB gzipped for typical usage) through its fully
|
|
14
|
+
* tree-shakeable modular API, making it ideal for serverless and edge
|
|
15
|
+
* deployments.
|
|
16
|
+
*
|
|
17
|
+
* @module unified/schema/adapters/valibot
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Creates a SchemaAdapter from a Valibot schema.
|
|
22
|
+
*
|
|
23
|
+
* Wraps a Valibot schema to provide validation via `v.safeParse()` and
|
|
24
|
+
* JSON Schema generation via `@valibot/to-json-schema`. Valibot's modular
|
|
25
|
+
* architecture ensures only the validators you use are included in the bundle.
|
|
26
|
+
*
|
|
27
|
+
* @param schema - A Valibot schema to wrap
|
|
28
|
+
* @returns A SchemaAdapter that validates using Valibot and generates JSON Schema
|
|
29
|
+
*
|
|
30
|
+
* @example Basic usage
|
|
31
|
+
* ```typescript
|
|
32
|
+
* import * as v from 'valibot';
|
|
33
|
+
* import { valibotSchema } from '@cosmneo/onion-lasagna-valibot';
|
|
34
|
+
*
|
|
35
|
+
* const userSchema = valibotSchema(v.object({
|
|
36
|
+
* name: v.pipe(v.string(), v.minLength(1), v.maxLength(100)),
|
|
37
|
+
* email: v.pipe(v.string(), v.email()),
|
|
38
|
+
* age: v.optional(v.pipe(v.number(), v.integer(), v.minValue(0), v.maxValue(150))),
|
|
39
|
+
* }));
|
|
40
|
+
*
|
|
41
|
+
* // Validate data
|
|
42
|
+
* const result = userSchema.validate({
|
|
43
|
+
* name: 'John Doe',
|
|
44
|
+
* email: 'john@example.com',
|
|
45
|
+
* });
|
|
46
|
+
*
|
|
47
|
+
* // Generate JSON Schema
|
|
48
|
+
* const jsonSchema = userSchema.toJsonSchema();
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
declare function valibotSchema<T extends GenericSchema>(schema: T): SchemaAdapter<v.InferOutput<T>, v.InferInput<T>>;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @fileoverview Pre-built Valibot pagination schemas.
|
|
55
|
+
*
|
|
56
|
+
* Provides reusable schemas for paginated list endpoints,
|
|
57
|
+
* matching the core `PaginationInput` and `PaginatedData<T>` types.
|
|
58
|
+
*
|
|
59
|
+
* @module schemas/pagination
|
|
60
|
+
*/
|
|
61
|
+
|
|
62
|
+
declare const pagination: {
|
|
63
|
+
/**
|
|
64
|
+
* Query params schema for paginated list requests.
|
|
65
|
+
*
|
|
66
|
+
* Coerces string query params to numbers via `v.transform(Number)`,
|
|
67
|
+
* validates constraints, and applies defaults.
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```typescript
|
|
71
|
+
* // Direct use
|
|
72
|
+
* valibotSchema(pagination.input)
|
|
73
|
+
*
|
|
74
|
+
* // Extended with filters
|
|
75
|
+
* valibotSchema(v.object({
|
|
76
|
+
* ...pagination.input.entries,
|
|
77
|
+
* searchTerm: v.optional(v.string()),
|
|
78
|
+
* }))
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
input: v.ObjectSchema<{
|
|
82
|
+
readonly page: v.OptionalSchema<v.SchemaWithPipe<readonly [v.UnknownSchema, v.TransformAction<any, number>, v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>, 1>;
|
|
83
|
+
readonly pageSize: v.OptionalSchema<v.SchemaWithPipe<readonly [v.UnknownSchema, v.TransformAction<any, number>, v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>, v.MaxValueAction<number, 100, undefined>]>, 10>;
|
|
84
|
+
}, undefined>;
|
|
85
|
+
/**
|
|
86
|
+
* Factory for paginated response schemas.
|
|
87
|
+
*
|
|
88
|
+
* @param itemSchema - Valibot schema for individual items in the list
|
|
89
|
+
* @returns Valibot schema for `{ items: T[], total: number }`
|
|
90
|
+
*/
|
|
91
|
+
response: <T extends GenericSchema>(itemSchema: T) => v.ObjectSchema<{
|
|
92
|
+
readonly items: v.ArraySchema<T, undefined>;
|
|
93
|
+
readonly total: v.NumberSchema<undefined>;
|
|
94
|
+
}, undefined>;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
export { pagination, valibotSchema };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import * as v from 'valibot';
|
|
2
|
+
import { GenericSchema } from 'valibot';
|
|
3
|
+
import { SchemaAdapter } from '@cosmneo/onion-lasagna/http/schema/types';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @fileoverview Valibot schema adapter for the unified route system.
|
|
7
|
+
*
|
|
8
|
+
* This adapter wraps Valibot schemas to provide a consistent interface
|
|
9
|
+
* for validation and JSON Schema generation. Uses `@valibot/to-json-schema`
|
|
10
|
+
* for JSON Schema conversion.
|
|
11
|
+
*
|
|
12
|
+
* Valibot offers the smallest bundle size among TypeScript validation
|
|
13
|
+
* libraries (~0.7-1.4 kB gzipped for typical usage) through its fully
|
|
14
|
+
* tree-shakeable modular API, making it ideal for serverless and edge
|
|
15
|
+
* deployments.
|
|
16
|
+
*
|
|
17
|
+
* @module unified/schema/adapters/valibot
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Creates a SchemaAdapter from a Valibot schema.
|
|
22
|
+
*
|
|
23
|
+
* Wraps a Valibot schema to provide validation via `v.safeParse()` and
|
|
24
|
+
* JSON Schema generation via `@valibot/to-json-schema`. Valibot's modular
|
|
25
|
+
* architecture ensures only the validators you use are included in the bundle.
|
|
26
|
+
*
|
|
27
|
+
* @param schema - A Valibot schema to wrap
|
|
28
|
+
* @returns A SchemaAdapter that validates using Valibot and generates JSON Schema
|
|
29
|
+
*
|
|
30
|
+
* @example Basic usage
|
|
31
|
+
* ```typescript
|
|
32
|
+
* import * as v from 'valibot';
|
|
33
|
+
* import { valibotSchema } from '@cosmneo/onion-lasagna-valibot';
|
|
34
|
+
*
|
|
35
|
+
* const userSchema = valibotSchema(v.object({
|
|
36
|
+
* name: v.pipe(v.string(), v.minLength(1), v.maxLength(100)),
|
|
37
|
+
* email: v.pipe(v.string(), v.email()),
|
|
38
|
+
* age: v.optional(v.pipe(v.number(), v.integer(), v.minValue(0), v.maxValue(150))),
|
|
39
|
+
* }));
|
|
40
|
+
*
|
|
41
|
+
* // Validate data
|
|
42
|
+
* const result = userSchema.validate({
|
|
43
|
+
* name: 'John Doe',
|
|
44
|
+
* email: 'john@example.com',
|
|
45
|
+
* });
|
|
46
|
+
*
|
|
47
|
+
* // Generate JSON Schema
|
|
48
|
+
* const jsonSchema = userSchema.toJsonSchema();
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
declare function valibotSchema<T extends GenericSchema>(schema: T): SchemaAdapter<v.InferOutput<T>, v.InferInput<T>>;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @fileoverview Pre-built Valibot pagination schemas.
|
|
55
|
+
*
|
|
56
|
+
* Provides reusable schemas for paginated list endpoints,
|
|
57
|
+
* matching the core `PaginationInput` and `PaginatedData<T>` types.
|
|
58
|
+
*
|
|
59
|
+
* @module schemas/pagination
|
|
60
|
+
*/
|
|
61
|
+
|
|
62
|
+
declare const pagination: {
|
|
63
|
+
/**
|
|
64
|
+
* Query params schema for paginated list requests.
|
|
65
|
+
*
|
|
66
|
+
* Coerces string query params to numbers via `v.transform(Number)`,
|
|
67
|
+
* validates constraints, and applies defaults.
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```typescript
|
|
71
|
+
* // Direct use
|
|
72
|
+
* valibotSchema(pagination.input)
|
|
73
|
+
*
|
|
74
|
+
* // Extended with filters
|
|
75
|
+
* valibotSchema(v.object({
|
|
76
|
+
* ...pagination.input.entries,
|
|
77
|
+
* searchTerm: v.optional(v.string()),
|
|
78
|
+
* }))
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
input: v.ObjectSchema<{
|
|
82
|
+
readonly page: v.OptionalSchema<v.SchemaWithPipe<readonly [v.UnknownSchema, v.TransformAction<any, number>, v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>, 1>;
|
|
83
|
+
readonly pageSize: v.OptionalSchema<v.SchemaWithPipe<readonly [v.UnknownSchema, v.TransformAction<any, number>, v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>, v.MaxValueAction<number, 100, undefined>]>, 10>;
|
|
84
|
+
}, undefined>;
|
|
85
|
+
/**
|
|
86
|
+
* Factory for paginated response schemas.
|
|
87
|
+
*
|
|
88
|
+
* @param itemSchema - Valibot schema for individual items in the list
|
|
89
|
+
* @returns Valibot schema for `{ items: T[], total: number }`
|
|
90
|
+
*/
|
|
91
|
+
response: <T extends GenericSchema>(itemSchema: T) => v.ObjectSchema<{
|
|
92
|
+
readonly items: v.ArraySchema<T, undefined>;
|
|
93
|
+
readonly total: v.NumberSchema<undefined>;
|
|
94
|
+
}, undefined>;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
export { pagination, valibotSchema };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// src/valibot.adapter.ts
|
|
2
|
+
import * as v from "valibot";
|
|
3
|
+
import { toJsonSchema } from "@valibot/to-json-schema";
|
|
4
|
+
function valibotSchema(schema) {
|
|
5
|
+
return {
|
|
6
|
+
validate(data) {
|
|
7
|
+
const result = v.safeParse(schema, data);
|
|
8
|
+
if (result.success) {
|
|
9
|
+
return { success: true, data: result.output };
|
|
10
|
+
}
|
|
11
|
+
return {
|
|
12
|
+
success: false,
|
|
13
|
+
issues: result.issues.map((issue) => ({
|
|
14
|
+
path: (issue.path ?? []).map((item) => String(item.key)),
|
|
15
|
+
message: issue.message,
|
|
16
|
+
code: issue.type,
|
|
17
|
+
expected: issue.expected ?? void 0,
|
|
18
|
+
received: issue.received
|
|
19
|
+
}))
|
|
20
|
+
};
|
|
21
|
+
},
|
|
22
|
+
toJsonSchema(_options) {
|
|
23
|
+
const result = toJsonSchema(schema, {
|
|
24
|
+
errorMode: "ignore"
|
|
25
|
+
});
|
|
26
|
+
const { $schema, ...schemaWithoutMeta } = result;
|
|
27
|
+
return schemaWithoutMeta;
|
|
28
|
+
},
|
|
29
|
+
_output: void 0,
|
|
30
|
+
_input: void 0,
|
|
31
|
+
_schema: schema
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// src/schemas/pagination.ts
|
|
36
|
+
import * as v2 from "valibot";
|
|
37
|
+
var pagination = {
|
|
38
|
+
/**
|
|
39
|
+
* Query params schema for paginated list requests.
|
|
40
|
+
*
|
|
41
|
+
* Coerces string query params to numbers via `v.transform(Number)`,
|
|
42
|
+
* validates constraints, and applies defaults.
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```typescript
|
|
46
|
+
* // Direct use
|
|
47
|
+
* valibotSchema(pagination.input)
|
|
48
|
+
*
|
|
49
|
+
* // Extended with filters
|
|
50
|
+
* valibotSchema(v.object({
|
|
51
|
+
* ...pagination.input.entries,
|
|
52
|
+
* searchTerm: v.optional(v.string()),
|
|
53
|
+
* }))
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
input: v2.object({
|
|
57
|
+
page: v2.optional(
|
|
58
|
+
v2.pipe(v2.unknown(), v2.transform(Number), v2.number(), v2.integer(), v2.minValue(1)),
|
|
59
|
+
1
|
|
60
|
+
),
|
|
61
|
+
pageSize: v2.optional(
|
|
62
|
+
v2.pipe(
|
|
63
|
+
v2.unknown(),
|
|
64
|
+
v2.transform(Number),
|
|
65
|
+
v2.number(),
|
|
66
|
+
v2.integer(),
|
|
67
|
+
v2.minValue(1),
|
|
68
|
+
v2.maxValue(100)
|
|
69
|
+
),
|
|
70
|
+
10
|
|
71
|
+
)
|
|
72
|
+
}),
|
|
73
|
+
/**
|
|
74
|
+
* Factory for paginated response schemas.
|
|
75
|
+
*
|
|
76
|
+
* @param itemSchema - Valibot schema for individual items in the list
|
|
77
|
+
* @returns Valibot schema for `{ items: T[], total: number }`
|
|
78
|
+
*/
|
|
79
|
+
response: (itemSchema) => v2.object({
|
|
80
|
+
items: v2.array(itemSchema),
|
|
81
|
+
total: v2.number()
|
|
82
|
+
})
|
|
83
|
+
};
|
|
84
|
+
export {
|
|
85
|
+
pagination,
|
|
86
|
+
valibotSchema
|
|
87
|
+
};
|
|
88
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/valibot.adapter.ts","../src/schemas/pagination.ts"],"sourcesContent":["/**\n * @fileoverview Valibot schema adapter for the unified route system.\n *\n * This adapter wraps Valibot schemas to provide a consistent interface\n * for validation and JSON Schema generation. Uses `@valibot/to-json-schema`\n * for JSON Schema conversion.\n *\n * Valibot offers the smallest bundle size among TypeScript validation\n * libraries (~0.7-1.4 kB gzipped for typical usage) through its fully\n * tree-shakeable modular API, making it ideal for serverless and edge\n * deployments.\n *\n * @module unified/schema/adapters/valibot\n */\n\nimport * as v from 'valibot';\nimport type { GenericSchema } from 'valibot';\nimport { toJsonSchema } from '@valibot/to-json-schema';\nimport type {\n JsonSchema,\n JsonSchemaOptions,\n SchemaAdapter,\n ValidationResult,\n} from '@cosmneo/onion-lasagna/http/schema/types';\n\n/**\n * Creates a SchemaAdapter from a Valibot schema.\n *\n * Wraps a Valibot schema to provide validation via `v.safeParse()` and\n * JSON Schema generation via `@valibot/to-json-schema`. Valibot's modular\n * architecture ensures only the validators you use are included in the bundle.\n *\n * @param schema - A Valibot schema to wrap\n * @returns A SchemaAdapter that validates using Valibot and generates JSON Schema\n *\n * @example Basic usage\n * ```typescript\n * import * as v from 'valibot';\n * import { valibotSchema } from '@cosmneo/onion-lasagna-valibot';\n *\n * const userSchema = valibotSchema(v.object({\n * name: v.pipe(v.string(), v.minLength(1), v.maxLength(100)),\n * email: v.pipe(v.string(), v.email()),\n * age: v.optional(v.pipe(v.number(), v.integer(), v.minValue(0), v.maxValue(150))),\n * }));\n *\n * // Validate data\n * const result = userSchema.validate({\n * name: 'John Doe',\n * email: 'john@example.com',\n * });\n *\n * // Generate JSON Schema\n * const jsonSchema = userSchema.toJsonSchema();\n * ```\n */\nexport function valibotSchema<T extends GenericSchema>(\n schema: T,\n): SchemaAdapter<v.InferOutput<T>, v.InferInput<T>> {\n type TOutput = v.InferOutput<T>;\n type TInput = v.InferInput<T>;\n\n return {\n validate(data: unknown): ValidationResult<TOutput> {\n const result = v.safeParse(schema, data);\n\n if (result.success) {\n return { success: true, data: result.output as TOutput };\n }\n\n return {\n success: false,\n issues: result.issues.map((issue) => ({\n path: (issue.path ?? []).map((item) => String(item.key)),\n message: issue.message,\n code: issue.type,\n expected: issue.expected ?? undefined,\n received: issue.received,\n })),\n };\n },\n\n toJsonSchema(_options?: JsonSchemaOptions): JsonSchema {\n const result = toJsonSchema(schema, {\n errorMode: 'ignore',\n });\n\n // Remove $schema to avoid conflicts with OpenAPI\n // eslint-disable-next-line @typescript-eslint/no-unused-vars, unused-imports/no-unused-vars\n const { $schema, ...schemaWithoutMeta } = result as Record<string, unknown>;\n\n return schemaWithoutMeta as JsonSchema;\n },\n\n _output: undefined as TOutput,\n _input: undefined as TInput,\n _schema: schema,\n };\n}\n","/**\n * @fileoverview Pre-built Valibot pagination schemas.\n *\n * Provides reusable schemas for paginated list endpoints,\n * matching the core `PaginationInput` and `PaginatedData<T>` types.\n *\n * @module schemas/pagination\n */\n\nimport * as v from 'valibot';\nimport type { GenericSchema } from 'valibot';\n\nexport const pagination = {\n /**\n * Query params schema for paginated list requests.\n *\n * Coerces string query params to numbers via `v.transform(Number)`,\n * validates constraints, and applies defaults.\n *\n * @example\n * ```typescript\n * // Direct use\n * valibotSchema(pagination.input)\n *\n * // Extended with filters\n * valibotSchema(v.object({\n * ...pagination.input.entries,\n * searchTerm: v.optional(v.string()),\n * }))\n * ```\n */\n input: v.object({\n page: v.optional(\n v.pipe(v.unknown(), v.transform(Number), v.number(), v.integer(), v.minValue(1)),\n 1,\n ),\n pageSize: v.optional(\n v.pipe(\n v.unknown(),\n v.transform(Number),\n v.number(),\n v.integer(),\n v.minValue(1),\n v.maxValue(100),\n ),\n 10,\n ),\n }),\n\n /**\n * Factory for paginated response schemas.\n *\n * @param itemSchema - Valibot schema for individual items in the list\n * @returns Valibot schema for `{ items: T[], total: number }`\n */\n response: <T extends GenericSchema>(itemSchema: T) =>\n v.object({\n items: v.array(itemSchema),\n total: v.number(),\n }),\n};\n"],"mappings":";AAeA,YAAY,OAAO;AAEnB,SAAS,oBAAoB;AAuCtB,SAAS,cACd,QACkD;AAIlD,SAAO;AAAA,IACL,SAAS,MAA0C;AACjD,YAAM,SAAW,YAAU,QAAQ,IAAI;AAEvC,UAAI,OAAO,SAAS;AAClB,eAAO,EAAE,SAAS,MAAM,MAAM,OAAO,OAAkB;AAAA,MACzD;AAEA,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ,OAAO,OAAO,IAAI,CAAC,WAAW;AAAA,UACpC,OAAO,MAAM,QAAQ,CAAC,GAAG,IAAI,CAAC,SAAS,OAAO,KAAK,GAAG,CAAC;AAAA,UACvD,SAAS,MAAM;AAAA,UACf,MAAM,MAAM;AAAA,UACZ,UAAU,MAAM,YAAY;AAAA,UAC5B,UAAU,MAAM;AAAA,QAClB,EAAE;AAAA,MACJ;AAAA,IACF;AAAA,IAEA,aAAa,UAA0C;AACrD,YAAM,SAAS,aAAa,QAAQ;AAAA,QAClC,WAAW;AAAA,MACb,CAAC;AAID,YAAM,EAAE,SAAS,GAAG,kBAAkB,IAAI;AAE1C,aAAO;AAAA,IACT;AAAA,IAEA,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,SAAS;AAAA,EACX;AACF;;;ACzFA,YAAYA,QAAO;AAGZ,IAAM,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBxB,OAAS,UAAO;AAAA,IACd,MAAQ;AAAA,MACJ,QAAO,WAAQ,GAAK,aAAU,MAAM,GAAK,UAAO,GAAK,WAAQ,GAAK,YAAS,CAAC,CAAC;AAAA,MAC/E;AAAA,IACF;AAAA,IACA,UAAY;AAAA,MACR;AAAA,QACE,WAAQ;AAAA,QACR,aAAU,MAAM;AAAA,QAChB,UAAO;AAAA,QACP,WAAQ;AAAA,QACR,YAAS,CAAC;AAAA,QACV,YAAS,GAAG;AAAA,MAChB;AAAA,MACA;AAAA,IACF;AAAA,EACF,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQD,UAAU,CAA0B,eAChC,UAAO;AAAA,IACP,OAAS,SAAM,UAAU;AAAA,IACzB,OAAS,UAAO;AAAA,EAClB,CAAC;AACL;","names":["v"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cosmneo/onion-lasagna-valibot",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Valibot schema adapter for onion-lasagna",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "Cosmneo",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/Cosmneo/onion-lasagna.git",
|
|
11
|
+
"directory": "packages/schemas/onion-lasagna-valibot"
|
|
12
|
+
},
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": ">=18.0.0"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"sideEffects": false,
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"tsup": "^8.5.1",
|
|
22
|
+
"vitest": "^4.0.16",
|
|
23
|
+
"valibot": "1.2.0",
|
|
24
|
+
"@valibot/to-json-schema": "1.5.0",
|
|
25
|
+
"@cosmneo/onion-lasagna": "workspace:*"
|
|
26
|
+
},
|
|
27
|
+
"peerDependencies": {
|
|
28
|
+
"valibot": "^1.0.0",
|
|
29
|
+
"@valibot/to-json-schema": "^1.0.0",
|
|
30
|
+
"@cosmneo/onion-lasagna": ">=0.2.0"
|
|
31
|
+
},
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "tsup",
|
|
34
|
+
"dev": "tsup --watch",
|
|
35
|
+
"test": "vitest",
|
|
36
|
+
"test:run": "vitest run",
|
|
37
|
+
"prepublishOnly": "bun run build"
|
|
38
|
+
},
|
|
39
|
+
"exports": {
|
|
40
|
+
".": {
|
|
41
|
+
"types": "./dist/index.d.ts",
|
|
42
|
+
"import": "./dist/index.js",
|
|
43
|
+
"require": "./dist/index.cjs",
|
|
44
|
+
"default": "./dist/index.js"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"publishConfig": {
|
|
48
|
+
"access": "public"
|
|
49
|
+
}
|
|
50
|
+
}
|