pqb 0.7.13 → 0.8.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.
Files changed (91) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/index.d.ts +618 -563
  3. package/dist/index.esm.js +1011 -402
  4. package/dist/index.esm.js.map +1 -1
  5. package/dist/index.js +1014 -401
  6. package/dist/index.js.map +1 -1
  7. package/package.json +1 -1
  8. package/src/columnSchema/array.test.ts +67 -0
  9. package/src/columnSchema/array.ts +39 -13
  10. package/src/columnSchema/boolean.test.ts +17 -0
  11. package/src/columnSchema/boolean.ts +5 -1
  12. package/src/columnSchema/columnType.test.ts +230 -107
  13. package/src/columnSchema/columnType.ts +198 -28
  14. package/src/columnSchema/columnTypes.ts +28 -15
  15. package/src/columnSchema/columnsSchema.ts +6 -4
  16. package/src/columnSchema/commonMethods.ts +11 -4
  17. package/src/columnSchema/dateTime.test.ts +298 -0
  18. package/src/columnSchema/dateTime.ts +59 -2
  19. package/src/columnSchema/enum.test.ts +33 -0
  20. package/src/columnSchema/enum.ts +11 -1
  21. package/src/columnSchema/json/array.test.ts +21 -0
  22. package/src/columnSchema/json/array.ts +27 -13
  23. package/src/columnSchema/json/discriminatedUnion.test.ts +32 -0
  24. package/src/columnSchema/json/discriminatedUnion.ts +17 -2
  25. package/src/columnSchema/json/enum.test.ts +9 -0
  26. package/src/columnSchema/json/enum.ts +9 -1
  27. package/src/columnSchema/json/index.ts +19 -19
  28. package/src/columnSchema/json/instanceOf.test.ts +8 -0
  29. package/src/columnSchema/json/instanceOf.ts +4 -1
  30. package/src/columnSchema/json/intersection.test.ts +19 -0
  31. package/src/columnSchema/json/intersection.ts +9 -1
  32. package/src/columnSchema/json/lazy.test.ts +22 -0
  33. package/src/columnSchema/json/lazy.ts +22 -1
  34. package/src/columnSchema/json/literal.test.ts +7 -0
  35. package/src/columnSchema/json/literal.ts +12 -1
  36. package/src/columnSchema/json/map.test.ts +10 -0
  37. package/src/columnSchema/json/map.ts +21 -1
  38. package/src/columnSchema/json/nativeEnum.test.ts +10 -0
  39. package/src/columnSchema/json/nativeEnum.ts +4 -1
  40. package/src/columnSchema/json/nullable.test.ts +18 -0
  41. package/src/columnSchema/json/nullish.test.ts +18 -0
  42. package/src/columnSchema/json/object.test.ts +77 -0
  43. package/src/columnSchema/json/object.ts +31 -3
  44. package/src/columnSchema/json/optional.test.ts +18 -0
  45. package/src/columnSchema/json/record.test.ts +14 -0
  46. package/src/columnSchema/json/record.ts +12 -1
  47. package/src/columnSchema/json/scalarTypes.test.ts +133 -0
  48. package/src/columnSchema/json/scalarTypes.ts +90 -1
  49. package/src/columnSchema/json/set.test.ts +29 -0
  50. package/src/columnSchema/json/set.ts +26 -7
  51. package/src/columnSchema/json/tuple.test.ts +17 -0
  52. package/src/columnSchema/json/tuple.ts +16 -1
  53. package/src/columnSchema/json/typeBase.test.ts +123 -0
  54. package/src/columnSchema/json/typeBase.ts +52 -13
  55. package/src/columnSchema/json/union.test.ts +10 -0
  56. package/src/columnSchema/json/union.ts +18 -1
  57. package/src/columnSchema/json.test.ts +17 -0
  58. package/src/columnSchema/json.ts +10 -2
  59. package/src/columnSchema/number.test.ts +176 -0
  60. package/src/columnSchema/number.ts +48 -1
  61. package/src/columnSchema/string.test.ts +412 -0
  62. package/src/columnSchema/string.ts +126 -15
  63. package/src/columnSchema/timestamps.test.ts +6 -6
  64. package/src/columnSchema/virtual.ts +4 -0
  65. package/src/db.ts +1 -1
  66. package/src/query.ts +1 -1
  67. package/src/queryMethods/create.ts +6 -6
  68. package/src/queryMethods/for.ts +3 -3
  69. package/src/queryMethods/having.ts +1 -1
  70. package/src/queryMethods/join.ts +4 -4
  71. package/src/queryMethods/json.ts +1 -1
  72. package/src/queryMethods/queryMethods.ts +2 -2
  73. package/src/queryMethods/select.ts +3 -3
  74. package/src/queryMethods/update.ts +17 -17
  75. package/src/queryMethods/where.test.ts +1 -1
  76. package/src/queryMethods/where.ts +4 -4
  77. package/src/relations.ts +1 -1
  78. package/src/sql/aggregate.ts +2 -2
  79. package/src/sql/copy.ts +3 -3
  80. package/src/sql/delete.ts +5 -5
  81. package/src/sql/fromAndAs.ts +4 -4
  82. package/src/sql/having.ts +7 -7
  83. package/src/sql/insert.ts +5 -5
  84. package/src/sql/join.ts +16 -16
  85. package/src/sql/select.ts +6 -6
  86. package/src/sql/toSql.ts +24 -24
  87. package/src/sql/update.ts +4 -4
  88. package/src/sql/where.ts +18 -18
  89. package/src/utils.test.ts +9 -0
  90. package/src/utils.ts +3 -0
  91. package/src/columnSchema/columnTypes.test.ts +0 -527
