+15
-13
dev/openapi-ts.config.ts
+15
-13
dev/openapi-ts.config.ts
···
431
},
432
},
433
'~resolvers': {
434
-
number(ctx) {
435
-
const { $, plugin, symbols } = ctx;
436
-
const { v } = symbols;
437
-
// ctx.nodes.base = () => {
438
-
// // implement custom base number resolver
439
-
// }
440
-
const big = plugin.symbolOnce('Big', {
441
-
external: 'big.js',
442
-
importKind: 'default',
443
-
});
444
-
return $(v).attr('instance').call(big);
445
-
},
446
// object(ctx) {
447
// const { $ } = ctx;
448
// const additional = ctx.nodes.additionalProperties(ctx);
···
458
// ctx.nodes.format = () => $('v').attr('isoDateTime').call();
459
// }
460
// },
461
-
// validator({ $, plugin, schema, v }) {
462
// const vShadow = plugin.symbol('v');
463
// const test = plugin.symbol('test');
464
// const e = plugin.symbol('err');
···
431
},
432
},
433
'~resolvers': {
434
+
// number(ctx) {
435
+
// const { $, plugin, symbols } = ctx;
436
+
// const { v } = symbols;
437
+
// // ctx.nodes.base = () => {
438
+
// // // implement custom base number resolver
439
+
// // }
440
+
// const big = plugin.symbolOnce('Big', {
441
+
// external: 'big.js',
442
+
// importKind: 'default',
443
+
// });
444
+
// return $(v).attr('instance').call(big);
445
+
// },
446
// object(ctx) {
447
// const { $ } = ctx;
448
// const additional = ctx.nodes.additionalProperties(ctx);
···
458
// ctx.nodes.format = () => $('v').attr('isoDateTime').call();
459
// }
460
// },
461
+
// validator(ctx) {
462
+
// const { $, plugin, symbols } = ctx;
463
+
// const { schema, v } = symbols;
464
// const vShadow = plugin.symbol('v');
465
// const test = plugin.symbol('test');
466
// const e = plugin.symbol('err');
+34
-30
packages/openapi-ts/src/plugins/valibot/types.d.ts
+34
-30
packages/openapi-ts/src/plugins/valibot/types.d.ts
···
1
import type { Refs, Symbol } from '@hey-api/codegen-core';
2
-
import type ts from 'typescript';
3
4
import type { IR } from '~/ir/types';
5
import type { DefinePlugin, Plugin, SchemaWithType } from '~/plugins';
···
8
ShouldCoerceToBigInt,
9
} from '~/plugins/shared/utils/coerce';
10
import type { GetIntegerLimit } from '~/plugins/shared/utils/formats';
11
-
import type { $, DollarTsDsl, TsDsl } from '~/ts-dsl';
12
import type { StringCase, StringName } from '~/types/case';
13
-
import type { MaybeArray } from '~/types/utils';
14
15
import type { IApi } from './api';
16
import type { Pipe, PipeResult, PipesUtils } from './shared/pipes';
···
328
};
329
};
330
331
-
type SharedResolverArgs = DollarTsDsl & {
332
/**
333
* Functions for working with pipes.
334
*/
335
-
pipes: PipesUtils;
336
plugin: ValibotPlugin['Instance'];
337
/**
338
-
* The current builder state being processed by this resolver.
339
-
*
340
-
* In Valibot, this represents the current list of call expressions ("pipes")
341
-
* being assembled to form a schema definition.
342
-
*
343
-
* Each pipe can be extended, modified, or replaced to customize how the
344
-
* resulting schema is constructed.
345
-
*/
346
-
result: Pipes;
347
-
/**
348
* Provides access to commonly used symbols within the Valibot plugin.
349
*/
350
symbols: {
351
v: Symbol;
352
};
353
-
};
354
355
-
export type NumberResolverContext = SharedResolverArgs & {
356
/**
357
* Nodes used to build different parts of the number schema.
358
*/
···
371
maybeBigInt: MaybeBigInt;
372
shouldCoerceToBigInt: ShouldCoerceToBigInt;
373
};
374
-
};
375
376
-
export type ObjectResolverContext = SharedResolverArgs & {
377
/**
378
* Nodes used to build different parts of the object schema.
379
*/
···
396
ast: Partial<Omit<Ast, 'typeName'>>;
397
state: Refs<PluginState>;
398
};
399
-
};
400
401
-
export type StringResolverContext = SharedResolverArgs & {
402
/**
403
* Nodes used to build different parts of the string schema.
404
*/
···
412
pattern: (ctx: StringResolverContext) => PipeResult | undefined;
413
};
414
schema: SchemaWithType<'string'>;
415
-
};
416
417
-
export type ValidatorResolverArgs = SharedResolverArgs & {
418
operation: IR.Operation;
419
-
schema: Symbol;
420
-
};
421
422
type ValidatorResolver = (
423
-
args: ValidatorResolverArgs,
424
-
) => MaybeArray<TsDsl<ts.Statement>> | null | undefined;
425
426
type Resolvers = Plugin.Resolvers<{
427
/**
···
455
*
456
* Example path: `~resolvers.validator.request` or `~resolvers.validator.response`
457
*
458
-
* Returning `undefined` from a resolver will apply the default generation logic.
459
*/
460
validator?:
461
| ValidatorResolver
···
463
/**
464
* Controls how the request validator function body is generated.
465
*
466
-
* Returning `undefined` will fall back to the default `.await().return()` logic.
467
*/
468
request?: ValidatorResolver;
469
/**
470
* Controls how the response validator function body is generated.
471
*
472
-
* Returning `undefined` will fall back to the default `.await().return()` logic.
473
*/
474
response?: ValidatorResolver;
475
};
···
1
import type { Refs, Symbol } from '@hey-api/codegen-core';
2
3
import type { IR } from '~/ir/types';
4
import type { DefinePlugin, Plugin, SchemaWithType } from '~/plugins';
···
7
ShouldCoerceToBigInt,
8
} from '~/plugins/shared/utils/coerce';
9
import type { GetIntegerLimit } from '~/plugins/shared/utils/formats';
10
+
import type { $, DollarTsDsl } from '~/ts-dsl';
11
import type { StringCase, StringName } from '~/types/case';
12
13
import type { IApi } from './api';
14
import type { Pipe, PipeResult, PipesUtils } from './shared/pipes';
···
326
};
327
};
328
329
+
interface BaseResolverContext extends DollarTsDsl {
330
/**
331
* Functions for working with pipes.
332
*/
333
+
pipes: PipesUtils & {
334
+
/**
335
+
* The current builder state being processed by this resolver.
336
+
*
337
+
* In Valibot, this represents the current list of call expressions ("pipes")
338
+
* being assembled to form a schema definition.
339
+
*
340
+
* Each pipe can be extended, modified, or replaced to customize how the
341
+
* resulting schema is constructed.
342
+
*/
343
+
current: Pipes;
344
+
};
345
plugin: ValibotPlugin['Instance'];
346
/**
347
* Provides access to commonly used symbols within the Valibot plugin.
348
*/
349
symbols: {
350
v: Symbol;
351
};
352
+
}
353
354
+
export interface NumberResolverContext extends BaseResolverContext {
355
/**
356
* Nodes used to build different parts of the number schema.
357
*/
···
370
maybeBigInt: MaybeBigInt;
371
shouldCoerceToBigInt: ShouldCoerceToBigInt;
372
};
373
+
}
374
375
+
export interface ObjectResolverContext extends BaseResolverContext {
376
/**
377
* Nodes used to build different parts of the object schema.
378
*/
···
395
ast: Partial<Omit<Ast, 'typeName'>>;
396
state: Refs<PluginState>;
397
};
398
+
}
399
400
+
export interface StringResolverContext extends BaseResolverContext {
401
/**
402
* Nodes used to build different parts of the string schema.
403
*/
···
411
pattern: (ctx: StringResolverContext) => PipeResult | undefined;
412
};
413
schema: SchemaWithType<'string'>;
414
+
}
415
416
+
export interface ValidatorResolverContext extends BaseResolverContext {
417
operation: IR.Operation;
418
+
/**
419
+
* Provides access to commonly used symbols within the Valibot plugin.
420
+
*/
421
+
symbols: BaseResolverContext['symbols'] & {
422
+
schema: Symbol;
423
+
};
424
+
}
425
426
type ValidatorResolver = (
427
+
args: ValidatorResolverContext,
428
+
) => PipeResult | null | undefined;
429
430
type Resolvers = Plugin.Resolvers<{
431
/**
···
459
*
460
* Example path: `~resolvers.validator.request` or `~resolvers.validator.response`
461
*
462
+
* Returning `undefined` will execute the default resolver logic.
463
*/
464
validator?:
465
| ValidatorResolver
···
467
/**
468
* Controls how the request validator function body is generated.
469
*
470
+
* Returning `undefined` will execute the default resolver logic.
471
*/
472
request?: ValidatorResolver;
473
/**
474
* Controls how the response validator function body is generated.
475
*
476
+
* Returning `undefined` will execute the default resolver logic.
477
*/
478
response?: ValidatorResolver;
479
};
+17
-14
packages/openapi-ts/src/plugins/valibot/v1/api.ts
+17
-14
packages/openapi-ts/src/plugins/valibot/v1/api.ts
···
2
3
import { pipes } from '../shared/pipes';
4
import type { ValidatorArgs } from '../shared/types';
5
-
import type { ValidatorResolverArgs } from '../types';
6
import { identifiers } from './constants';
7
8
const validatorResolver = (
9
-
ctx: ValidatorResolverArgs,
10
): ReturnType<typeof $.return> => {
11
-
const { schema, symbols } = ctx;
12
-
const { v } = symbols;
13
return $(v)
14
.attr(identifiers.async.parseAsync)
15
.call(schema, 'data')
···
30
});
31
if (!symbol) return;
32
33
-
const args: ValidatorResolverArgs = {
34
$,
35
operation,
36
-
pipes,
37
plugin,
38
-
result: [],
39
-
schema: symbol,
40
symbols: {
41
v: plugin.external('valibot.v'),
42
},
43
};
···
46
typeof validator === 'function' ? validator : validator?.request;
47
const candidates = [resolver, validatorResolver];
48
for (const candidate of candidates) {
49
-
const statements = candidate?.(args);
50
if (statements === null) return;
51
if (statements !== undefined) {
52
return $.func()
···
71
});
72
if (!symbol) return;
73
74
-
const args: ValidatorResolverArgs = {
75
$,
76
operation,
77
-
pipes,
78
plugin,
79
-
result: [],
80
-
schema: symbol,
81
symbols: {
82
v: plugin.external('valibot.v'),
83
},
84
};
···
87
typeof validator === 'function' ? validator : validator?.response;
88
const candidates = [resolver, validatorResolver];
89
for (const candidate of candidates) {
90
-
const statements = candidate?.(args);
91
if (statements === null) return;
92
if (statements !== undefined) {
93
return $.func()
···
2
3
import { pipes } from '../shared/pipes';
4
import type { ValidatorArgs } from '../shared/types';
5
+
import type { ValidatorResolverContext } from '../types';
6
import { identifiers } from './constants';
7
8
const validatorResolver = (
9
+
ctx: ValidatorResolverContext,
10
): ReturnType<typeof $.return> => {
11
+
const { schema, v } = ctx.symbols;
12
return $(v)
13
.attr(identifiers.async.parseAsync)
14
.call(schema, 'data')
···
29
});
30
if (!symbol) return;
31
32
+
const ctx: ValidatorResolverContext = {
33
$,
34
operation,
35
+
pipes: {
36
+
...pipes,
37
+
current: [],
38
+
},
39
plugin,
40
symbols: {
41
+
schema: symbol,
42
v: plugin.external('valibot.v'),
43
},
44
};
···
47
typeof validator === 'function' ? validator : validator?.request;
48
const candidates = [resolver, validatorResolver];
49
for (const candidate of candidates) {
50
+
const statements = candidate?.(ctx);
51
if (statements === null) return;
52
if (statements !== undefined) {
53
return $.func()
···
72
});
73
if (!symbol) return;
74
75
+
const ctx: ValidatorResolverContext = {
76
$,
77
operation,
78
+
pipes: {
79
+
...pipes,
80
+
current: [],
81
+
},
82
plugin,
83
symbols: {
84
+
schema: symbol,
85
v: plugin.external('valibot.v'),
86
},
87
};
···
90
typeof validator === 'function' ? validator : validator?.response;
91
const candidates = [resolver, validatorResolver];
92
for (const candidate of candidates) {
93
+
const statements = candidate?.(ctx);
94
if (statements === null) return;
95
if (statements !== undefined) {
96
return $.func()
+9
-7
packages/openapi-ts/src/plugins/valibot/v1/toAst/number.ts
+9
-7
packages/openapi-ts/src/plugins/valibot/v1/toAst/number.ts
···
100
101
function numberResolver(ctx: NumberResolverContext): Pipes {
102
const constNode = ctx.nodes.const(ctx);
103
-
if (constNode) return ctx.pipes.push(ctx.result, constNode);
104
105
const baseNode = ctx.nodes.base(ctx);
106
-
if (baseNode) ctx.pipes.push(ctx.result, baseNode);
107
108
const minNode = ctx.nodes.min(ctx);
109
-
if (minNode) ctx.pipes.push(ctx.result, minNode);
110
111
const maxNode = ctx.nodes.max(ctx);
112
-
if (maxNode) ctx.pipes.push(ctx.result, maxNode);
113
114
-
return ctx.result;
115
}
116
117
export const numberToNode = ({
···
128
max: maxNode,
129
min: minNode,
130
},
131
-
pipes,
132
plugin,
133
-
result: [],
134
schema,
135
symbols: {
136
v: plugin.external('valibot.v'),
···
100
101
function numberResolver(ctx: NumberResolverContext): Pipes {
102
const constNode = ctx.nodes.const(ctx);
103
+
if (constNode) return ctx.pipes.push(ctx.pipes.current, constNode);
104
105
const baseNode = ctx.nodes.base(ctx);
106
+
if (baseNode) ctx.pipes.push(ctx.pipes.current, baseNode);
107
108
const minNode = ctx.nodes.min(ctx);
109
+
if (minNode) ctx.pipes.push(ctx.pipes.current, minNode);
110
111
const maxNode = ctx.nodes.max(ctx);
112
+
if (maxNode) ctx.pipes.push(ctx.pipes.current, maxNode);
113
114
+
return ctx.pipes.current;
115
}
116
117
export const numberToNode = ({
···
128
max: maxNode,
129
min: minNode,
130
},
131
+
pipes: {
132
+
...pipes,
133
+
current: [],
134
+
},
135
plugin,
136
schema,
137
symbols: {
138
v: plugin.external('valibot.v'),
+4
-2
packages/openapi-ts/src/plugins/valibot/v1/toAst/object.ts
+4
-2
packages/openapi-ts/src/plugins/valibot/v1/toAst/object.ts
+12
-10
packages/openapi-ts/src/plugins/valibot/v1/toAst/string.ts
+12
-10
packages/openapi-ts/src/plugins/valibot/v1/toAst/string.ts
···
80
81
function stringResolver(ctx: StringResolverContext): Pipes {
82
const constNode = ctx.nodes.const(ctx);
83
-
if (constNode) return ctx.pipes.push(ctx.result, constNode);
84
85
const baseNode = ctx.nodes.base(ctx);
86
-
if (baseNode) ctx.pipes.push(ctx.result, baseNode);
87
88
const formatNode = ctx.nodes.format(ctx);
89
-
if (formatNode) ctx.pipes.push(ctx.result, formatNode);
90
91
const lengthNode = ctx.nodes.length(ctx);
92
if (lengthNode) {
93
-
ctx.pipes.push(ctx.result, lengthNode);
94
} else {
95
const minLengthNode = ctx.nodes.minLength(ctx);
96
-
if (minLengthNode) ctx.pipes.push(ctx.result, minLengthNode);
97
98
const maxLengthNode = ctx.nodes.maxLength(ctx);
99
-
if (maxLengthNode) ctx.pipes.push(ctx.result, maxLengthNode);
100
}
101
102
const patternNode = ctx.nodes.pattern(ctx);
103
-
if (patternNode) ctx.pipes.push(ctx.result, patternNode);
104
105
-
return ctx.result;
106
}
107
108
export const stringToNode = ({
···
122
minLength: minLengthNode,
123
pattern: patternNode,
124
},
125
-
pipes,
126
plugin,
127
-
result: [],
128
schema,
129
symbols: {
130
v: plugin.external('valibot.v'),
···
80
81
function stringResolver(ctx: StringResolverContext): Pipes {
82
const constNode = ctx.nodes.const(ctx);
83
+
if (constNode) return ctx.pipes.push(ctx.pipes.current, constNode);
84
85
const baseNode = ctx.nodes.base(ctx);
86
+
if (baseNode) ctx.pipes.push(ctx.pipes.current, baseNode);
87
88
const formatNode = ctx.nodes.format(ctx);
89
+
if (formatNode) ctx.pipes.push(ctx.pipes.current, formatNode);
90
91
const lengthNode = ctx.nodes.length(ctx);
92
if (lengthNode) {
93
+
ctx.pipes.push(ctx.pipes.current, lengthNode);
94
} else {
95
const minLengthNode = ctx.nodes.minLength(ctx);
96
+
if (minLengthNode) ctx.pipes.push(ctx.pipes.current, minLengthNode);
97
98
const maxLengthNode = ctx.nodes.maxLength(ctx);
99
+
if (maxLengthNode) ctx.pipes.push(ctx.pipes.current, maxLengthNode);
100
}
101
102
const patternNode = ctx.nodes.pattern(ctx);
103
+
if (patternNode) ctx.pipes.push(ctx.pipes.current, patternNode);
104
105
+
return ctx.pipes.current;
106
}
107
108
export const stringToNode = ({
···
122
minLength: minLengthNode,
123
pattern: patternNode,
124
},
125
+
pipes: {
126
+
...pipes,
127
+
current: [],
128
+
},
129
plugin,
130
schema,
131
symbols: {
132
v: plugin.external('valibot.v'),