@loydjs/vite 1.0.0 → 1.1.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/README.md +140 -111
- package/dist/index.cjs +5832 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -1
- package/dist/index.d.ts +14 -1
- package/dist/index.js +5822 -15
- package/dist/index.js.map +1 -1
- package/package.json +10 -7
- package/src/plugin.ts +84 -18
- package/src/transform.ts +179 -3
package/README.md
CHANGED
|
@@ -1,171 +1,200 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
|
|
3
|
-
<h1
|
|
3
|
+
<h1>@loydjs/vite</h1>
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
<p><strong>AOT compilation plugin for Vite and Rollup.</strong><br/>
|
|
6
|
+
Replaces compile() calls with flat inline validators at build time · Zero runtime overhead.</p>
|
|
7
7
|
|
|
8
8
|
[](https://github.com/b3nito404/loyd/actions/workflows/ci.yml)
|
|
9
9
|
[](https://opensource.org/licenses/MIT)
|
|
10
|
-
[](https://bundlephobia.com/package/@loydjs/vite)
|
|
11
11
|
[](https://www.typescriptlang.org)
|
|
12
|
-
[](https://www.npmjs.com/package/@loydjs/vite)
|
|
13
13
|
|
|
14
14
|
</div>
|
|
15
15
|
|
|
16
16
|
---
|
|
17
17
|
|
|
18
|
-
##
|
|
18
|
+
## Overview
|
|
19
|
+
|
|
20
|
+
`@loydjs/vite` is a Vite and Rollup plugin that performs Ahead-of-Time (AOT) compilation of Loyd schemas. When enabled, it replaces `compile(schema)` calls in your source code with the flat inline validator functions at build time — so your production bundle contains zero compilation overhead and no dependency on `@loydjs/compiler` at runtime.
|
|
19
21
|
|
|
20
|
-
|
|
21
|
-
- **JIT compiler** : `compile(schema)` generates a pure JavaScript function via `new Function()`; subsequent calls are **2× faster** than `safeParse` on hot paths
|
|
22
|
-
- **Structured i18n** : validators emit `{ code, path, meta }`, never locale strings; swap locales at runtime without touching your schemas
|
|
23
|
-
- **Two-pass async pipeline** : sync rules execute first; async rules only if sync passes; multiple async rules run in parallel via `Promise.all`
|
|
24
|
-
- **Field dependency graph** : `buildDag(schema, deps)` enables incremental revalidation; change one field -> revalidate only it and its dependents
|
|
25
|
-
- **Native React integration** : `useForm`, `useField`, `useFieldArray` with zero external dependencies, backed by the DAG
|
|
22
|
+
In development, the plugin is a no-op — JIT compilation runs as normal for fast HMR.
|
|
26
23
|
|
|
27
24
|
---
|
|
28
25
|
|
|
29
26
|
## Installation
|
|
30
27
|
|
|
31
28
|
```sh
|
|
32
|
-
|
|
33
|
-
npm install @loydjs/schema @loydjs/core @loydjs/types
|
|
34
|
-
|
|
35
|
-
# Optional packages
|
|
36
|
-
npm install @loydjs/async # two-pass async pipeline
|
|
37
|
-
npm install @loydjs/compiler # JIT compilation
|
|
38
|
-
npm install @loydjs/error-engine # structured i18n
|
|
39
|
-
npm install @loydjs/react # React hooks (requires @loydjs/graph)
|
|
40
|
-
npm install @loydjs/graph # field dependency DAG
|
|
41
|
-
npm install @loydjs/zod-compat # Zod migration utilities
|
|
42
|
-
npm install @loydjs/openapi # OpenAPI 3.1 / JSON Schema export
|
|
43
|
-
npm install @loydjs/vite # Vite / Rollup AOT plugin
|
|
29
|
+
npm install @loydjs/vite
|
|
44
30
|
```
|
|
45
|
-
|
|
31
|
+
|
|
32
|
+
> **Requires** `@loydjs/core` · `@loydjs/compiler` · Vite ≥ 5.0.0 · Node.js ≥ 20 · TypeScript ≥ 5.4
|
|
46
33
|
|
|
47
34
|
---
|
|
48
35
|
|
|
49
|
-
##
|
|
36
|
+
## Setup
|
|
37
|
+
|
|
38
|
+
### Vite
|
|
50
39
|
|
|
51
40
|
```ts
|
|
52
|
-
|
|
53
|
-
import {
|
|
54
|
-
import
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
41
|
+
// vite.config.ts
|
|
42
|
+
import { defineConfig } from "vite";
|
|
43
|
+
import { loydPlugin } from "@loydjs/vite";
|
|
44
|
+
|
|
45
|
+
export default defineConfig({
|
|
46
|
+
plugins: [
|
|
47
|
+
loydPlugin({
|
|
48
|
+
// Schemas to resolve statically at build time.
|
|
49
|
+
// Key = variable name as it appears in your source code.
|
|
50
|
+
schemas: {
|
|
51
|
+
UserSchema,
|
|
52
|
+
PostSchema,
|
|
53
|
+
CommentSchema,
|
|
54
|
+
},
|
|
55
|
+
}),
|
|
56
|
+
],
|
|
61
57
|
});
|
|
62
|
-
|
|
63
|
-
// 2. Infer the TypeScript type - zero runtime cost
|
|
64
|
-
type User = Infer<typeof UserSchema>;
|
|
65
|
-
// -> { name: string; email: string; age: number }
|
|
66
|
-
|
|
67
|
-
// 3a. parse() throws LoydError on failure
|
|
68
|
-
const user = parse(UserSchema, req.body);
|
|
69
|
-
|
|
70
|
-
// 3b. safeParse() never throws
|
|
71
|
-
const result = safeParse(UserSchema, formData);
|
|
72
|
-
if (result.success) {
|
|
73
|
-
console.log(result.data.name); // typed as User
|
|
74
|
-
} else {
|
|
75
|
-
result.issues.forEach(issue => {
|
|
76
|
-
console.log(issue.code); // "ERR_STRING_TOO_SHORT"
|
|
77
|
-
console.log(issue.path); // ["name"]
|
|
78
|
-
console.log(issue.meta); // { min: 2, actual: 1 }
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
58
|
```
|
|
82
59
|
|
|
83
|
-
###
|
|
84
|
-
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
return (
|
|
96
|
-
<form onSubmit={handleSubmit(onValid, onInvalid)}>
|
|
97
|
-
<input {...register("email")} type="email" />
|
|
98
|
-
<input {...register("password")} type="password" />
|
|
99
|
-
<button type="submit" disabled={state.isSubmitting}>Sign in</button>
|
|
100
|
-
</form>
|
|
101
|
-
);
|
|
102
|
-
}
|
|
60
|
+
### Rollup
|
|
61
|
+
|
|
62
|
+
```js
|
|
63
|
+
// rollup.config.js
|
|
64
|
+
import { loydPlugin } from "@loydjs/vite";
|
|
65
|
+
|
|
66
|
+
export default {
|
|
67
|
+
input: "src/index.ts",
|
|
68
|
+
plugins: [
|
|
69
|
+
loydPlugin({ schemas: { UserSchema } }),
|
|
70
|
+
],
|
|
71
|
+
};
|
|
103
72
|
```
|
|
104
73
|
|
|
105
|
-
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## How it works
|
|
77
|
+
|
|
78
|
+
Your source code, untouched:
|
|
106
79
|
|
|
107
80
|
```ts
|
|
108
81
|
import { compile } from "@loydjs/compiler";
|
|
82
|
+
import { UserSchema } from "./schemas";
|
|
109
83
|
|
|
110
84
|
const validate = compile(UserSchema);
|
|
85
|
+
const result = validate(req.body);
|
|
86
|
+
```
|
|
111
87
|
|
|
112
|
-
|
|
113
|
-
|
|
88
|
+
After AOT transform — what ships in your production bundle:
|
|
89
|
+
|
|
90
|
+
```js
|
|
91
|
+
// @loydjs/compiler: AOT-inlined validator for UserSchema
|
|
92
|
+
function __loyd_UserSchema__(input) {
|
|
93
|
+
"use strict";
|
|
94
|
+
let __input__ = input;
|
|
95
|
+
const __issues__ = [];
|
|
96
|
+
if (typeof __input__ !== "object" || __input__ === null || Array.isArray(__input__)) {
|
|
97
|
+
__issues__.push({ code: "ERR_OBJECT_INVALID_TYPE", path: [] });
|
|
98
|
+
} else {
|
|
99
|
+
const __fname__ = __input__["name"];
|
|
100
|
+
if (typeof __fname__ !== "string") {
|
|
101
|
+
__issues__.push({ code: "ERR_STRING_INVALID_TYPE", path: ["name"] });
|
|
102
|
+
} else {
|
|
103
|
+
if (__fname__.length < 2) { __issues__.push({ code: "ERR_STRING_TOO_SHORT", path: ["name"], meta: { min: 2, actual: __fname__.length } }); }
|
|
104
|
+
if (__fname__.length > 100) { __issues__.push({ code: "ERR_STRING_TOO_LONG", path: ["name"], meta: { max: 100, actual: __fname__.length } }); }
|
|
105
|
+
}
|
|
106
|
+
// ...
|
|
107
|
+
}
|
|
108
|
+
if (__issues__.length > 0) return { success: false, data: undefined, issues: __issues__ };
|
|
109
|
+
return { success: true, data: __input__, issues: [] };
|
|
110
|
+
}
|
|
111
|
+
const validate = __loyd_UserSchema__;
|
|
112
|
+
const result = validate(req.body);
|
|
114
113
|
```
|
|
115
114
|
|
|
116
|
-
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Plugin options
|
|
117
118
|
|
|
118
119
|
```ts
|
|
119
|
-
|
|
120
|
+
interface LoydVitePluginOptions {
|
|
121
|
+
/**
|
|
122
|
+
* Schemas to resolve statically at build time.
|
|
123
|
+
* Key = variable name as it appears in source code.
|
|
124
|
+
*/
|
|
125
|
+
schemas?: Record<string, LoydSchema<unknown>>;
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Enable/disable the plugin entirely.
|
|
129
|
+
* @default true
|
|
130
|
+
*/
|
|
131
|
+
enabled?: boolean;
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Log transformed files.
|
|
135
|
+
* @default false
|
|
136
|
+
*/
|
|
137
|
+
verbose?: boolean;
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Force AOT even in development mode.
|
|
141
|
+
* By default, AOT is only active during production builds.
|
|
142
|
+
* @default false
|
|
143
|
+
*/
|
|
144
|
+
forceAot?: boolean;
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Generate sourcemaps for transformed files.
|
|
148
|
+
* @default true
|
|
149
|
+
*/
|
|
150
|
+
sourcemap?: boolean;
|
|
151
|
+
}
|
|
152
|
+
```
|
|
120
153
|
|
|
121
|
-
|
|
122
|
-
configureFormatter("fr", fr);
|
|
154
|
+
---
|
|
123
155
|
|
|
124
|
-
|
|
125
|
-
const result = safeParse(UserSchema, badInput);
|
|
126
|
-
// result.issues[0].message -> "Minimum 2 caractères (reçu : 1)"
|
|
127
|
-
```
|
|
156
|
+
## Emit standalone validators
|
|
128
157
|
|
|
129
|
-
|
|
158
|
+
Use the `emit()` function from `@loydjs/compiler` to generate standalone `.js` + `.d.ts` validator files, independent of the Vite plugin.
|
|
130
159
|
|
|
131
160
|
```ts
|
|
132
|
-
import {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
161
|
+
import { emit } from "@loydjs/compiler";
|
|
162
|
+
import { UserSchema } from "./schemas";
|
|
163
|
+
|
|
164
|
+
await emit(UserSchema, {
|
|
165
|
+
outFile: "./dist/validators/user.js",
|
|
166
|
+
exportName: "validateUser",
|
|
167
|
+
format: "esm",
|
|
168
|
+
dts: true,
|
|
169
|
+
});
|
|
136
170
|
|
|
137
|
-
//
|
|
138
|
-
|
|
171
|
+
// dist/validators/user.js — flat inline validator, no imports
|
|
172
|
+
// dist/validators/user.d.ts — TypeScript declarations
|
|
139
173
|
```
|
|
140
174
|
|
|
141
175
|
---
|
|
142
176
|
|
|
143
|
-
##
|
|
144
|
-
|
|
145
|
-
| Package |
|
|
146
|
-
|
|
147
|
-
| `@loydjs/core` | `
|
|
148
|
-
| `@loydjs/
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
|
153
|
-
|
|
154
|
-
|
|
|
155
|
-
| `@loydjs/zod-compat` | `fromZod`, `toZod`, `runCodemod` | ~5 kb |
|
|
156
|
-
| `@loydjs/openapi` | `toOpenApi`, `toJsonSchema`, `toOpenApiComponents` | ~4 kb |
|
|
157
|
-
| `@loydjs/vite` | `loydPlugin()` - Vite/Rollup AOT compilation | ~2 kb |
|
|
177
|
+
## Dependencies
|
|
178
|
+
|
|
179
|
+
| Package | Role |
|
|
180
|
+
|:---|:---|
|
|
181
|
+
| `@loydjs/core` | `LoydSchema` type |
|
|
182
|
+
| `@loydjs/compiler` | `generateCode`, `optimize` for AOT codegen |
|
|
183
|
+
|
|
184
|
+
## Peer dependencies
|
|
185
|
+
|
|
186
|
+
| Package | Version |
|
|
187
|
+
|:---|:---|
|
|
188
|
+
| `vite` | ≥ 5.0.0 |
|
|
158
189
|
|
|
159
190
|
---
|
|
160
191
|
|
|
161
192
|
## Documentation
|
|
162
193
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
**[https://loyddev-psi.vercel.app](https://loyddev-psi.vercel.app)**
|
|
194
|
+
**[loyddev-psi.vercel.app](https://loyddev-psi.vercel.app)**
|
|
166
195
|
|
|
167
196
|
---
|
|
168
197
|
|
|
169
198
|
## License
|
|
170
199
|
|
|
171
|
-
MIT
|
|
200
|
+
MIT © [b3nito404](https://github.com/b3nito404)
|