1- import type { SchemaWithType } from '@hey-api/shared' ;
1+ import type { SchemaVisitorContext , SchemaWithType , Walker } from '@hey-api/shared' ;
22import { childContext , deduplicateSchema } from '@hey-api/shared' ;
33
44import { $ } from '../../../../ts-dsl' ;
55import { identifiers } from '../../constants' ;
6- import type {
7- Ast ,
8- IrSchemaToAstOptions ,
9- ZodAppliedResult ,
10- ZodSchemaResult ,
11- } from '../../shared/types' ;
6+ import type { Chain } from '../../shared/chain' ;
7+ import type { CompositeHandlerResult , ZodFinal , ZodResult } from '../../shared/types' ;
8+ import type { ZodPlugin } from '../../types' ;
129import { unknownToAst } from './unknown' ;
1310
14- export function arrayToAst (
15- options : IrSchemaToAstOptions & {
16- applyModifiers : ( result : ZodSchemaResult , opts : { optional ?: boolean } ) => ZodAppliedResult ;
17- schema : SchemaWithType < 'array' > ;
18- } ,
19- ) : Omit < Ast , 'typeName' > {
20- const { applyModifiers, plugin, walk } = options ;
21- let { schema } = options ;
22-
23- const result : Partial < Omit < Ast , 'typeName' > > = { } ;
11+ export function arrayToAst ( {
12+ applyModifiers,
13+ plugin,
14+ schema,
15+ walk,
16+ walkerCtx,
17+ } : {
18+ applyModifiers : ( result : ZodResult , opts : { optional ?: boolean } ) => ZodFinal ;
19+ plugin : ZodPlugin [ 'Instance' ] ;
20+ schema : SchemaWithType < 'array' > ;
21+ walk : Walker < ZodResult , ZodPlugin [ 'Instance' ] > ;
22+ walkerCtx : SchemaVisitorContext < ZodPlugin [ 'Instance' ] > ;
23+ } ) : CompositeHandlerResult {
24+ const childResults : Array < ZodResult > = [ ] ;
25+ let schemaCopy = schema ;
2426
2527 const z = plugin . external ( 'zod.z' ) ;
2628 const functionName = $ ( z ) . attr ( identifiers . array ) ;
2729
28- if ( ! schema . items ) {
29- result . expression = functionName . call (
30+ let arrayExpression : ReturnType < typeof $ . call > | undefined ;
31+
32+ if ( ! schemaCopy . items ) {
33+ arrayExpression = functionName . call (
3034 unknownToAst ( {
31- ...options ,
32- schema : {
33- type : 'unknown' ,
34- } ,
35- } ) . expression ,
35+ plugin,
36+ schema : { type : 'unknown' } ,
37+ } ) ,
3638 ) ;
3739 } else {
38- schema = deduplicateSchema ( { schema } ) ;
40+ schemaCopy = deduplicateSchema ( { schema : schemaCopy } ) ;
3941
40- // at least one item is guaranteed
41- const itemExpressions = schema . items ! . map ( ( item , index ) => {
42- const itemResult = walk (
43- item ,
44- childContext (
45- {
46- path : options . state . path ,
47- plugin : options . plugin ,
48- } ,
49- 'items' ,
50- index ,
51- ) ,
52- ) ;
53- if ( itemResult . hasLazyExpression ) {
54- result . hasLazyExpression = true ;
55- }
42+ const itemExpressions : Array < Chain > = [ ] ;
43+
44+ schemaCopy . items ! . forEach ( ( item , index ) => {
45+ const itemResult = walk ( item , childContext ( walkerCtx , 'items' , index ) ) ;
46+ childResults . push ( itemResult ) ;
5647
5748 const finalExpr = applyModifiers ( itemResult , { optional : false } ) ;
58- return finalExpr . expression ;
49+ itemExpressions . push ( finalExpr . expression ) ;
5950 } ) ;
6051
6152 if ( itemExpressions . length === 1 ) {
62- result . expression = functionName . call ( ...itemExpressions ) ;
53+ arrayExpression = functionName . call ( ...itemExpressions ) ;
6354 } else {
64- if ( schema . logicalOperator === 'and' ) {
65- const firstSchema = schema . items ! [ 0 ] ! ;
66- // we want to add an intersection, but not every schema can use the same API.
67- // if the first item contains another array or not an object, we cannot use
68- // `.intersection()` as that does not exist on `.union()` and non-object schemas.
69- let intersectionExpression : ReturnType < typeof $ . expr | typeof $ . call > ;
70- if (
71- firstSchema . logicalOperator === 'or' ||
72- ( firstSchema . type && firstSchema . type !== 'object' )
73- ) {
74- intersectionExpression = $ ( z )
55+ if ( schemaCopy . logicalOperator === 'and' ) {
56+ arrayExpression = functionName . call (
57+ $ ( z )
7558 . attr ( identifiers . intersection )
76- . call ( ...itemExpressions ) ;
77- } else {
78- intersectionExpression = itemExpressions [ 0 ] ! ;
79- for ( let i = 1 ; i < itemExpressions . length ; i ++ ) {
80- intersectionExpression = $ ( z )
81- . attr ( identifiers . intersection )
82- . call ( intersectionExpression , itemExpressions [ i ] ) ;
83- }
84- }
85-
86- result . expression = functionName . call ( intersectionExpression ) ;
59+ . call ( ...itemExpressions ) ,
60+ ) ;
8761 } else {
88- result . expression = $ ( z )
62+ arrayExpression = $ ( z )
8963 . attr ( identifiers . array )
9064 . call (
9165 $ ( z )
@@ -96,23 +70,28 @@ export function arrayToAst(
9670 }
9771 }
9872
99- const checks : Array < ReturnType < typeof $ . call > > = [ ] ;
100-
101- if ( schema . minItems === schema . maxItems && schema . minItems !== undefined ) {
102- checks . push ( $ ( z ) . attr ( identifiers . length ) . call ( $ . fromValue ( schema . minItems ) ) ) ;
73+ if ( schemaCopy . minItems === schemaCopy . maxItems && schemaCopy . minItems !== undefined ) {
74+ arrayExpression = arrayExpression
75+ . attr ( identifiers . length )
76+ . call ( $ . fromValue ( schemaCopy . minItems ) ) ;
10377 } else {
104- if ( schema . minItems !== undefined ) {
105- checks . push ( $ ( z ) . attr ( identifiers . minLength ) . call ( $ . fromValue ( schema . minItems ) ) ) ;
78+ const checks : Array < ReturnType < typeof $ . call > > = [ ] ;
79+
80+ if ( schemaCopy . minItems !== undefined ) {
81+ checks . push ( $ ( z ) . attr ( identifiers . minLength ) . call ( $ . fromValue ( schemaCopy . minItems ) ) ) ;
10682 }
10783
108- if ( schema . maxItems !== undefined ) {
109- checks . push ( $ ( z ) . attr ( identifiers . maxLength ) . call ( $ . fromValue ( schema . maxItems ) ) ) ;
84+ if ( schemaCopy . maxItems !== undefined ) {
85+ checks . push ( $ ( z ) . attr ( identifiers . maxLength ) . call ( $ . fromValue ( schemaCopy . maxItems ) ) ) ;
11086 }
111- }
11287
113- if ( checks . length > 0 ) {
114- result . expression = result . expression . attr ( identifiers . check ) . call ( ...checks ) ;
88+ if ( checks . length ) {
89+ arrayExpression = arrayExpression . attr ( identifiers . check ) . call ( ...checks ) ;
90+ }
11591 }
11692
117- return result as Omit < Ast , 'typeName' > ;
93+ return {
94+ childResults,
95+ expression : arrayExpression ,
96+ } ;
11897}
0 commit comments