@@ -1,4 +1,4 @@
1
- import { constructType, JSONType, JSONTypeAny } from './typeBase';
1
+ import { constructType, JSONType, JSONTypeAny, toCode } from './typeBase';
2
2
  import { BaseNumberData } from '../number';
3
3
  import { BaseStringData } from '../string';
4
4
  import {
@@ -7,6 +7,7 @@ import {
7
7
  stringTypeMethods,
8
8
  } from '../commonMethods';
9
9
  import { DateColumnData } from '../dateTime';
10
+ import { singleQuote } from '../../utils';
10
11
 
11
12
  export type JSONAny = JSONTypeAny & {
12
13
  dataType: 'any';
@@ -14,6 +15,9 @@ export type JSONAny = JSONTypeAny & {
14
15
  const any = () => {
15
16
  return constructType<JSONAny>({
16
17
  dataType: 'any',
18
+ toCode(this: JSONAny, t: string) {
19
+ return toCode(this, t, `${t}.any()`);
20
+ },
17
21
  });
18
22
  };
19
23
 
@@ -23,6 +27,9 @@ export type JSONBigInt = JSONType<bigint, 'bigint'> & {
23
27
  const bigIntMethods = {
24
28
  dataType: 'bigint' as const,
25
29
  ...numberTypeMethods,
30
+ toCode(this: JSONTypeAny, t: string) {
31
+ return toCode(this, t, `${t}.bigint()`);
32
+ },
26
33
  };
27
34
  const bigint = () => {
28
35
  return constructType<JSONBigInt>(bigIntMethods);
@@ -32,6 +39,9 @@ export type JSONBoolean = JSONType<boolean, 'boolean'>;
32
39
  const boolean = () => {
33
40
  return constructType<JSONBoolean>({
34
41
  dataType: 'boolean',
42
+ toCode(this: JSONBoolean, t: string) {
43
+ return toCode(this, t, `${t}.boolean()`);
44
+ },
35
45
  });
36
46
  };
37
47
 
@@ -39,6 +49,9 @@ export type JSONNaN = JSONType<number, 'nan'>;
39
49
  const nan = () => {
40
50
  return constructType<JSONNaN>({
41
51
  dataType: 'nan',
52
+ toCode(this: JSONNaN, t: string) {
53
+ return toCode(this, t, `${t}.nan()`);
54
+ },
42
55
  });
43
56
  };
44
57
 
@@ -46,6 +59,9 @@ export type JSONNever = JSONType<unknown, 'never'>;
46
59
  const never = () => {
47
60
  return constructType<JSONNever>({
48
61
  dataType: 'never',
62
+ toCode(this: JSONNever, t: string) {
63
+ return toCode(this, t, `${t}.never()`);
64
+ },
49
65
  });
50
66
  };
51
67
 
@@ -53,6 +69,9 @@ export type JSONNull = JSONType<null, 'null'>;
53
69
  const nullType = () => {
54
70
  return constructType<JSONNull>({
55
71
  dataType: 'null',
72
+ toCode(this: JSONNull, t: string) {
73
+ return toCode(this, t, `${t}.null()`);
74
+ },
56
75
  });
57
76
  };
58
77
 
@@ -62,6 +81,24 @@ export type JSONNumber = JSONType<number, 'number'> & {
62
81
  const numberMethods = {
63
82
  ...numberTypeMethods,
64
83
  dataType: 'number' as const,
84
+ toCode(
85
+ this: JSONType<number, 'number'> & {
86
+ data: BaseNumberData;
87
+ },
88
+ t: string,
89
+ ) {
90
+ let code = `${t}.number()`;
91
+
92
+ if (this.data.gte !== undefined) code += `.min(${this.data.gte})`;
93
+ if (this.data.gt !== undefined) code += `.gt(${this.data.gt})`;
94
+ if (this.data.lte !== undefined) code += `.max(${this.data.lte})`;
95
+ if (this.data.lt !== undefined) code += `.lt(${this.data.lt})`;
96
+ if (this.data.multipleOf !== undefined)
97
+ code += `.step(${this.data.multipleOf})`;
98
+ if (this.data.int) code += `.int()`;
99
+
100
+ return toCode(this, t, code);
101
+ },
65
102
  };
66
103
  const number = () => {
67
104
  return constructType<JSONNumber>(numberMethods);
@@ -73,6 +110,21 @@ export type JSONDate = JSONType<Date, 'date'> & {
73
110
  const dateMethods = {
74
111
  ...dateTypeMethods,
75
112
  dataType: 'date' as const,
113
+ toCode(
114
+ this: JSONType<Date, 'date'> & {
115
+ data: DateColumnData;
116
+ },
117
+ t: string,
118
+ ) {
119
+ let code = `${t}.date()`;
120
+
121
+ if (this.data.min)
122
+ code += `.min(new Date('${this.data.min.toISOString()}'))`;
123
+ if (this.data.max)
124
+ code += `.max(new Date('${this.data.max.toISOString()}'))`;
125
+
126
+ return toCode(this, t, code);
127
+ },
76
128
  };
77
129
  const date = () => {
78
130
  return constructType<JSONDate>(dateMethods);
@@ -84,6 +136,34 @@ export type JSONString = JSONType<string, 'string'> & {
84
136
  const stringMethods = {
85
137
  ...stringTypeMethods(),
86
138
  dataType: 'string' as const,
139
+ toCode(
140
+ this: JSONType<string, 'string'> & {
141
+ data: BaseStringData;
142
+ },
143
+ t: string,
144
+ ) {
145
+ let code = `${t}.string()`;
146
+
147
+ const { min, isNonEmpty } = this.data;
148
+
149
+ if (min !== undefined && (!isNonEmpty || (isNonEmpty && min !== 1)))
150
+ code += `.min(${min})`;
151
+
152
+ if (this.data.max !== undefined) code += `.max(${this.data.max})`;
153
+ if (this.data.length !== undefined) code += `.length(${this.data.length})`;
154
+ if (this.data.email !== undefined) code += `.email()`;
155
+ if (this.data.url !== undefined) code += `.url()`;
156
+ if (this.data.uuid !== undefined) code += `.uuid()`;
157
+ if (this.data.cuid !== undefined) code += `.cuid()`;
158
+ if (this.data.regex) code += `.regex(${this.data.regex.toString()})`;
159
+ if (this.data.startsWith !== undefined)
160
+ code += `.startsWith(${singleQuote(this.data.startsWith)})`;
161
+ if (this.data.endsWith !== undefined)
162
+ code += `.endsWith(${singleQuote(this.data.endsWith)})`;
163
+ if (this.data.cuid !== undefined) code += `.trim()`;
164
+
165
+ return toCode(this, t, code);
166
+ },
87
167
  };
88
168
  const string = () => {
89
169
  return constructType<JSONString>(stringMethods);
@@ -93,6 +173,9 @@ export type JSONUndefined = JSONType<undefined, 'undefined'>;
93
173
  const undefinedType = () => {
94
174
  return constructType<JSONUndefined>({
95
175
  dataType: 'undefined',
176
+ toCode(this: JSONUndefined, t: string) {
177
+ return toCode(this, t, `${t}.undefined()`);
178
+ },
96
179
  });
97
180
  };
98
181
 
@@ -100,6 +183,9 @@ export type JSONUnknown = JSONType<unknown, 'unknown'>;
100
183
  const unknown = () => {
101
184
  return constructType<JSONUnknown>({
102
185
  dataType: 'unknown',
186
+ toCode(this: JSONUnknown, t: string) {
187
+ return toCode(this, t, `${t}.unknown()`);
188
+ },
103
189
  });
104
190
  };
105
191
 
@@ -107,6 +193,9 @@ export type JSONVoid = JSONType<void, 'void'>;
107
193
  const voidType = () => {
108
194
  return constructType<JSONVoid>({
109
195
  dataType: 'void',
196
+ toCode(this: JSONVoid, t: string) {
197
+ return toCode(this, t, `${t}.void()`);
198
+ },
110
199
  });
111
200
  };
112
201
 
@@ -0,0 +1,29 @@
1
+ import { set } from './set';
2
+ import { scalarTypes } from './scalarTypes';
3
+
4
+ const { number } = scalarTypes;
5
+
6
+ describe('set', () => {
7
+ it('should have toCode', () => {
8
+ expect(set(number()).toCode('t')).toEqual(['t.set(', 't.number()', ')']);
9
+
10
+ expect(set(number()).deepPartial().toCode('t')).toEqual([
11
+ 't.set(',
12
+ 't.number().optional()',
13
+ ')',
14
+ ]);
15
+
16
+ expect(set(number()).nonEmpty().toCode('t')).toEqual([
17
+ 't.set(',
18
+ 't.number()',
19
+ ')',
20
+ '.nonEmpty()',
21
+ ]);
22
+
23
+ expect(set(number()).min(1).max(10).size(15).toCode('t')).toEqual([
24
+ 't.set(',
25
+ 't.number()',
26
+ ').min(1).max(10).size(15)',
27
+ ]);
28
+ });
29
+ });
@@ -1,5 +1,12 @@
1
- import { constructType, JSONType, JSONTypeAny, JSONTypeData } from './typeBase';
1
+ import {
2
+ constructType,
3
+ JSONType,
4
+ JSONTypeAny,
5
+ JSONTypeData,
6
+ toCode,
7
+ } from './typeBase';
2
8
  import { SetMethods, setMethods } from '../commonMethods';
9
+ import { toArray } from '../../utils';
3
10
 
4
11
  export interface JSONSet<Value extends JSONTypeAny>
5
12
  extends JSONType<Set<Value['type']>, 'set'>,
@@ -11,24 +18,36 @@ export interface JSONSet<Value extends JSONTypeAny>
11
18
  };
12
19
  valueType: Value;
13
20
  deepPartial(): JSONSet<ReturnType<Value['deepPartial']>>;
14
- nonEmpty(this: JSONSet<Value>): JSONSet<Value> & { data: { min: 1 } };
15
21
  }
16
22
 
17
23
  export const set = <Value extends JSONTypeAny>(valueType: Value) => {
18
24
  return constructType<JSONSet<Value>>({
19
25
  dataType: 'set',
20
26
  valueType,
27
+ toCode(this: JSONSet<Value>, t: string) {
28
+ let append = ')';
29
+
30
+ const { min, max, size, isNonEmpty } = this.data;
31
+
32
+ if (min !== undefined && (!isNonEmpty || (isNonEmpty && min !== 1)))
33
+ append += `.min(${min})`;
34
+
35
+ if (max !== undefined) append += `.max(${max})`;
36
+
37
+ if (size !== undefined) append += `.size(${size})`;
38
+
39
+ return toCode(this, t, [
40
+ `${t}.set(`,
41
+ ...toArray(this.valueType.toCode(t)),
42
+ append,
43
+ ]);
44
+ },
21
45
  deepPartial(this: JSONSet<Value>) {
22
46
  return {
23
47
  ...this,
24
48
  valueType: this.valueType.deepPartial(),
25
49
  };
26
50
  },
27
- nonEmpty(this: JSONSet<Value>) {
28
- return this.min(1) as unknown as JSONSet<Value> & {
29
- data: { min: 1 };
30
- };
31
- },
32
51
  ...setMethods,
33
52
  });
34
53
  };
@@ -0,0 +1,17 @@
1
+ import { tuple } from './tuple';
2
+ import { scalarTypes } from './scalarTypes';
3
+
4
+ describe('tuple', () => {
5
+ it('should have toCode', () => {
6
+ expect(
7
+ tuple([scalarTypes.string(), scalarTypes.number()]).toCode('t'),
8
+ ).toBe('t.tuple([t.string(), t.number()])');
9
+
10
+ expect(
11
+ tuple(
12
+ [scalarTypes.string(), scalarTypes.number()],
13
+ scalarTypes.boolean(),
14
+ ).toCode('t'),
15
+ ).toBe('t.tuple([t.string(), t.number()], t.boolean())');
16
+ });
17
+ });
@@ -1,4 +1,10 @@
1
- import { constructType, DeepPartial, JSONType, JSONTypeAny } from './typeBase';
1
+ import {
2
+ constructType,
3
+ DeepPartial,
4
+ JSONType,
5
+ JSONTypeAny,
6
+ toCode,
7
+ } from './typeBase';
2
8
 
3
9
  export interface JSONTuple<
4
10
  T extends JSONTupleItems | [] = JSONTupleItems,
@@ -39,6 +45,15 @@ export const tuple = <
39
45
  dataType: 'tuple',
40
46
  items,
41
47
  restType: rest,
48
+ toCode(this: JSONTuple<T, Rest>, t: string) {
49
+ return toCode(
50
+ this,
51
+ t,
52
+ `${t}.tuple([${this.items.map((item) => item.toCode(t)).join(', ')}]${
53
+ this.restType ? `, ${this.restType.toCode(t)}` : ''
54
+ })`,
55
+ );
56
+ },
42
57
  rest<Rest extends JSONTypeAny | null>(rest: Rest): JSONTuple<T, Rest> {
43
58
  return {
44
59
  ...this,
@@ -0,0 +1,123 @@
1
+ import { scalarTypes } from './scalarTypes';
2
+
3
+ const { string, number } = scalarTypes;
4
+
5
+ describe('typeBase', () => {
6
+ describe('optional', () => {
7
+ it('should have toCode', () => {
8
+ expect(string().optional().toCode('t')).toBe('t.string().optional()');
9
+ });
10
+ });
11
+
12
+ describe('required', () => {
13
+ it('should have toCode', () => {
14
+ expect(string().optional().required().toCode('t')).toBe('t.string()');
15
+ });
16
+ });
17
+
18
+ describe('nullable', () => {
19
+ it('should have toCode', () => {
20
+ expect(string().nullable().toCode('t')).toBe('t.string().nullable()');
21
+ });
22
+ });
23
+
24
+ describe('notNullable', () => {
25
+ it('should have toCode', () => {
26
+ expect(string().nullable().notNullable().toCode('t')).toBe('t.string()');
27
+ });
28
+ });
29
+
30
+ describe('nullish', () => {
31
+ it('should have toCode', () => {
32
+ expect(string().nullish().toCode('t')).toBe('t.string().nullish()');
33
+ });
34
+ });
35
+
36
+ describe('notNullish', () => {
37
+ it('should have toCode', () => {
38
+ expect(string().nullish().notNullish().toCode('t')).toBe('t.string()');
39
+ });
40
+ });
41
+
42
+ describe('deepPartial', () => {
43
+ it('should have toCode', () => {
44
+ expect(string().deepPartial().toCode('t')).toBe('t.string().optional()');
45
+ });
46
+ });
47
+
48
+ describe('transform', () => {
49
+ it('should have toCode', () => {
50
+ expect(
51
+ string()
52
+ .transform((s) => s)
53
+ .toCode('t'),
54
+ ).toEqual(['t.string()', '.transform((s)=>s)']);
55
+ });
56
+ });
57
+
58
+ describe('to', () => {
59
+ it('should have toCode', () => {
60
+ expect(
61
+ string()
62
+ .to((s) => parseInt(s), number())
63
+ .toCode('t'),
64
+ ).toEqual(['t.string()', '.to((s)=>parseInt(s), ', 't.number()', ')']);
65
+ });
66
+ });
67
+
68
+ describe('refine', () => {
69
+ it('should have toCode', () => {
70
+ expect(
71
+ string()
72
+ .refine((s) => s.length > 0)
73
+ .toCode('t'),
74
+ ).toEqual(['t.string()', '.refine((s)=>s.length > 0)']);
75
+ });
76
+ });
77
+
78
+ describe('superRefine', () => {
79
+ it('should have toCode', () => {
80
+ expect(
81
+ string()
82
+ .superRefine((s) => s)
83
+ .toCode('t'),
84
+ ).toEqual(['t.string()', '.superRefine((s)=>s)']);
85
+ });
86
+ });
87
+
88
+ describe('and', () => {
89
+ it('should have toCode', () => {
90
+ expect(string().and(number()).toCode('t')).toEqual([
91
+ 't.string()',
92
+ '.and(',
93
+ 't.number()',
94
+ ')',
95
+ ]);
96
+ });
97
+ });
98
+
99
+ describe('or', () => {
100
+ it('should have toCode', () => {
101
+ expect(string().or(number()).toCode('t')).toEqual([
102
+ 't.string()',
103
+ '.or(',
104
+ 't.number()',
105
+ ')',
106
+ ]);
107
+ });
108
+ });
109
+
110
+ describe('default', () => {
111
+ it('should have toCode', () => {
112
+ expect(string().default('value').toCode('t')).toBe(
113
+ 't.string().default("value")',
114
+ );
115
+ });
116
+ });
117
+
118
+ describe('array', () => {
119
+ it('should have toCode', () => {
120
+ expect(string().array().toCode('t')).toEqual(['t.string()', '.array()']);
121
+ });
122
+ });
123
+ });
@@ -9,10 +9,16 @@ import { JSONNotNullish, JSONNullish, notNullish, nullish } from './nullish';
9
9
  import { intersection, JSONIntersection } from './intersection';
10
10
  import { array, JSONArray } from './array';
11
11
  import { union } from './union';
12
- import { ColumnData, ValidationContext } from '../columnType';
12
+ import {
13
+ Code,
14
+ ColumnChain,
15
+ columnChainToCode,
16
+ ColumnData,
17
+ ValidationContext,
18
+ } from '../columnType';
13
19
 
14
20
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
15
- export type JSONTypeAny = JSONType<any, string>;
21
+ export type JSONTypeAny = JSONType<any>;
16
22
 
17
23
  export type DeepPartial<T extends JSONTypeAny> = ReturnType<
18
24
  JSONTypeAny['deepPartial']
@@ -23,6 +29,8 @@ export type DeepPartial<T extends JSONTypeAny> = ReturnType<
23
29
  export type JSONTypeData = ColumnData & {
24
30
  optional?: true;
25
31
  nullable?: true;
32
+ isDeepPartial?: true;
33
+ isNonEmpty?: true;
26
34
  };
27
35
 
28
36
  export type Primitive = string | number | bigint | boolean | null | undefined;
@@ -31,12 +39,9 @@ export type JSONType<Type, DataType extends string = string> = {
31
39
  type: Type;
32
40
  data: JSONTypeData;
33
41
  dataType: DataType;
34
- chain: (
35
- | ['transform', (input: unknown, ctx: ValidationContext) => unknown]
36
- | ['to', (input: unknown) => JSONTypeAny | undefined, JSONTypeAny]
37
- | ['refine', (input: unknown) => unknown]
38
- | ['superRefine', (input: unknown, ctx: ValidationContext) => unknown]
39
- )[];
42
+ chain: ColumnChain;
43
+
44
+ toCode(t: string): Code;
40
45
 
41
46
  optional<T extends JSONTypeAny>(this: T): JSONOptional<T>;
42
47
  required<T extends JSONTypeAny>(this: T): JSONRequired<T>;
@@ -90,6 +95,32 @@ export type JSONType<Type, DataType extends string = string> = {
90
95
  array<T extends JSONTypeAny>(this: T): JSONArray<T>;
91
96
  };
92
97
 
98
+ export const toCode = (type: JSONTypeAny, t: string, code: Code) => {
99
+ let append = '';
100
+
101
+ if (type.data.nullable && type.data.optional) {
102
+ append += '.nullish()';
103
+ } else if (type.data.nullable) {
104
+ append += '.nullable()';
105
+ } else if (type.data.optional) {
106
+ append += '.optional()';
107
+ }
108
+
109
+ if (type.data.isDeepPartial) {
110
+ append += '.deepPartial()';
111
+ }
112
+
113
+ if (type.data.isNonEmpty) {
114
+ append += '.nonEmpty()';
115
+ }
116
+
117
+ if (type.data.default) {
118
+ append += `.default(${JSON.stringify(type.data.default)})`;
119
+ }
120
+
121
+ return columnChainToCode(type.chain, t, code, append);
122
+ };
123
+
93
124
  const baseTypeMethods: JSONTypeAny = {
94
125
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
95
126
  type: undefined as any,
@@ -97,6 +128,10 @@ const baseTypeMethods: JSONTypeAny = {
97
128
  dataType: 'any',
98
129
  chain: [],
99
130
 
131
+ toCode() {
132
+ throw new Error('toCode is not implemented');
133
+ },
134
+
100
135
  optional<T extends JSONTypeAny>(this: T) {
101
136
  return optional(this);
102
137
  },
@@ -122,7 +157,7 @@ const baseTypeMethods: JSONTypeAny = {
122
157
  },
123
158
 
124
159
  deepPartial() {
125
- return this;
160
+ return this.optional();
126
161
  },
127
162
 
128
163
  transform<T extends JSONTypeAny, Transformed>(
@@ -135,11 +170,15 @@ const baseTypeMethods: JSONTypeAny = {
135
170
  };
136
171
  },
137
172
 
138
- to(fn, type) {
173
+ to<T extends JSONTypeAny, ToType extends JSONTypeAny>(
174
+ this: T,
175
+ fn: (input: T['type']) => ToType['type'] | undefined,
176
+ type: ToType,
177
+ ): ToType {
139
178
  return {
140
- ...type,
179
+ ...this,
141
180
  chain: [...this.chain, ['to', fn, type], ...type.chain],
142
- };
181
+ } as unknown as ToType;
143
182
  },
144
183
 
145
184
  refine(check) {
@@ -177,7 +216,7 @@ const baseTypeMethods: JSONTypeAny = {
177
216
  };
178
217
 
179
218
  type BaseTypeProps<T extends JSONTypeAny> = Omit<
180
- JSONType<T['type'], string>,
219
+ JSONType<T['type']>,
181
220
  'dataType'
182
221
  >;
183
222
  export type OwnTypeProps<T extends JSONTypeAny> = Omit<
@@ -0,0 +1,10 @@
1
+ import { union } from './union';
2
+ import { scalarTypes } from './scalarTypes';
3
+
4
+ describe('union', () => {
5
+ it('should have toCode', () => {
6
+ expect(
7
+ union([scalarTypes.string(), scalarTypes.number()]).toCode('t'),
8
+ ).toEqual(['t.string()', '.or(', 't.number()', ')']);
9
+ });
10
+ });
@@ -1,4 +1,5 @@
1
- import { constructType, JSONType, JSONTypeAny } from './typeBase';
1
+ import { constructType, JSONType, JSONTypeAny, toCode } from './typeBase';
2
+ import { toArray } from '../../utils';
2
3
 
3
4
  export interface JSONUnion<
4
5
  T extends [JSONTypeAny, JSONTypeAny, ...JSONTypeAny[]],
@@ -12,5 +13,21 @@ export const union = <T extends [JSONTypeAny, JSONTypeAny, ...JSONTypeAny[]]>(
12
13
  return constructType<JSONUnion<T>>({
13
14
  dataType: 'union',
14
15
  types,
16
+ toCode(this: JSONUnion<T>, t: string) {
17
+ const last = this.types.length - 1;
18
+ return toCode(
19
+ this,
20
+ t,
21
+ this.types.flatMap((type, i) => {
22
+ const item = [...toArray(type.toCode(t))];
23
+ if (i < last) {
24
+ item.push(`${i > 0 ? ')' : ''}.or(`);
25
+ } else {
26
+ item.push(')');
27
+ }
28
+ return item;
29
+ }),
30
+ );
31
+ },
15
32
  });
16
33
  };
@@ -0,0 +1,17 @@
1
+ import { JSONColumn, JSONTextColumn } from './json';
2
+
3
+ describe('json columns', () => {
4
+ describe('json', () => {
5
+ it('should have toCode', () => {
6
+ expect(new JSONColumn((t) => t.string()).toCode('t')).toBe(
7
+ 't.json((t) => t.string())',
8
+ );
9
+ });
10
+ });
11
+
12
+ describe('jsonText', () => {
13
+ it('should have toCode', () => {
14
+ expect(new JSONTextColumn().toCode('t')).toBe('t.jsonText()');
15
+ });
16
+ });
17
+ });
@@ -1,4 +1,4 @@
1
- import { ColumnData, ColumnType } from './columnType';
1
+ import { Code, columnCode, ColumnData, ColumnType } from './columnType';
2
2
  import { Operators } from '../columnsOperators';
3
3
  import {
4
4
  scalarTypes,
@@ -20,7 +20,7 @@ import {
20
20
  tuple,
21
21
  union,
22
22
  JSONTypeAny,
23
- } from './json/index';
23
+ } from './json';
24
24
 
25
25
  export * from './json/index';
26
26
 
@@ -60,9 +60,17 @@ export class JSONColumn<
60
60
  typeof schemaOrFn === 'function' ? schemaOrFn(jsonTypes) : schemaOrFn;
61
61
  this.data = { schema };
62
62
  }
63
+
64
+ toCode(t: string): Code {
65
+ const { schema } = this.data;
66
+ return columnCode(this, t, `${t}.json((t) => ${schema.toCode('t')})`);
67
+ }
63
68
  }
64
69
 
65
70
  export class JSONTextColumn extends ColumnType<string, typeof Operators.text> {
66
71
  dataType = 'json' as const;
67
72
  operators = Operators.text;
73
+ toCode(t: string): Code {
74
+ return columnCode(this, t, `${t}.jsonText()`);
75
+ }
68
76
  }