yuppi 1.2.12 → 1.3.1
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 +89 -65
- package/dist/main.mjs +89 -65
- 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,14 @@ var convertToYup = (schema, error_messages) => {
|
|
|
132
178
|
return Yup.object().shape(properties);
|
|
133
179
|
};
|
|
134
180
|
|
|
135
|
-
// src/utils/
|
|
136
|
-
var
|
|
137
|
-
|
|
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);
|
|
181
|
+
// src/utils/PascalCase.util.ts
|
|
182
|
+
var pascalCase = (text) => {
|
|
183
|
+
return text.replace(/[^a-zA-Z0-9]/g, " ").split(" ").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("");
|
|
176
184
|
};
|
|
177
185
|
|
|
178
186
|
// src/defaults/YuppiOptions.default.ts
|
|
179
187
|
var YuppiOptionsDefault = {
|
|
188
|
+
folder_path: "./",
|
|
180
189
|
error_messages: {
|
|
181
190
|
base: {
|
|
182
191
|
nullable: "Field {path} cannot be null",
|
|
@@ -228,14 +237,29 @@ var Yuppi = class {
|
|
|
228
237
|
this.options = import_lodash.default.merge({}, YuppiOptionsDefault, options);
|
|
229
238
|
}
|
|
230
239
|
validate(schema, properties) {
|
|
231
|
-
const yup_schema = convertToYup(schema
|
|
240
|
+
const yup_schema = this.convertToYup(schema);
|
|
232
241
|
return yup_schema.validateSync(properties, this.options.validate_options);
|
|
233
242
|
}
|
|
243
|
+
declare(schema, name) {
|
|
244
|
+
name = pascalCase(name);
|
|
245
|
+
const types_dir = import_path.default.join(this.options.folder_path ?? "./", "yuppi", "types");
|
|
246
|
+
const banner_comment = `/* eslint-disable */
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* This type was automatically generated by **Yuppi**.
|
|
250
|
+
* _DO NOT MODIFY IT BY HAND_. Instead, modify your Yuppi schema.
|
|
251
|
+
* Use \`Yuppi.declare()\` to regenerate this type.
|
|
252
|
+
*/`;
|
|
253
|
+
(0, import_json_schema_to_typescript.compile)(this.convertToJSONSchema(schema), name, { bannerComment: banner_comment }).then((type) => {
|
|
254
|
+
import_fs.default.mkdirSync(types_dir, { recursive: true });
|
|
255
|
+
import_fs.default.writeFileSync(import_path.default.join(types_dir, `${name}.d.ts`), type);
|
|
256
|
+
});
|
|
257
|
+
}
|
|
234
258
|
convertToYup(schema) {
|
|
235
259
|
return convertToYup(schema, this.options.error_messages);
|
|
236
260
|
}
|
|
237
261
|
convertToJSONSchema(schema) {
|
|
238
|
-
return convertToJSONSchema(schema);
|
|
262
|
+
return JSON.parse(JSON.stringify(convertToJSONSchema(schema)));
|
|
239
263
|
}
|
|
240
264
|
};
|
|
241
265
|
|
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,14 @@ var convertToYup = (schema, error_messages) => {
|
|
|
101
147
|
return Yup.object().shape(properties);
|
|
102
148
|
};
|
|
103
149
|
|
|
104
|
-
// src/utils/
|
|
105
|
-
|
|
106
|
-
|
|
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);
|
|
150
|
+
// src/utils/PascalCase.util.ts
|
|
151
|
+
var pascalCase = (text) => {
|
|
152
|
+
return text.replace(/[^a-zA-Z0-9]/g, " ").split(" ").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("");
|
|
145
153
|
};
|
|
146
154
|
|
|
147
155
|
// src/defaults/YuppiOptions.default.ts
|
|
148
156
|
var YuppiOptionsDefault = {
|
|
157
|
+
folder_path: "./",
|
|
149
158
|
error_messages: {
|
|
150
159
|
base: {
|
|
151
160
|
nullable: "Field {path} cannot be null",
|
|
@@ -197,14 +206,29 @@ var Yuppi = class {
|
|
|
197
206
|
this.options = _.merge({}, YuppiOptionsDefault, options);
|
|
198
207
|
}
|
|
199
208
|
validate(schema, properties) {
|
|
200
|
-
const yup_schema = convertToYup(schema
|
|
209
|
+
const yup_schema = this.convertToYup(schema);
|
|
201
210
|
return yup_schema.validateSync(properties, this.options.validate_options);
|
|
202
211
|
}
|
|
212
|
+
declare(schema, name) {
|
|
213
|
+
name = pascalCase(name);
|
|
214
|
+
const types_dir = path.join(this.options.folder_path ?? "./", "yuppi", "types");
|
|
215
|
+
const banner_comment = `/* eslint-disable */
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* This type was automatically generated by **Yuppi**.
|
|
219
|
+
* _DO NOT MODIFY IT BY HAND_. Instead, modify your Yuppi schema.
|
|
220
|
+
* Use \`Yuppi.declare()\` to regenerate this type.
|
|
221
|
+
*/`;
|
|
222
|
+
compile(this.convertToJSONSchema(schema), name, { bannerComment: banner_comment }).then((type) => {
|
|
223
|
+
fs.mkdirSync(types_dir, { recursive: true });
|
|
224
|
+
fs.writeFileSync(path.join(types_dir, `${name}.d.ts`), type);
|
|
225
|
+
});
|
|
226
|
+
}
|
|
203
227
|
convertToYup(schema) {
|
|
204
228
|
return convertToYup(schema, this.options.error_messages);
|
|
205
229
|
}
|
|
206
230
|
convertToJSONSchema(schema) {
|
|
207
|
-
return convertToJSONSchema(schema);
|
|
231
|
+
return JSON.parse(JSON.stringify(convertToJSONSchema(schema)));
|
|
208
232
|
}
|
|
209
233
|
};
|
|
210
234
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yuppi",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.1",
|
|
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
|
},
|