@vercube/schema 0.0.19

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2025-present - Vercube
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,146 @@
1
+ <div align="center">
2
+ <a href="https://vercube.dev/"><img src="https://github.com/OskarLebuda/vue-lazy-hydration/raw/main/.github/assets/logo.png?raw=true" alt="Vite logo" width="200"></a>
3
+ <br>
4
+ <br>
5
+
6
+ # Vercube
7
+
8
+ Next generation HTTP framework
9
+
10
+ <a href="https://www.npmjs.com/package/@vercube/schema">
11
+ <img src="https://img.shields.io/npm/v/%40vercube%2Fschema?style=for-the-badge&logo=npm&color=%23767eff" alt="npm"/>
12
+ </a>
13
+ <a href="https://www.npmjs.com/package/@vercube/schema">
14
+ <img src="https://img.shields.io/npm/dm/%40vercube%2Fschema?style=for-the-badge&logo=npm&color=%23767eff" alt="npm"/>
15
+ </a>
16
+ <a href="https://github.com/vercube/vercube/blob/main/LICENSE" target="_blank">
17
+ <img src="https://img.shields.io/npm/l/%40vercube%2Fschema?style=for-the-badge&color=%23767eff" alt="License"/>
18
+ </a>
19
+ <br/>
20
+ <br/>
21
+ </div>
22
+
23
+ An ultra-efficient JavaScript server framework that runs anywhere - Node.js, Bun, or Deno - with unmatched flexibility and complete configurability for developers who refuse to sacrifice speed or control.
24
+
25
+ ---
26
+
27
+ ## ๐Ÿงฉ `@vercube/schema` Module
28
+
29
+ The `@vercube/schema` module provides a unified, provider-agnostic interface for managing OpenAPI schemas.
30
+ It abstracts schema definitions into a consistent API that works across tools and environments, enabling easy switching between providers without modifying your application code.
31
+
32
+ ### โœ… Key Features
33
+
34
+ - Seamless integration with OpenAPI
35
+ - Zod-based schema definition
36
+ - Works out-of-the-box with route decorators
37
+ - Compatible with custom validation and metadata
38
+ - Supports both static and runtime schema generation
39
+
40
+ ---
41
+
42
+ ## ๐Ÿš€ Installation
43
+
44
+ ```bash
45
+ pnpm install @vercube/schema
46
+ ````
47
+
48
+ ---
49
+
50
+ ## โš™๏ธ Usage
51
+
52
+ Integrate the Schema plugin into your app setup:
53
+
54
+ ```ts
55
+ import { createApp } from '@vercube/core';
56
+ import { SchemaPlugin } from '@vercube/schema';
57
+
58
+ const app = createApp({
59
+ setup: async (app) => {
60
+ app.addPlugin(SchemaPlugin);
61
+ }
62
+ });
63
+ ```
64
+
65
+ ---
66
+
67
+ ## ๐Ÿงต Route Schema Decorators
68
+
69
+ The `@Schema` decorator lets you define OpenAPI-compatible schema definitions directly on your routes.
70
+ It leverages [`@asteasolutions/zod-to-openapi`](https://github.com/asteasolutions/zod-to-openapi) for automatic schema translation and also supports `.openapi` properties on Zod schemas.
71
+
72
+ ```ts
73
+ import { Controller, Post, Body } from '@vercube/core';
74
+ import { Schema } from '@vercube/schema';
75
+
76
+ @Controller('/users')
77
+ export class UsersController {
78
+
79
+ @Post('/')
80
+ @Schema({
81
+ request: {
82
+ params: ParamsSchema,
83
+ },
84
+ responses: {
85
+ 200: {
86
+ description: 'Retrieve the user',
87
+ content: {
88
+ 'application/json': {
89
+ schema: UserSchema,
90
+ },
91
+ },
92
+ },
93
+ },
94
+ })
95
+ public async insertUser(
96
+ @Body({ validationSchema: UserSchema }) user: User,
97
+ ): Promise<void> {
98
+ console.log(user);
99
+ }
100
+ }
101
+ ```
102
+
103
+ ## ๐Ÿ“„ Runtime Access to OpenAPI Schema
104
+
105
+ When the SchemaPlugin is added to your application, a special controller is automatically registered.
106
+ This controller exposes the full OpenAPI schema at runtime and is available without any additional configuration.
107
+
108
+ You can access it at:
109
+ ```
110
+ http://localhost:3000/_schema
111
+ ```
112
+
113
+ This makes it easy to integrate with tools like Swagger UI, Postman, or for debugging and documentation purposes.
114
+
115
+ ### โœจ Automatic Resolution
116
+
117
+ * The `@Schema` decorator automatically resolves:
118
+
119
+ * HTTP method and route path
120
+ * Request body schema (`@Body`)
121
+ * Query parameters (`@QueryParams`)
122
+ * Path parameters (`@Params`)
123
+
124
+ ---
125
+
126
+ ## ๐Ÿ“š Documentation
127
+
128
+ Full documentation is available at [**vercube.dev**](https://vercube.dev).
129
+ Explore guides, API references, and best practices to master Vercube.
130
+
131
+ ---
132
+
133
+ ## ๐Ÿ™Œ Credits
134
+
135
+ This module is inspired by:
136
+
137
+ * [@asteasolutions/zod-to-openapi](https://github.com/asteasolutions/zod-to-openapi)
138
+ * [Hono Zod OpenAPI Example](https://hono.dev/examples/zod-openapi)
139
+ * [Nitro OpenAPI](https://nitro.build/config#openapi)
140
+
141
+ ---
142
+
143
+ ## ๐Ÿชช License
144
+
145
+ [MIT License](https://github.com/vercube/vercube/blob/main/LICENSE)
146
+
@@ -0,0 +1,57 @@
1
+ import { z } from "zod";
2
+ import { RouteConfig } from "@asteasolutions/zod-to-openapi";
3
+ import { App, BasePlugin } from "@vercube/core";
4
+
5
+ //#region src/Decorators/Schema.d.ts
6
+ interface SchemaDecoratorOptions extends Omit<RouteConfig, 'method' | 'path'> {}
7
+ /**
8
+ * A decorator function for registering OpenAPI schema metadata for a route.
9
+ *
10
+ * This function creates an instance of the SchemaDecorator class and registers
11
+ * the schema with the specified options.
12
+ *
13
+ * @param {SchemaDecoratorOptions} params - The schema options for the route.
14
+ * @returns {Function} - The decorator function.
15
+ */
16
+ declare function Schema(params: SchemaDecoratorOptions): Function;
17
+ //#endregion
18
+ //#region src/Plugins/SchemaPlugin.d.ts
19
+ /**
20
+ * Schema Plugin for Vercube framework
21
+ *
22
+ * Provides OpenAPI/Swagger schema generation and validation capabilities:
23
+ * - Automatic OpenAPI schema generation from Zod schemas
24
+ * - Route-level schema validation via @Schema decorator
25
+ * - Runtime schema access via /_schema endpoint
26
+ * - Seamless integration with request validation (@Body, @Query, etc)
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * import { createApp } from '@vercube/core';
31
+ * import { SchemaPlugin } from '@vercube/schema';
32
+ *
33
+ * const app = createApp({
34
+ * setup: async (app) => {
35
+ * app.addPlugin(SchemaPlugin);
36
+ * }
37
+ * });
38
+ * ```
39
+ *
40
+ * @see {@link https://vercube.dev} for full documentation
41
+ */
42
+ declare class SchemaPlugin<T = unknown> extends BasePlugin<T> {
43
+ /**
44
+ * The name of the plugin.
45
+ * @override
46
+ */
47
+ name: string;
48
+ /**
49
+ * Method to use the plugin with the given app.
50
+ * @param {App} app - The application instance.
51
+ * @returns {void | Promise<void>}
52
+ * @override
53
+ */
54
+ use(app: App, options: T): void | Promise<void>;
55
+ }
56
+ //#endregion
57
+ export { Schema, SchemaPlugin, z };
package/dist/index.mjs ADDED
@@ -0,0 +1,219 @@
1
+ import "node:module";
2
+ import { z } from "zod";
3
+ import { OpenAPIRegistry, OpenApiGeneratorV3, extendZodWithOpenApi } from "@asteasolutions/zod-to-openapi";
4
+ import { BaseDecorator, Inject, createDecorator } from "@vercube/di";
5
+ import defu from "defu";
6
+ import { BasePlugin, Controller, Get } from "@vercube/core";
7
+
8
+ //#region rolldown:runtime
9
+ var __create = Object.create;
10
+ var __defProp = Object.defineProperty;
11
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
12
+ var __getOwnPropNames = Object.getOwnPropertyNames;
13
+ var __getProtoOf = Object.getPrototypeOf;
14
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
15
+ var __commonJS = (cb, mod) => function() {
16
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
17
+ };
18
+ var __copyProps = (to, from, except, desc) => {
19
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
20
+ key = keys[i];
21
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
22
+ get: ((k) => from[k]).bind(null, key),
23
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
24
+ });
25
+ }
26
+ return to;
27
+ };
28
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
29
+ value: mod,
30
+ enumerable: true
31
+ }) : target, mod));
32
+
33
+ //#endregion
34
+ //#region src/Services/SchemaRegistry.ts
35
+ /**
36
+ * Manages the OpenAPI schema registry and provides utilities to generate OpenAPI components
37
+ * from registered Zod schemas using the @asteasolutions/zod-to-openapi library.
38
+ *
39
+ * This class is intended to be used for collecting and generating OpenAPI-compatible
40
+ * schema definitions for API documentation and validation purposes.
41
+ */
42
+ var SchemaRegistry = class {
43
+ /**
44
+ * Internal registry instance for storing OpenAPI schema definitions.
45
+ * @private
46
+ */
47
+ fRegistry = new OpenAPIRegistry();
48
+ /**
49
+ * Registers a route configuration with the registry.
50
+ * @param cfg - The route configuration to register.
51
+ */
52
+ register(cfg) {
53
+ this.fRegistry.registerPath(cfg);
54
+ }
55
+ /**
56
+ * Generates OpenAPI components from the registered schemas.
57
+ *
58
+ * @async
59
+ * @returns {Promise<unknown>} A promise that resolves to the generated OpenAPI components object.
60
+ */
61
+ async generateSchema() {
62
+ return new OpenApiGeneratorV3(this.fRegistry.definitions).generateDocument({
63
+ openapi: "3.0.0",
64
+ info: {
65
+ title: "API",
66
+ version: "1.0.0"
67
+ }
68
+ });
69
+ }
70
+ };
71
+
72
+ //#endregion
73
+ //#region src/Resolvers/SchemaBodyResolver.ts
74
+ /**
75
+ * Resolves the body schema for a given method.
76
+ * @param metadata - The metadata of the method.
77
+ * @param schema - The schema to resolve the body for.
78
+ * @returns void
79
+ */
80
+ function SchemaBodyResolver(metadata, schema) {
81
+ const body = metadata.args.find((arg) => arg.type === "body");
82
+ if (!body || !body.validationSchema) return;
83
+ schema.request = defu(schema?.request ?? {}, { body: { content: { "application/json": { schema: body.validationSchema } } } });
84
+ }
85
+
86
+ //#endregion
87
+ //#region src/Resolvers/SchemaQueryParamsResolver.ts
88
+ /**
89
+ * Resolves the query params schema for a given method.
90
+ * @param metadata - The metadata of the method.
91
+ * @param schema - The schema to resolve the query params for.
92
+ * @returns void
93
+ */
94
+ function SchemaQueryParamsResolver(metadata, schema) {
95
+ const query = metadata.args.find((arg) => arg.type === "query-params");
96
+ if (!query || !query.validationSchema) return;
97
+ schema.request = defu(schema?.request ?? {}, { query: query.validationSchema });
98
+ }
99
+
100
+ //#endregion
101
+ //#region ../../node_modules/.pnpm/@oxc-project+runtime@0.77.3/node_modules/@oxc-project/runtime/src/helpers/decorate.js
102
+ var require_decorate = __commonJS({ "../../node_modules/.pnpm/@oxc-project+runtime@0.77.3/node_modules/@oxc-project/runtime/src/helpers/decorate.js"(exports, module) {
103
+ function __decorate(decorators, target, key, desc) {
104
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
105
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
106
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
107
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
108
+ }
109
+ module.exports = __decorate, module.exports.__esModule = true, module.exports["default"] = module.exports;
110
+ } });
111
+
112
+ //#endregion
113
+ //#region src/Decorators/Schema.ts
114
+ var import_decorate$1 = __toESM(require_decorate());
115
+ /**
116
+ * A decorator class for handling OpenAPI schema registration for routes.
117
+ *
118
+ * This class extends BaseDecorator and is used to register route schemas
119
+ * with the SchemaRegistry. It also applies schema resolvers for responses,
120
+ * body, and query parameters.
121
+ *
122
+ * @extends {BaseDecorator<SchemaDecoratorOptions>}
123
+ */
124
+ var SchemaDecorator = class extends BaseDecorator {
125
+ gSchemaRegistry;
126
+ async created() {
127
+ await new Promise((resolve) => setTimeout(resolve, 0));
128
+ const _methodMeta = this.prototype.__metadata.__methods[this.propertyName];
129
+ const _schema = {
130
+ method: _methodMeta.method.toLowerCase(),
131
+ path: _methodMeta.url,
132
+ ...this.options
133
+ };
134
+ SchemaBodyResolver(_methodMeta, _schema);
135
+ SchemaQueryParamsResolver(_methodMeta, _schema);
136
+ this.gSchemaRegistry.register(_schema);
137
+ }
138
+ };
139
+ (0, import_decorate$1.default)([Inject(SchemaRegistry)], SchemaDecorator.prototype, "gSchemaRegistry", void 0);
140
+ /**
141
+ * A decorator function for registering OpenAPI schema metadata for a route.
142
+ *
143
+ * This function creates an instance of the SchemaDecorator class and registers
144
+ * the schema with the specified options.
145
+ *
146
+ * @param {SchemaDecoratorOptions} params - The schema options for the route.
147
+ * @returns {Function} - The decorator function.
148
+ */
149
+ function Schema(params) {
150
+ return createDecorator(SchemaDecorator, params);
151
+ }
152
+
153
+ //#endregion
154
+ //#region src/Controllers/SchameController.ts
155
+ var import_decorate = __toESM(require_decorate(), 1);
156
+ let SchemaController = class SchemaController$1 {
157
+ gSchemaRegistry;
158
+ /**
159
+ * Handles GET requests to retrieve the generated OpenAPI schema.
160
+ *
161
+ * @returns {Promise<unknown>} The generated OpenAPI schema object.
162
+ */
163
+ async get() {
164
+ return this.gSchemaRegistry.generateSchema();
165
+ }
166
+ };
167
+ (0, import_decorate.default)([Inject(SchemaRegistry)], SchemaController.prototype, "gSchemaRegistry", void 0);
168
+ (0, import_decorate.default)([Get("/")], SchemaController.prototype, "get", null);
169
+ SchemaController = (0, import_decorate.default)([Controller("/_schema")], SchemaController);
170
+
171
+ //#endregion
172
+ //#region src/Plugins/SchemaPlugin.ts
173
+ /**
174
+ * Schema Plugin for Vercube framework
175
+ *
176
+ * Provides OpenAPI/Swagger schema generation and validation capabilities:
177
+ * - Automatic OpenAPI schema generation from Zod schemas
178
+ * - Route-level schema validation via @Schema decorator
179
+ * - Runtime schema access via /_schema endpoint
180
+ * - Seamless integration with request validation (@Body, @Query, etc)
181
+ *
182
+ * @example
183
+ * ```ts
184
+ * import { createApp } from '@vercube/core';
185
+ * import { SchemaPlugin } from '@vercube/schema';
186
+ *
187
+ * const app = createApp({
188
+ * setup: async (app) => {
189
+ * app.addPlugin(SchemaPlugin);
190
+ * }
191
+ * });
192
+ * ```
193
+ *
194
+ * @see {@link https://vercube.dev} for full documentation
195
+ */
196
+ var SchemaPlugin = class extends BasePlugin {
197
+ /**
198
+ * The name of the plugin.
199
+ * @override
200
+ */
201
+ name = "SchemaPlugin";
202
+ /**
203
+ * Method to use the plugin with the given app.
204
+ * @param {App} app - The application instance.
205
+ * @returns {void | Promise<void>}
206
+ * @override
207
+ */
208
+ use(app, options) {
209
+ app.container.bind(SchemaRegistry);
210
+ app.container.bind(SchemaController);
211
+ }
212
+ };
213
+
214
+ //#endregion
215
+ //#region src/index.ts
216
+ extendZodWithOpenApi(z);
217
+
218
+ //#endregion
219
+ export { Schema, SchemaPlugin, z };
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@vercube/schema",
3
+ "version": "0.0.19",
4
+ "description": "Schema (swagger) module for Vercube framework",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/vercube/vercube.git",
8
+ "directory": "packages/schema"
9
+ },
10
+ "license": "MIT",
11
+ "sideEffects": false,
12
+ "type": "module",
13
+ "main": "./dist/index.mjs",
14
+ "module": "./dist/index.mjs",
15
+ "exports": {
16
+ ".": "./dist/index.mjs",
17
+ "./package.json": "./package.json"
18
+ },
19
+ "types": "./dist/index.d.mts",
20
+ "files": [
21
+ "dist",
22
+ "README.md"
23
+ ],
24
+ "keywords": [
25
+ "vercube",
26
+ "schema",
27
+ "swagger"
28
+ ],
29
+ "dependencies": {
30
+ "@asteasolutions/zod-to-openapi": "8.0.0",
31
+ "@standard-schema/spec": "1.0.0",
32
+ "defu": "6.1.4",
33
+ "zod": "4.0.10",
34
+ "@vercube/core": "0.0.19",
35
+ "@vercube/di": "0.0.19"
36
+ },
37
+ "publishConfig": {
38
+ "access": "public"
39
+ }
40
+ }