yuppi 1.2.12 → 1.3.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 +33 -55
- package/dist/main.d.mts +2 -0
- package/dist/main.d.ts +2 -0
- package/dist/main.js +86 -67
- package/dist/main.mjs +86 -67
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -99,6 +99,7 @@ Yuppi
|
|
|
99
99
|
├── new Yuppi(options?)
|
|
100
100
|
│ │
|
|
101
101
|
│ ├── validate(schema, properties)
|
|
102
|
+
│ ├── declare(schema, name)
|
|
102
103
|
│ ├── convertToYup(schema)
|
|
103
104
|
│ └── convertToJSONSchema(schema)
|
|
104
105
|
│
|
|
@@ -209,6 +210,36 @@ Validate the properties with your Yuppi schema.
|
|
|
209
210
|
|
|
210
211
|
<br/>
|
|
211
212
|
|
|
213
|
+
`Yuppi.declare(schema, name)`
|
|
214
|
+
|
|
215
|
+
Declare your Yuppi schema for TypeScript.
|
|
216
|
+
|
|
217
|
+
> | Parameter | Default | Description |
|
|
218
|
+
> | --------- | ------- | ------------------------------ |
|
|
219
|
+
> | schema | | [Schema]<br/>Yuppi schema. |
|
|
220
|
+
> | name | | [String]<br/>Declaration name. |
|
|
221
|
+
>
|
|
222
|
+
> returns [Void]
|
|
223
|
+
>
|
|
224
|
+
> Example:
|
|
225
|
+
>
|
|
226
|
+
> ```typescript
|
|
227
|
+
> import type { User } from './yuppi/types/user';
|
|
228
|
+
>
|
|
229
|
+
> Yupp.declare(schema, 'user');
|
|
230
|
+
>
|
|
231
|
+
> const user = Yupp.validate(schema, properties) as User;
|
|
232
|
+
> /*
|
|
233
|
+
> interface User {
|
|
234
|
+
> display_name: string;
|
|
235
|
+
> username: string;
|
|
236
|
+
> email: string;
|
|
237
|
+
> }
|
|
238
|
+
> */
|
|
239
|
+
> ```
|
|
240
|
+
|
|
241
|
+
<br/>
|
|
242
|
+
|
|
212
243
|
`Yuppi.convertToYup(schema)`
|
|
213
244
|
|
|
214
245
|
Convert your Yuppi schema into Yup schema.
|
|
@@ -222,33 +253,6 @@ Convert your Yuppi schema into Yup schema.
|
|
|
222
253
|
> Example:
|
|
223
254
|
>
|
|
224
255
|
> ```typescript
|
|
225
|
-
> const schema: Schema = {
|
|
226
|
-
> display_name: {
|
|
227
|
-
> type: 'string',
|
|
228
|
-
> min: 1,
|
|
229
|
-
> max: 32,
|
|
230
|
-
> nullable: false,
|
|
231
|
-
> required: true
|
|
232
|
-
> },
|
|
233
|
-
>
|
|
234
|
-
> username: {
|
|
235
|
-
> type: 'string',
|
|
236
|
-
> min: 3,
|
|
237
|
-
> max: 16,
|
|
238
|
-
> pattern: Patterns.Username,
|
|
239
|
-
> nullable: false,
|
|
240
|
-
> required: true
|
|
241
|
-
> },
|
|
242
|
-
>
|
|
243
|
-
> email: {
|
|
244
|
-
> type: 'string',
|
|
245
|
-
> pattern: Patterns.Email,
|
|
246
|
-
> lowercase: true,
|
|
247
|
-
> nullable: false,
|
|
248
|
-
> required: true
|
|
249
|
-
> }
|
|
250
|
-
> };
|
|
251
|
-
>
|
|
252
256
|
> Yupp.convertToYup(schema);
|
|
253
257
|
> ```
|
|
254
258
|
|
|
@@ -267,33 +271,6 @@ Convert your Yuppi schema into [JSON Schema](https://json-schema.org).
|
|
|
267
271
|
> Example:
|
|
268
272
|
>
|
|
269
273
|
> ```typescript
|
|
270
|
-
> const schema: Schema = {
|
|
271
|
-
> display_name: {
|
|
272
|
-
> type: 'string',
|
|
273
|
-
> min: 1,
|
|
274
|
-
> max: 32,
|
|
275
|
-
> nullable: false,
|
|
276
|
-
> required: true
|
|
277
|
-
> },
|
|
278
|
-
>
|
|
279
|
-
> username: {
|
|
280
|
-
> type: 'string',
|
|
281
|
-
> min: 3,
|
|
282
|
-
> max: 16,
|
|
283
|
-
> pattern: Patterns.Username,
|
|
284
|
-
> nullable: false,
|
|
285
|
-
> required: true
|
|
286
|
-
> },
|
|
287
|
-
>
|
|
288
|
-
> email: {
|
|
289
|
-
> type: 'string',
|
|
290
|
-
> pattern: Patterns.Email,
|
|
291
|
-
> lowercase: true,
|
|
292
|
-
> nullable: false,
|
|
293
|
-
> required: true
|
|
294
|
-
> }
|
|
295
|
-
> };
|
|
296
|
-
>
|
|
297
274
|
> Yupp.convertToJSONSchema(schema);
|
|
298
275
|
> /*
|
|
299
276
|
> {
|
|
@@ -319,7 +296,8 @@ Convert your Yuppi schema into [JSON Schema](https://json-schema.org).
|
|
|
319
296
|
> "display_name",
|
|
320
297
|
> "username",
|
|
321
298
|
> "email"
|
|
322
|
-
> ]
|
|
299
|
+
> ],
|
|
300
|
+
> additionalProperties: false
|
|
323
301
|
> }
|
|
324
302
|
> */
|
|
325
303
|
> ```
|
package/dist/main.d.mts
CHANGED
|
@@ -66,6 +66,7 @@ type Schema = Record<string, Types>;
|
|
|
66
66
|
type ValidateOptions = ValidateOptions$1;
|
|
67
67
|
|
|
68
68
|
type YuppiOptions = {
|
|
69
|
+
folder_path?: string;
|
|
69
70
|
error_messages?: {
|
|
70
71
|
base?: {
|
|
71
72
|
nullable?: string;
|
|
@@ -114,6 +115,7 @@ declare class Yuppi {
|
|
|
114
115
|
[x: string]: any;
|
|
115
116
|
[x: number]: any;
|
|
116
117
|
};
|
|
118
|
+
declare(schema: Schema, name: string): void;
|
|
117
119
|
convertToYup(schema: Schema): yup.ObjectSchema<{
|
|
118
120
|
[x: string]: any;
|
|
119
121
|
}, yup.AnyObject, {
|
package/dist/main.d.ts
CHANGED
|
@@ -66,6 +66,7 @@ type Schema = Record<string, Types>;
|
|
|
66
66
|
type ValidateOptions = ValidateOptions$1;
|
|
67
67
|
|
|
68
68
|
type YuppiOptions = {
|
|
69
|
+
folder_path?: string;
|
|
69
70
|
error_messages?: {
|
|
70
71
|
base?: {
|
|
71
72
|
nullable?: string;
|
|
@@ -114,6 +115,7 @@ declare class Yuppi {
|
|
|
114
115
|
[x: string]: any;
|
|
115
116
|
[x: number]: any;
|
|
116
117
|
};
|
|
118
|
+
declare(schema: Schema, name: string): void;
|
|
117
119
|
convertToYup(schema: Schema): yup.ObjectSchema<{
|
|
118
120
|
[x: string]: any;
|
|
119
121
|
}, yup.AnyObject, {
|
package/dist/main.js
CHANGED
|
@@ -36,7 +36,53 @@ __export(main_exports, {
|
|
|
36
36
|
module.exports = __toCommonJS(main_exports);
|
|
37
37
|
|
|
38
38
|
// src/Yuppi.class.ts
|
|
39
|
+
var import_json_schema_to_typescript = require("json-schema-to-typescript");
|
|
39
40
|
var import_lodash = __toESM(require("lodash"));
|
|
41
|
+
var import_fs = __toESM(require("fs"));
|
|
42
|
+
var import_path = __toESM(require("path"));
|
|
43
|
+
|
|
44
|
+
// src/utils/ConvertToJSONSchema.util.ts
|
|
45
|
+
var import_typebox = require("@sinclair/typebox");
|
|
46
|
+
var convertToJSONSchema = (schema) => {
|
|
47
|
+
const base = (schema2, key, config) => {
|
|
48
|
+
if (!config.required) schema2 = import_typebox.Type.Optional(schema2);
|
|
49
|
+
if (config.nullable || config.default === null) schema2 = import_typebox.Type.Union([schema2, import_typebox.Type.Null()]);
|
|
50
|
+
return schema2;
|
|
51
|
+
};
|
|
52
|
+
const build = (key, config) => {
|
|
53
|
+
let schema2;
|
|
54
|
+
if (config.type === "string") {
|
|
55
|
+
schema2 = import_typebox.Type.String({ enum: config.enum, minLength: config.min, maxLength: config.max, pattern: config.pattern ? new RegExp(config.pattern).source : void 0, default: config.default });
|
|
56
|
+
schema2 = base(schema2, key, config);
|
|
57
|
+
return schema2;
|
|
58
|
+
} else if (config.type === "number") {
|
|
59
|
+
schema2 = config.integer === true ? import_typebox.Type.Integer({ enum: config.enum, minimum: config.min, maximum: config.max, default: config.default }) : import_typebox.Type.Number({ enum: config.enum, minimum: config.min, maximum: config.max, default: config.default });
|
|
60
|
+
schema2 = base(schema2, key, config);
|
|
61
|
+
return schema2;
|
|
62
|
+
} else if (config.type === "boolean") {
|
|
63
|
+
schema2 = import_typebox.Type.Boolean({ default: config.default });
|
|
64
|
+
schema2 = base(schema2, key, config);
|
|
65
|
+
return schema2;
|
|
66
|
+
} else if (config.type === "date") {
|
|
67
|
+
schema2 = import_typebox.Type.String({ format: "date-time", minimum: config.min, maximum: config.max, default: config.default });
|
|
68
|
+
schema2 = base(schema2, key, config);
|
|
69
|
+
return schema2;
|
|
70
|
+
} else if (config.type === "object") {
|
|
71
|
+
const nested_properties = {};
|
|
72
|
+
for (const [nested_key, nested_config] of Object.entries(config.properties)) nested_properties[nested_key] = build(nested_key, nested_config);
|
|
73
|
+
schema2 = import_typebox.Type.Object(nested_properties, { additionalProperties: false });
|
|
74
|
+
schema2 = base(schema2, key, config);
|
|
75
|
+
return schema2;
|
|
76
|
+
} else if (config.type === "array") {
|
|
77
|
+
schema2 = import_typebox.Type.Array(build(key, config.items), { minItems: config.min, maxItems: config.max, default: config.default });
|
|
78
|
+
schema2 = base(schema2, key, config);
|
|
79
|
+
return schema2;
|
|
80
|
+
} else throw new Error(`Unsupported schema type for ${key}`);
|
|
81
|
+
};
|
|
82
|
+
const properties = {};
|
|
83
|
+
for (const [key, config] of Object.entries(schema)) properties[key] = build(key, config);
|
|
84
|
+
return import_typebox.Type.Object(properties, { additionalProperties: false });
|
|
85
|
+
};
|
|
40
86
|
|
|
41
87
|
// src/utils/ConvertToYup.util.ts
|
|
42
88
|
var Yup = __toESM(require("yup"));
|
|
@@ -46,7 +92,7 @@ var convertToYup = (schema, error_messages) => {
|
|
|
46
92
|
if (config.required)
|
|
47
93
|
schema2 = schema2.test(
|
|
48
94
|
"required",
|
|
49
|
-
({ path }) => (error_messages?.base?.required ?? "").replaceAll("{path}",
|
|
95
|
+
({ path: path2 }) => (error_messages?.base?.required ?? "").replaceAll("{path}", path2),
|
|
50
96
|
(property) => {
|
|
51
97
|
if (property === void 0) return false;
|
|
52
98
|
if (typeof property === "string" && property.trim() === "") return false;
|
|
@@ -54,74 +100,74 @@ var convertToYup = (schema, error_messages) => {
|
|
|
54
100
|
return true;
|
|
55
101
|
}
|
|
56
102
|
);
|
|
57
|
-
if (!config.nullable && config.default !== null) schema2 = schema2.nonNullable(({ path }) => (error_messages?.base?.nullable ?? "").replaceAll("{path}",
|
|
103
|
+
if (!config.nullable && config.default !== null) schema2 = schema2.nonNullable(({ path: path2 }) => (error_messages?.base?.nullable ?? "").replaceAll("{path}", path2));
|
|
58
104
|
if (config.default) schema2 = schema2.default(config.default);
|
|
59
105
|
return schema2;
|
|
60
106
|
};
|
|
61
107
|
const build = (key, config) => {
|
|
62
108
|
let schema2;
|
|
63
109
|
if (config.type === "string") {
|
|
64
|
-
schema2 = Yup.string().typeError(({ path }) => (error_messages?.string?.type ?? "").replaceAll("{path}",
|
|
110
|
+
schema2 = Yup.string().typeError(({ path: path2 }) => (error_messages?.string?.type ?? "").replaceAll("{path}", path2));
|
|
65
111
|
schema2 = base(schema2, key, config);
|
|
66
112
|
schema2 = schema2.transform((property) => typeof property === "string" ? property.trim() : property);
|
|
67
113
|
if (config.enum)
|
|
68
114
|
schema2 = schema2.oneOf(
|
|
69
115
|
config.enum.map((item) => item.trim()),
|
|
70
|
-
({ path }) => (error_messages?.string?.enum ?? "").replaceAll("{path}",
|
|
116
|
+
({ path: path2 }) => (error_messages?.string?.enum ?? "").replaceAll("{path}", path2)
|
|
71
117
|
);
|
|
72
|
-
if (config.pattern) schema2 = schema2.matches(new RegExp(config.pattern), ({ path }) => (error_messages?.string?.pattern ?? "").replaceAll("{path}",
|
|
118
|
+
if (config.pattern) schema2 = schema2.matches(new RegExp(config.pattern), ({ path: path2 }) => (error_messages?.string?.pattern ?? "").replaceAll("{path}", path2).replaceAll("{pattern}", config.pattern ? new RegExp(config.pattern).source : ""));
|
|
73
119
|
if (config.min)
|
|
74
120
|
schema2 = schema2.min(
|
|
75
121
|
config.min,
|
|
76
|
-
({ path, min }) => (error_messages?.string?.min ?? "").replaceAll("{path}",
|
|
122
|
+
({ path: path2, min }) => (error_messages?.string?.min ?? "").replaceAll("{path}", path2).replaceAll("{min}", min.toString()).replaceAll("{plural_suffix}", min > 1 ? "s" : "")
|
|
77
123
|
);
|
|
78
124
|
if (config.max)
|
|
79
125
|
schema2 = schema2.max(
|
|
80
126
|
config.max,
|
|
81
|
-
({ path, max }) => (error_messages?.string?.max ?? "").replaceAll("{path}",
|
|
127
|
+
({ path: path2, max }) => (error_messages?.string?.max ?? "").replaceAll("{path}", path2).replaceAll("{max}", max.toString()).replaceAll("{plural_suffix}", max > 1 ? "s" : "")
|
|
82
128
|
);
|
|
83
129
|
if (config.lowercase) schema2 = schema2.transform((property) => typeof property === "string" ? property.toLowerCase() : property);
|
|
84
130
|
if (config.uppercase) schema2 = schema2.transform((property) => typeof property === "string" ? property.toUpperCase() : property);
|
|
85
131
|
return schema2;
|
|
86
132
|
} else if (config.type === "number") {
|
|
87
|
-
schema2 = Yup.number().typeError(({ path }) => (error_messages?.number?.type ?? "").replaceAll("{path}",
|
|
133
|
+
schema2 = Yup.number().typeError(({ path: path2 }) => (error_messages?.number?.type ?? "").replaceAll("{path}", path2));
|
|
88
134
|
schema2 = base(schema2, key, config);
|
|
89
|
-
if (config.enum) schema2 = schema2.oneOf(config.enum, ({ path }) => (error_messages?.number?.enum ?? "").replaceAll("{path}",
|
|
90
|
-
if (config.min) schema2 = schema2.min(config.min, ({ path, min }) => (error_messages?.number?.min ?? "").replaceAll("{path}",
|
|
91
|
-
if (config.max) schema2 = schema2.max(config.max, ({ path, max }) => (error_messages?.number?.max ?? "").replaceAll("{path}",
|
|
92
|
-
if (config.integer) schema2 = schema2.integer(({ path }) => (error_messages?.number?.integer ?? "").replaceAll("{path}",
|
|
93
|
-
if (config.positive) schema2 = schema2.positive(({ path }) => (error_messages?.number?.positive ?? "").replaceAll("{path}",
|
|
94
|
-
if (config.negative) schema2 = schema2.negative(({ path }) => (error_messages?.number?.negative ?? "").replaceAll("{path}",
|
|
135
|
+
if (config.enum) schema2 = schema2.oneOf(config.enum, ({ path: path2 }) => (error_messages?.number?.enum ?? "").replaceAll("{path}", path2));
|
|
136
|
+
if (config.min) schema2 = schema2.min(config.min, ({ path: path2, min }) => (error_messages?.number?.min ?? "").replaceAll("{path}", path2).replaceAll("{min}", min.toString()));
|
|
137
|
+
if (config.max) schema2 = schema2.max(config.max, ({ path: path2, max }) => (error_messages?.number?.max ?? "").replaceAll("{path}", path2).replaceAll("{max}", max.toString()));
|
|
138
|
+
if (config.integer) schema2 = schema2.integer(({ path: path2 }) => (error_messages?.number?.integer ?? "").replaceAll("{path}", path2));
|
|
139
|
+
if (config.positive) schema2 = schema2.positive(({ path: path2 }) => (error_messages?.number?.positive ?? "").replaceAll("{path}", path2));
|
|
140
|
+
if (config.negative) schema2 = schema2.negative(({ path: path2 }) => (error_messages?.number?.negative ?? "").replaceAll("{path}", path2));
|
|
95
141
|
return schema2;
|
|
96
142
|
} else if (config.type === "boolean") {
|
|
97
|
-
schema2 = Yup.boolean().typeError(({ path }) => (error_messages?.boolean?.type ?? "").replaceAll("{path}",
|
|
143
|
+
schema2 = Yup.boolean().typeError(({ path: path2 }) => (error_messages?.boolean?.type ?? "").replaceAll("{path}", path2));
|
|
98
144
|
schema2 = base(schema2, key, config);
|
|
99
145
|
return schema2;
|
|
100
146
|
} else if (config.type === "date") {
|
|
101
|
-
schema2 = Yup.date().typeError(({ path }) => (error_messages?.date?.type ?? "").replaceAll("{path}",
|
|
147
|
+
schema2 = Yup.date().typeError(({ path: path2 }) => (error_messages?.date?.type ?? "").replaceAll("{path}", path2));
|
|
102
148
|
schema2 = base(schema2, key, config);
|
|
103
|
-
if (config.min) schema2 = schema2.min(config.min, ({ path, min }) => (error_messages?.date?.min ?? "").replaceAll("{path}",
|
|
104
|
-
if (config.max) schema2 = schema2.max(config.max, ({ path, max }) => (error_messages?.date?.max ?? "").replaceAll("{path}",
|
|
149
|
+
if (config.min) schema2 = schema2.min(config.min, ({ path: path2, min }) => (error_messages?.date?.min ?? "").replaceAll("{path}", path2).replaceAll("{min}", new Date(min).toISOString()));
|
|
150
|
+
if (config.max) schema2 = schema2.max(config.max, ({ path: path2, max }) => (error_messages?.date?.max ?? "").replaceAll("{path}", path2).replaceAll("{max}", new Date(max).toISOString()));
|
|
105
151
|
return schema2;
|
|
106
152
|
} else if (config.type === "object") {
|
|
107
|
-
schema2 = Yup.object().typeError(({ path }) => (error_messages?.object?.type ?? "").replaceAll("{path}",
|
|
153
|
+
schema2 = Yup.object().typeError(({ path: path2 }) => (error_messages?.object?.type ?? "").replaceAll("{path}", path2));
|
|
108
154
|
schema2 = base(schema2, key, config);
|
|
109
155
|
const nested_properties = {};
|
|
110
156
|
for (const [nested_key, nested_config] of Object.entries(config.properties)) nested_properties[nested_key] = build(nested_key, nested_config);
|
|
111
157
|
schema2 = schema2.shape(nested_properties);
|
|
112
158
|
return schema2;
|
|
113
159
|
} else if (config.type === "array") {
|
|
114
|
-
schema2 = Yup.array().typeError(({ path }) => (error_messages?.array?.type ?? "").replaceAll("{path}",
|
|
160
|
+
schema2 = Yup.array().typeError(({ path: path2 }) => (error_messages?.array?.type ?? "").replaceAll("{path}", path2));
|
|
115
161
|
schema2 = base(schema2, key, config);
|
|
116
162
|
if (config.min)
|
|
117
163
|
schema2 = schema2.min(
|
|
118
164
|
config.min,
|
|
119
|
-
({ path, min }) => (error_messages?.array?.min ?? "").replaceAll("{path}",
|
|
165
|
+
({ path: path2, min }) => (error_messages?.array?.min ?? "").replaceAll("{path}", path2).replaceAll("{min}", min.toString()).replaceAll("{plural_suffix}", min > 1 ? "s" : "")
|
|
120
166
|
);
|
|
121
167
|
if (config.max)
|
|
122
168
|
schema2 = schema2.max(
|
|
123
169
|
config.max,
|
|
124
|
-
({ path, max }) => (error_messages?.array?.max ?? "").replaceAll("{path}",
|
|
170
|
+
({ path: path2, max }) => (error_messages?.array?.max ?? "").replaceAll("{path}", path2).replaceAll("{max}", max.toString()).replaceAll("{plural_suffix}", max > 1 ? "s" : "")
|
|
125
171
|
);
|
|
126
172
|
schema2 = schema2.of(build(key, config.items));
|
|
127
173
|
return schema2;
|
|
@@ -132,51 +178,9 @@ var convertToYup = (schema, error_messages) => {
|
|
|
132
178
|
return Yup.object().shape(properties);
|
|
133
179
|
};
|
|
134
180
|
|
|
135
|
-
// src/utils/ConvertToJSONSchema.util.ts
|
|
136
|
-
var import_typebox = require("@sinclair/typebox");
|
|
137
|
-
var convertToJSONSchema = (schema) => {
|
|
138
|
-
const base = (schema2, key, config) => {
|
|
139
|
-
if (!config.required) schema2 = import_typebox.Type.Optional(schema2);
|
|
140
|
-
if (config.nullable || config.default === null) schema2 = import_typebox.Type.Union([schema2, import_typebox.Type.Null()]);
|
|
141
|
-
return schema2;
|
|
142
|
-
};
|
|
143
|
-
const build = (key, config) => {
|
|
144
|
-
let schema2;
|
|
145
|
-
if (config.type === "string") {
|
|
146
|
-
schema2 = import_typebox.Type.String({ enum: config.enum, minLength: config.min, maxLength: config.max, pattern: config.pattern ? new RegExp(config.pattern).source : void 0, default: config.default });
|
|
147
|
-
schema2 = base(schema2, key, config);
|
|
148
|
-
return schema2;
|
|
149
|
-
} else if (config.type === "number") {
|
|
150
|
-
schema2 = config.integer === true ? import_typebox.Type.Integer({ enum: config.enum, minimum: config.min, maximum: config.max, default: config.default }) : import_typebox.Type.Number({ enum: config.enum, minimum: config.min, maximum: config.max, default: config.default });
|
|
151
|
-
schema2 = base(schema2, key, config);
|
|
152
|
-
return schema2;
|
|
153
|
-
} else if (config.type === "boolean") {
|
|
154
|
-
schema2 = import_typebox.Type.Boolean({ default: config.default });
|
|
155
|
-
schema2 = base(schema2, key, config);
|
|
156
|
-
return schema2;
|
|
157
|
-
} else if (config.type === "date") {
|
|
158
|
-
schema2 = import_typebox.Type.String({ format: "date-time", minimum: config.min, maximum: config.max, default: config.default });
|
|
159
|
-
schema2 = base(schema2, key, config);
|
|
160
|
-
return schema2;
|
|
161
|
-
} else if (config.type === "object") {
|
|
162
|
-
const nested_properties = {};
|
|
163
|
-
for (const [nested_key, nested_config] of Object.entries(config.properties)) nested_properties[nested_key] = build(nested_key, nested_config);
|
|
164
|
-
schema2 = import_typebox.Type.Object(nested_properties);
|
|
165
|
-
schema2 = base(schema2, key, config);
|
|
166
|
-
return schema2;
|
|
167
|
-
} else if (config.type === "array") {
|
|
168
|
-
schema2 = import_typebox.Type.Array(build(key, config.items), { minItems: config.min, maxItems: config.max, default: config.default });
|
|
169
|
-
schema2 = base(schema2, key, config);
|
|
170
|
-
return schema2;
|
|
171
|
-
} else throw new Error(`Unsupported schema type for ${key}`);
|
|
172
|
-
};
|
|
173
|
-
const properties = {};
|
|
174
|
-
for (const [key, config] of Object.entries(schema)) properties[key] = build(key, config);
|
|
175
|
-
return import_typebox.Type.Object(properties);
|
|
176
|
-
};
|
|
177
|
-
|
|
178
181
|
// src/defaults/YuppiOptions.default.ts
|
|
179
182
|
var YuppiOptionsDefault = {
|
|
183
|
+
folder_path: "./",
|
|
180
184
|
error_messages: {
|
|
181
185
|
base: {
|
|
182
186
|
nullable: "Field {path} cannot be null",
|
|
@@ -228,14 +232,29 @@ var Yuppi = class {
|
|
|
228
232
|
this.options = import_lodash.default.merge({}, YuppiOptionsDefault, options);
|
|
229
233
|
}
|
|
230
234
|
validate(schema, properties) {
|
|
231
|
-
const yup_schema = convertToYup(schema
|
|
235
|
+
const yup_schema = this.convertToYup(schema);
|
|
232
236
|
return yup_schema.validateSync(properties, this.options.validate_options);
|
|
233
237
|
}
|
|
238
|
+
declare(schema, name) {
|
|
239
|
+
name = name.toLowerCase();
|
|
240
|
+
const types_dir = import_path.default.join(this.options.folder_path ?? "./", "yuppi", "types");
|
|
241
|
+
const banner_comment = `/* eslint-disable */
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* This type was automatically generated by **Yuppi**.
|
|
245
|
+
* _DO NOT MODIFY IT BY HAND_. Instead, modify your Yuppi schema.
|
|
246
|
+
* Use \`Yuppi.declare()\` to regenerate this type.
|
|
247
|
+
*/`;
|
|
248
|
+
(0, import_json_schema_to_typescript.compile)(this.convertToJSONSchema(schema), name, { bannerComment: banner_comment }).then((type) => {
|
|
249
|
+
import_fs.default.mkdirSync(types_dir, { recursive: true });
|
|
250
|
+
import_fs.default.writeFileSync(import_path.default.join(types_dir, `${name}.d.ts`), type);
|
|
251
|
+
});
|
|
252
|
+
}
|
|
234
253
|
convertToYup(schema) {
|
|
235
254
|
return convertToYup(schema, this.options.error_messages);
|
|
236
255
|
}
|
|
237
256
|
convertToJSONSchema(schema) {
|
|
238
|
-
return convertToJSONSchema(schema);
|
|
257
|
+
return JSON.parse(JSON.stringify(convertToJSONSchema(schema)));
|
|
239
258
|
}
|
|
240
259
|
};
|
|
241
260
|
|
package/dist/main.mjs
CHANGED
|
@@ -5,7 +5,53 @@ var __export = (target, all) => {
|
|
|
5
5
|
};
|
|
6
6
|
|
|
7
7
|
// src/Yuppi.class.ts
|
|
8
|
+
import { compile } from "json-schema-to-typescript";
|
|
8
9
|
import _ from "lodash";
|
|
10
|
+
import fs from "fs";
|
|
11
|
+
import path from "path";
|
|
12
|
+
|
|
13
|
+
// src/utils/ConvertToJSONSchema.util.ts
|
|
14
|
+
import { Type } from "@sinclair/typebox";
|
|
15
|
+
var convertToJSONSchema = (schema) => {
|
|
16
|
+
const base = (schema2, key, config) => {
|
|
17
|
+
if (!config.required) schema2 = Type.Optional(schema2);
|
|
18
|
+
if (config.nullable || config.default === null) schema2 = Type.Union([schema2, Type.Null()]);
|
|
19
|
+
return schema2;
|
|
20
|
+
};
|
|
21
|
+
const build = (key, config) => {
|
|
22
|
+
let schema2;
|
|
23
|
+
if (config.type === "string") {
|
|
24
|
+
schema2 = Type.String({ enum: config.enum, minLength: config.min, maxLength: config.max, pattern: config.pattern ? new RegExp(config.pattern).source : void 0, default: config.default });
|
|
25
|
+
schema2 = base(schema2, key, config);
|
|
26
|
+
return schema2;
|
|
27
|
+
} else if (config.type === "number") {
|
|
28
|
+
schema2 = config.integer === true ? Type.Integer({ enum: config.enum, minimum: config.min, maximum: config.max, default: config.default }) : Type.Number({ enum: config.enum, minimum: config.min, maximum: config.max, default: config.default });
|
|
29
|
+
schema2 = base(schema2, key, config);
|
|
30
|
+
return schema2;
|
|
31
|
+
} else if (config.type === "boolean") {
|
|
32
|
+
schema2 = Type.Boolean({ default: config.default });
|
|
33
|
+
schema2 = base(schema2, key, config);
|
|
34
|
+
return schema2;
|
|
35
|
+
} else if (config.type === "date") {
|
|
36
|
+
schema2 = Type.String({ format: "date-time", minimum: config.min, maximum: config.max, default: config.default });
|
|
37
|
+
schema2 = base(schema2, key, config);
|
|
38
|
+
return schema2;
|
|
39
|
+
} else if (config.type === "object") {
|
|
40
|
+
const nested_properties = {};
|
|
41
|
+
for (const [nested_key, nested_config] of Object.entries(config.properties)) nested_properties[nested_key] = build(nested_key, nested_config);
|
|
42
|
+
schema2 = Type.Object(nested_properties, { additionalProperties: false });
|
|
43
|
+
schema2 = base(schema2, key, config);
|
|
44
|
+
return schema2;
|
|
45
|
+
} else if (config.type === "array") {
|
|
46
|
+
schema2 = Type.Array(build(key, config.items), { minItems: config.min, maxItems: config.max, default: config.default });
|
|
47
|
+
schema2 = base(schema2, key, config);
|
|
48
|
+
return schema2;
|
|
49
|
+
} else throw new Error(`Unsupported schema type for ${key}`);
|
|
50
|
+
};
|
|
51
|
+
const properties = {};
|
|
52
|
+
for (const [key, config] of Object.entries(schema)) properties[key] = build(key, config);
|
|
53
|
+
return Type.Object(properties, { additionalProperties: false });
|
|
54
|
+
};
|
|
9
55
|
|
|
10
56
|
// src/utils/ConvertToYup.util.ts
|
|
11
57
|
import * as Yup from "yup";
|
|
@@ -15,7 +61,7 @@ var convertToYup = (schema, error_messages) => {
|
|
|
15
61
|
if (config.required)
|
|
16
62
|
schema2 = schema2.test(
|
|
17
63
|
"required",
|
|
18
|
-
({ path }) => (error_messages?.base?.required ?? "").replaceAll("{path}",
|
|
64
|
+
({ path: path2 }) => (error_messages?.base?.required ?? "").replaceAll("{path}", path2),
|
|
19
65
|
(property) => {
|
|
20
66
|
if (property === void 0) return false;
|
|
21
67
|
if (typeof property === "string" && property.trim() === "") return false;
|
|
@@ -23,74 +69,74 @@ var convertToYup = (schema, error_messages) => {
|
|
|
23
69
|
return true;
|
|
24
70
|
}
|
|
25
71
|
);
|
|
26
|
-
if (!config.nullable && config.default !== null) schema2 = schema2.nonNullable(({ path }) => (error_messages?.base?.nullable ?? "").replaceAll("{path}",
|
|
72
|
+
if (!config.nullable && config.default !== null) schema2 = schema2.nonNullable(({ path: path2 }) => (error_messages?.base?.nullable ?? "").replaceAll("{path}", path2));
|
|
27
73
|
if (config.default) schema2 = schema2.default(config.default);
|
|
28
74
|
return schema2;
|
|
29
75
|
};
|
|
30
76
|
const build = (key, config) => {
|
|
31
77
|
let schema2;
|
|
32
78
|
if (config.type === "string") {
|
|
33
|
-
schema2 = Yup.string().typeError(({ path }) => (error_messages?.string?.type ?? "").replaceAll("{path}",
|
|
79
|
+
schema2 = Yup.string().typeError(({ path: path2 }) => (error_messages?.string?.type ?? "").replaceAll("{path}", path2));
|
|
34
80
|
schema2 = base(schema2, key, config);
|
|
35
81
|
schema2 = schema2.transform((property) => typeof property === "string" ? property.trim() : property);
|
|
36
82
|
if (config.enum)
|
|
37
83
|
schema2 = schema2.oneOf(
|
|
38
84
|
config.enum.map((item) => item.trim()),
|
|
39
|
-
({ path }) => (error_messages?.string?.enum ?? "").replaceAll("{path}",
|
|
85
|
+
({ path: path2 }) => (error_messages?.string?.enum ?? "").replaceAll("{path}", path2)
|
|
40
86
|
);
|
|
41
|
-
if (config.pattern) schema2 = schema2.matches(new RegExp(config.pattern), ({ path }) => (error_messages?.string?.pattern ?? "").replaceAll("{path}",
|
|
87
|
+
if (config.pattern) schema2 = schema2.matches(new RegExp(config.pattern), ({ path: path2 }) => (error_messages?.string?.pattern ?? "").replaceAll("{path}", path2).replaceAll("{pattern}", config.pattern ? new RegExp(config.pattern).source : ""));
|
|
42
88
|
if (config.min)
|
|
43
89
|
schema2 = schema2.min(
|
|
44
90
|
config.min,
|
|
45
|
-
({ path, min }) => (error_messages?.string?.min ?? "").replaceAll("{path}",
|
|
91
|
+
({ path: path2, min }) => (error_messages?.string?.min ?? "").replaceAll("{path}", path2).replaceAll("{min}", min.toString()).replaceAll("{plural_suffix}", min > 1 ? "s" : "")
|
|
46
92
|
);
|
|
47
93
|
if (config.max)
|
|
48
94
|
schema2 = schema2.max(
|
|
49
95
|
config.max,
|
|
50
|
-
({ path, max }) => (error_messages?.string?.max ?? "").replaceAll("{path}",
|
|
96
|
+
({ path: path2, max }) => (error_messages?.string?.max ?? "").replaceAll("{path}", path2).replaceAll("{max}", max.toString()).replaceAll("{plural_suffix}", max > 1 ? "s" : "")
|
|
51
97
|
);
|
|
52
98
|
if (config.lowercase) schema2 = schema2.transform((property) => typeof property === "string" ? property.toLowerCase() : property);
|
|
53
99
|
if (config.uppercase) schema2 = schema2.transform((property) => typeof property === "string" ? property.toUpperCase() : property);
|
|
54
100
|
return schema2;
|
|
55
101
|
} else if (config.type === "number") {
|
|
56
|
-
schema2 = Yup.number().typeError(({ path }) => (error_messages?.number?.type ?? "").replaceAll("{path}",
|
|
102
|
+
schema2 = Yup.number().typeError(({ path: path2 }) => (error_messages?.number?.type ?? "").replaceAll("{path}", path2));
|
|
57
103
|
schema2 = base(schema2, key, config);
|
|
58
|
-
if (config.enum) schema2 = schema2.oneOf(config.enum, ({ path }) => (error_messages?.number?.enum ?? "").replaceAll("{path}",
|
|
59
|
-
if (config.min) schema2 = schema2.min(config.min, ({ path, min }) => (error_messages?.number?.min ?? "").replaceAll("{path}",
|
|
60
|
-
if (config.max) schema2 = schema2.max(config.max, ({ path, max }) => (error_messages?.number?.max ?? "").replaceAll("{path}",
|
|
61
|
-
if (config.integer) schema2 = schema2.integer(({ path }) => (error_messages?.number?.integer ?? "").replaceAll("{path}",
|
|
62
|
-
if (config.positive) schema2 = schema2.positive(({ path }) => (error_messages?.number?.positive ?? "").replaceAll("{path}",
|
|
63
|
-
if (config.negative) schema2 = schema2.negative(({ path }) => (error_messages?.number?.negative ?? "").replaceAll("{path}",
|
|
104
|
+
if (config.enum) schema2 = schema2.oneOf(config.enum, ({ path: path2 }) => (error_messages?.number?.enum ?? "").replaceAll("{path}", path2));
|
|
105
|
+
if (config.min) schema2 = schema2.min(config.min, ({ path: path2, min }) => (error_messages?.number?.min ?? "").replaceAll("{path}", path2).replaceAll("{min}", min.toString()));
|
|
106
|
+
if (config.max) schema2 = schema2.max(config.max, ({ path: path2, max }) => (error_messages?.number?.max ?? "").replaceAll("{path}", path2).replaceAll("{max}", max.toString()));
|
|
107
|
+
if (config.integer) schema2 = schema2.integer(({ path: path2 }) => (error_messages?.number?.integer ?? "").replaceAll("{path}", path2));
|
|
108
|
+
if (config.positive) schema2 = schema2.positive(({ path: path2 }) => (error_messages?.number?.positive ?? "").replaceAll("{path}", path2));
|
|
109
|
+
if (config.negative) schema2 = schema2.negative(({ path: path2 }) => (error_messages?.number?.negative ?? "").replaceAll("{path}", path2));
|
|
64
110
|
return schema2;
|
|
65
111
|
} else if (config.type === "boolean") {
|
|
66
|
-
schema2 = Yup.boolean().typeError(({ path }) => (error_messages?.boolean?.type ?? "").replaceAll("{path}",
|
|
112
|
+
schema2 = Yup.boolean().typeError(({ path: path2 }) => (error_messages?.boolean?.type ?? "").replaceAll("{path}", path2));
|
|
67
113
|
schema2 = base(schema2, key, config);
|
|
68
114
|
return schema2;
|
|
69
115
|
} else if (config.type === "date") {
|
|
70
|
-
schema2 = Yup.date().typeError(({ path }) => (error_messages?.date?.type ?? "").replaceAll("{path}",
|
|
116
|
+
schema2 = Yup.date().typeError(({ path: path2 }) => (error_messages?.date?.type ?? "").replaceAll("{path}", path2));
|
|
71
117
|
schema2 = base(schema2, key, config);
|
|
72
|
-
if (config.min) schema2 = schema2.min(config.min, ({ path, min }) => (error_messages?.date?.min ?? "").replaceAll("{path}",
|
|
73
|
-
if (config.max) schema2 = schema2.max(config.max, ({ path, max }) => (error_messages?.date?.max ?? "").replaceAll("{path}",
|
|
118
|
+
if (config.min) schema2 = schema2.min(config.min, ({ path: path2, min }) => (error_messages?.date?.min ?? "").replaceAll("{path}", path2).replaceAll("{min}", new Date(min).toISOString()));
|
|
119
|
+
if (config.max) schema2 = schema2.max(config.max, ({ path: path2, max }) => (error_messages?.date?.max ?? "").replaceAll("{path}", path2).replaceAll("{max}", new Date(max).toISOString()));
|
|
74
120
|
return schema2;
|
|
75
121
|
} else if (config.type === "object") {
|
|
76
|
-
schema2 = Yup.object().typeError(({ path }) => (error_messages?.object?.type ?? "").replaceAll("{path}",
|
|
122
|
+
schema2 = Yup.object().typeError(({ path: path2 }) => (error_messages?.object?.type ?? "").replaceAll("{path}", path2));
|
|
77
123
|
schema2 = base(schema2, key, config);
|
|
78
124
|
const nested_properties = {};
|
|
79
125
|
for (const [nested_key, nested_config] of Object.entries(config.properties)) nested_properties[nested_key] = build(nested_key, nested_config);
|
|
80
126
|
schema2 = schema2.shape(nested_properties);
|
|
81
127
|
return schema2;
|
|
82
128
|
} else if (config.type === "array") {
|
|
83
|
-
schema2 = Yup.array().typeError(({ path }) => (error_messages?.array?.type ?? "").replaceAll("{path}",
|
|
129
|
+
schema2 = Yup.array().typeError(({ path: path2 }) => (error_messages?.array?.type ?? "").replaceAll("{path}", path2));
|
|
84
130
|
schema2 = base(schema2, key, config);
|
|
85
131
|
if (config.min)
|
|
86
132
|
schema2 = schema2.min(
|
|
87
133
|
config.min,
|
|
88
|
-
({ path, min }) => (error_messages?.array?.min ?? "").replaceAll("{path}",
|
|
134
|
+
({ path: path2, min }) => (error_messages?.array?.min ?? "").replaceAll("{path}", path2).replaceAll("{min}", min.toString()).replaceAll("{plural_suffix}", min > 1 ? "s" : "")
|
|
89
135
|
);
|
|
90
136
|
if (config.max)
|
|
91
137
|
schema2 = schema2.max(
|
|
92
138
|
config.max,
|
|
93
|
-
({ path, max }) => (error_messages?.array?.max ?? "").replaceAll("{path}",
|
|
139
|
+
({ path: path2, max }) => (error_messages?.array?.max ?? "").replaceAll("{path}", path2).replaceAll("{max}", max.toString()).replaceAll("{plural_suffix}", max > 1 ? "s" : "")
|
|
94
140
|
);
|
|
95
141
|
schema2 = schema2.of(build(key, config.items));
|
|
96
142
|
return schema2;
|
|
@@ -101,51 +147,9 @@ var convertToYup = (schema, error_messages) => {
|
|
|
101
147
|
return Yup.object().shape(properties);
|
|
102
148
|
};
|
|
103
149
|
|
|
104
|
-
// src/utils/ConvertToJSONSchema.util.ts
|
|
105
|
-
import { Type } from "@sinclair/typebox";
|
|
106
|
-
var convertToJSONSchema = (schema) => {
|
|
107
|
-
const base = (schema2, key, config) => {
|
|
108
|
-
if (!config.required) schema2 = Type.Optional(schema2);
|
|
109
|
-
if (config.nullable || config.default === null) schema2 = Type.Union([schema2, Type.Null()]);
|
|
110
|
-
return schema2;
|
|
111
|
-
};
|
|
112
|
-
const build = (key, config) => {
|
|
113
|
-
let schema2;
|
|
114
|
-
if (config.type === "string") {
|
|
115
|
-
schema2 = Type.String({ enum: config.enum, minLength: config.min, maxLength: config.max, pattern: config.pattern ? new RegExp(config.pattern).source : void 0, default: config.default });
|
|
116
|
-
schema2 = base(schema2, key, config);
|
|
117
|
-
return schema2;
|
|
118
|
-
} else if (config.type === "number") {
|
|
119
|
-
schema2 = config.integer === true ? Type.Integer({ enum: config.enum, minimum: config.min, maximum: config.max, default: config.default }) : Type.Number({ enum: config.enum, minimum: config.min, maximum: config.max, default: config.default });
|
|
120
|
-
schema2 = base(schema2, key, config);
|
|
121
|
-
return schema2;
|
|
122
|
-
} else if (config.type === "boolean") {
|
|
123
|
-
schema2 = Type.Boolean({ default: config.default });
|
|
124
|
-
schema2 = base(schema2, key, config);
|
|
125
|
-
return schema2;
|
|
126
|
-
} else if (config.type === "date") {
|
|
127
|
-
schema2 = Type.String({ format: "date-time", minimum: config.min, maximum: config.max, default: config.default });
|
|
128
|
-
schema2 = base(schema2, key, config);
|
|
129
|
-
return schema2;
|
|
130
|
-
} else if (config.type === "object") {
|
|
131
|
-
const nested_properties = {};
|
|
132
|
-
for (const [nested_key, nested_config] of Object.entries(config.properties)) nested_properties[nested_key] = build(nested_key, nested_config);
|
|
133
|
-
schema2 = Type.Object(nested_properties);
|
|
134
|
-
schema2 = base(schema2, key, config);
|
|
135
|
-
return schema2;
|
|
136
|
-
} else if (config.type === "array") {
|
|
137
|
-
schema2 = Type.Array(build(key, config.items), { minItems: config.min, maxItems: config.max, default: config.default });
|
|
138
|
-
schema2 = base(schema2, key, config);
|
|
139
|
-
return schema2;
|
|
140
|
-
} else throw new Error(`Unsupported schema type for ${key}`);
|
|
141
|
-
};
|
|
142
|
-
const properties = {};
|
|
143
|
-
for (const [key, config] of Object.entries(schema)) properties[key] = build(key, config);
|
|
144
|
-
return Type.Object(properties);
|
|
145
|
-
};
|
|
146
|
-
|
|
147
150
|
// src/defaults/YuppiOptions.default.ts
|
|
148
151
|
var YuppiOptionsDefault = {
|
|
152
|
+
folder_path: "./",
|
|
149
153
|
error_messages: {
|
|
150
154
|
base: {
|
|
151
155
|
nullable: "Field {path} cannot be null",
|
|
@@ -197,14 +201,29 @@ var Yuppi = class {
|
|
|
197
201
|
this.options = _.merge({}, YuppiOptionsDefault, options);
|
|
198
202
|
}
|
|
199
203
|
validate(schema, properties) {
|
|
200
|
-
const yup_schema = convertToYup(schema
|
|
204
|
+
const yup_schema = this.convertToYup(schema);
|
|
201
205
|
return yup_schema.validateSync(properties, this.options.validate_options);
|
|
202
206
|
}
|
|
207
|
+
declare(schema, name) {
|
|
208
|
+
name = name.toLowerCase();
|
|
209
|
+
const types_dir = path.join(this.options.folder_path ?? "./", "yuppi", "types");
|
|
210
|
+
const banner_comment = `/* eslint-disable */
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* This type was automatically generated by **Yuppi**.
|
|
214
|
+
* _DO NOT MODIFY IT BY HAND_. Instead, modify your Yuppi schema.
|
|
215
|
+
* Use \`Yuppi.declare()\` to regenerate this type.
|
|
216
|
+
*/`;
|
|
217
|
+
compile(this.convertToJSONSchema(schema), name, { bannerComment: banner_comment }).then((type) => {
|
|
218
|
+
fs.mkdirSync(types_dir, { recursive: true });
|
|
219
|
+
fs.writeFileSync(path.join(types_dir, `${name}.d.ts`), type);
|
|
220
|
+
});
|
|
221
|
+
}
|
|
203
222
|
convertToYup(schema) {
|
|
204
223
|
return convertToYup(schema, this.options.error_messages);
|
|
205
224
|
}
|
|
206
225
|
convertToJSONSchema(schema) {
|
|
207
|
-
return convertToJSONSchema(schema);
|
|
226
|
+
return JSON.parse(JSON.stringify(convertToJSONSchema(schema)));
|
|
208
227
|
}
|
|
209
228
|
};
|
|
210
229
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yuppi",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Schemas that can be converted to Yup and JSON Schema.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/keift/yuppi",
|
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@sinclair/typebox": "^0.34.41",
|
|
19
19
|
"@types/lodash": "^4.17.20",
|
|
20
|
+
"@types/node": "^24.5.2",
|
|
21
|
+
"json-schema-to-typescript": "^15.0.4",
|
|
20
22
|
"lodash": "^4.17.21",
|
|
21
23
|
"yup": "^1.7.1"
|
|
22
24
|
},
|