tinybase 9.4.0 → 9.5.0-beta.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 (126) hide show
  1. package/@types/_internal/store/with-schemas/index.d.ts +43 -8
  2. package/@types/mergeable-store/with-schemas/index.d.ts +30 -11
  3. package/@types/queries/index.d.ts +11 -11
  4. package/@types/queries/with-schemas/index.d.ts +17 -3
  5. package/@types/schematizers/index.d.ts +6 -4
  6. package/@types/schematizers/schematizer-arktype/index.d.ts +6 -6
  7. package/@types/schematizers/schematizer-arktype/with-schemas/index.d.ts +112 -1
  8. package/@types/schematizers/schematizer-effect/index.d.ts +9 -11
  9. package/@types/schematizers/schematizer-effect/with-schemas/index.d.ts +114 -1
  10. package/@types/schematizers/schematizer-typebox/index.d.ts +7 -7
  11. package/@types/schematizers/schematizer-typebox/with-schemas/index.d.ts +114 -1
  12. package/@types/schematizers/schematizer-valibot/index.d.ts +6 -6
  13. package/@types/schematizers/schematizer-valibot/with-schemas/index.d.ts +112 -1
  14. package/@types/schematizers/schematizer-yup/index.d.ts +5 -4
  15. package/@types/schematizers/schematizer-yup/with-schemas/index.d.ts +112 -1
  16. package/@types/schematizers/schematizer-zod/index.d.ts +6 -6
  17. package/@types/schematizers/schematizer-zod/with-schemas/index.d.ts +112 -1
  18. package/@types/schematizers/with-schemas/index.d.ts +113 -4
  19. package/@types/store/index.d.ts +175 -16
  20. package/@types/store/with-schemas/index.d.ts +238 -55
  21. package/@types/synchronizers/with-schemas/index.d.ts +12 -2
  22. package/@types/ui-react/with-schemas/index.d.ts +576 -7
  23. package/@types/ui-react-dom/index.d.ts +10 -10
  24. package/@types/ui-react-dom/with-schemas/index.d.ts +94 -10
  25. package/@types/ui-react-dom-charts/index.d.ts +7 -7
  26. package/@types/ui-react-dom-charts/with-schemas/index.d.ts +7 -7
  27. package/@types/ui-react-inspector/index.d.ts +1 -1
  28. package/@types/ui-react-inspector/with-schemas/index.d.ts +1 -1
  29. package/@types/ui-solid/with-schemas/index.d.ts +340 -7
  30. package/@types/ui-solid-dom/index.d.ts +10 -10
  31. package/@types/ui-solid-dom/with-schemas/index.d.ts +94 -10
  32. package/@types/ui-solid-inspector/index.d.ts +1 -1
  33. package/@types/ui-solid-inspector/with-schemas/index.d.ts +1 -1
  34. package/@types/ui-svelte/with-schemas/index.d.ts +30 -0
  35. package/@types/ui-svelte-dom/index.d.ts +10 -10
  36. package/@types/ui-svelte-dom/with-schemas/index.d.ts +94 -10
  37. package/@types/ui-svelte-inspector/index.d.ts +1 -1
  38. package/@types/ui-svelte-inspector/with-schemas/index.d.ts +1 -1
  39. package/agents.md +4 -0
  40. package/index.js +76 -22
  41. package/mergeable-store/index.js +76 -22
  42. package/mergeable-store/with-schemas/index.js +76 -22
  43. package/min/index.js +1 -1
  44. package/min/index.js.gz +0 -0
  45. package/min/mergeable-store/index.js +1 -1
  46. package/min/mergeable-store/index.js.gz +0 -0
  47. package/min/mergeable-store/with-schemas/index.js +1 -1
  48. package/min/mergeable-store/with-schemas/index.js.gz +0 -0
  49. package/min/omni/index.js +1 -1
  50. package/min/omni/index.js.gz +0 -0
  51. package/min/omni/with-schemas/index.js +1 -1
  52. package/min/omni/with-schemas/index.js.gz +0 -0
  53. package/min/schematizers/index.js +1 -1
  54. package/min/schematizers/index.js.gz +0 -0
  55. package/min/schematizers/schematizer-arktype/index.js +1 -1
  56. package/min/schematizers/schematizer-arktype/index.js.gz +0 -0
  57. package/min/schematizers/schematizer-arktype/with-schemas/index.js +1 -1
  58. package/min/schematizers/schematizer-arktype/with-schemas/index.js.gz +0 -0
  59. package/min/schematizers/schematizer-effect/index.js +1 -1
  60. package/min/schematizers/schematizer-effect/index.js.gz +0 -0
  61. package/min/schematizers/schematizer-effect/with-schemas/index.js +1 -1
  62. package/min/schematizers/schematizer-effect/with-schemas/index.js.gz +0 -0
  63. package/min/schematizers/schematizer-typebox/index.js +1 -1
  64. package/min/schematizers/schematizer-typebox/index.js.gz +0 -0
  65. package/min/schematizers/schematizer-typebox/with-schemas/index.js +1 -1
  66. package/min/schematizers/schematizer-typebox/with-schemas/index.js.gz +0 -0
  67. package/min/schematizers/schematizer-valibot/index.js +1 -1
  68. package/min/schematizers/schematizer-valibot/index.js.gz +0 -0
  69. package/min/schematizers/schematizer-valibot/with-schemas/index.js +1 -1
  70. package/min/schematizers/schematizer-valibot/with-schemas/index.js.gz +0 -0
  71. package/min/schematizers/schematizer-yup/index.js +1 -1
  72. package/min/schematizers/schematizer-yup/index.js.gz +0 -0
  73. package/min/schematizers/schematizer-yup/with-schemas/index.js +1 -1
  74. package/min/schematizers/schematizer-yup/with-schemas/index.js.gz +0 -0
  75. package/min/schematizers/schematizer-zod/index.js +1 -1
  76. package/min/schematizers/schematizer-zod/index.js.gz +0 -0
  77. package/min/schematizers/schematizer-zod/with-schemas/index.js +1 -1
  78. package/min/schematizers/schematizer-zod/with-schemas/index.js.gz +0 -0
  79. package/min/schematizers/with-schemas/index.js +1 -1
  80. package/min/schematizers/with-schemas/index.js.gz +0 -0
  81. package/min/store/index.js +1 -1
  82. package/min/store/index.js.gz +0 -0
  83. package/min/store/with-schemas/index.js +1 -1
  84. package/min/store/with-schemas/index.js.gz +0 -0
  85. package/min/ui-react-inspector/index.js +1 -1
  86. package/min/ui-react-inspector/index.js.gz +0 -0
  87. package/min/ui-react-inspector/with-schemas/index.js +1 -1
  88. package/min/ui-react-inspector/with-schemas/index.js.gz +0 -0
  89. package/min/ui-solid-inspector/index.js +1 -1
  90. package/min/ui-solid-inspector/index.js.gz +0 -0
  91. package/min/ui-solid-inspector/with-schemas/index.js +1 -1
  92. package/min/ui-solid-inspector/with-schemas/index.js.gz +0 -0
  93. package/min/ui-svelte-inspector/index.js +1 -1
  94. package/min/ui-svelte-inspector/index.js.gz +0 -0
  95. package/min/ui-svelte-inspector/with-schemas/index.js +1 -1
  96. package/min/ui-svelte-inspector/with-schemas/index.js.gz +0 -0
  97. package/min/with-schemas/index.js +1 -1
  98. package/min/with-schemas/index.js.gz +0 -0
  99. package/omni/index.js +76 -22
  100. package/omni/with-schemas/index.js +76 -22
  101. package/package.json +2 -2
  102. package/readme.md +14 -14
  103. package/releases.md +95 -65
  104. package/schematizers/index.js +54 -6
  105. package/schematizers/schematizer-arktype/index.js +99 -19
  106. package/schematizers/schematizer-arktype/with-schemas/index.js +99 -19
  107. package/schematizers/schematizer-effect/index.js +101 -11
  108. package/schematizers/schematizer-effect/with-schemas/index.js +101 -11
  109. package/schematizers/schematizer-typebox/index.js +87 -11
  110. package/schematizers/schematizer-typebox/with-schemas/index.js +87 -11
  111. package/schematizers/schematizer-valibot/index.js +125 -21
  112. package/schematizers/schematizer-valibot/with-schemas/index.js +125 -21
  113. package/schematizers/schematizer-yup/index.js +58 -14
  114. package/schematizers/schematizer-yup/with-schemas/index.js +58 -14
  115. package/schematizers/schematizer-zod/index.js +131 -12
  116. package/schematizers/schematizer-zod/with-schemas/index.js +131 -12
  117. package/schematizers/with-schemas/index.js +54 -6
  118. package/store/index.js +76 -22
  119. package/store/with-schemas/index.js +76 -22
  120. package/ui-react-inspector/index.js +76 -22
  121. package/ui-react-inspector/with-schemas/index.js +76 -22
  122. package/ui-solid-inspector/index.js +76 -22
  123. package/ui-solid-inspector/with-schemas/index.js +76 -22
  124. package/ui-svelte-inspector/index.js +76 -22
  125. package/ui-svelte-inspector/with-schemas/index.js +76 -22
  126. package/with-schemas/index.js +76 -22
@@ -6,27 +6,38 @@ const NUMBER = getTypeOf(0);
6
6
  const OBJECT = 'object';
7
7
  const ARRAY = 'array';
8
8
  const TYPE = 'type';
9
+ const ENUM = 'enum';
9
10
  const DEFAULT = 'default';
10
11
  const ALLOW_NULL = 'allowNull';
12
+ const NULL = 'null';
11
13
  const NULLABLE = 'nullable';
12
14
  const OPTIONAL = 'optional';
13
15
  const REQUIRED = 'required';
14
16
  const RECORD = 'record';
17
+ const UNDEFINED = '\uFFFC';
18
+ const JSON_PREFIX = '\uFFFD';
15
19
 
16
20
  const getIfNotFunction = (predicate) => (value, then, otherwise) =>
17
21
  predicate(value)
18
22
  ? /* istanbul ignore next */
19
23
  otherwise?.()
20
24
  : then(value);
25
+ const isFiniteNumber = isFinite;
21
26
  const isNullish = (thing) => thing == null;
22
27
  const isUndefined = (thing) => thing === void 0;
28
+ const isNull = (thing) => thing === null;
23
29
  const ifNotNullish = getIfNotFunction(isNullish);
24
30
  const ifNotUndefined = getIfNotFunction(isUndefined);
31
+ const isTypeStringOrBoolean = (type) => type == STRING || type == BOOLEAN;
25
32
  const isString = (thing) => getTypeOf(thing) == STRING;
33
+ const isArray = (thing) => Array.isArray(thing);
26
34
  const size = (thing) => thing.length;
27
35
 
36
+ const arrayIndexOf = (array, value) => array.indexOf(value);
28
37
  const arrayEvery = (array, cb) => array.every(cb);
29
38
  const arrayForEach = (array, cb) => array.forEach(cb);
39
+ const arrayFilter = (array, cb) => array.filter(cb);
40
+ const arrayPush = (array, ...values) => array.push(...values);
30
41
 
31
42
  const object = Object;
32
43
  const getPrototypeOf = (obj) => object.getPrototypeOf(obj);
@@ -59,9 +70,48 @@ const objNew = (entries = []) => {
59
70
  };
60
71
  const objForEach = (obj, cb) =>
61
72
  arrayForEach(objIds(obj), (id) => cb(obj[id], id));
73
+ const objValues = (obj) => object.values(obj);
62
74
  const objSize = (obj) => size(objIds(obj));
63
75
  const objIsEmpty = (obj) => isObject(obj) && objSize(obj) == 0;
64
76
 
77
+ const getCellOrValueType = (cellOrValue) => {
78
+ if (isNull(cellOrValue)) {
79
+ return NULL;
80
+ }
81
+ if (isArray(cellOrValue)) {
82
+ return ARRAY;
83
+ }
84
+ if (isObject(cellOrValue)) {
85
+ return OBJECT;
86
+ }
87
+ const type = getTypeOf(cellOrValue);
88
+ return isTypeStringOrBoolean(type) ||
89
+ (type == NUMBER && isFiniteNumber(cellOrValue))
90
+ ? type
91
+ : void 0;
92
+ };
93
+ const isJsonType = (type) => type == OBJECT || type == ARRAY;
94
+ const isCellOrValueSchemaType = (type) =>
95
+ isTypeStringOrBoolean(type) || type == NUMBER || isJsonType(type);
96
+ const isCellOrValueSchemaTypes = (types) =>
97
+ isArray(types)
98
+ ? !isUndefined(types[0]) && arrayEvery(types, isCellOrValueSchemaType)
99
+ : isCellOrValueSchemaType(types);
100
+ const isEncodedJson = (value) => isString(value) && value[0] == JSON_PREFIX;
101
+ const isReservedString = (value, encoded = 0) =>
102
+ value === UNDEFINED || (!encoded && isEncodedJson(value));
103
+
104
+ const getTypeOrTypeUnion = (types) => {
105
+ if (!arrayEvery(types, isCellOrValueSchemaType)) {
106
+ return;
107
+ }
108
+ const uniqueTypes = arrayFilter(
109
+ types,
110
+ (type, index) => arrayIndexOf(types, type) == index,
111
+ );
112
+ return uniqueTypes[1] ? uniqueTypes : uniqueTypes[0];
113
+ };
114
+
65
115
  const createCustomSchematizer = (
66
116
  unwrapSchema,
67
117
  getProperties,
@@ -71,16 +121,27 @@ const createCustomSchematizer = (
71
121
  const [unwrapped, defaultValue, allowNull, unwrappedRequired = required] =
72
122
  unwrapSchema(schema, void 0, void 0, required);
73
123
  const type = unwrapped?.type;
124
+ const enumValues = unwrapped?.[ENUM];
125
+ const isEnum =
126
+ isUndefined(type) &&
127
+ isArray(enumValues) &&
128
+ !isUndefined(enumValues[0]) &&
129
+ arrayEvery(enumValues, (enumValue) => {
130
+ const enumType = getCellOrValueType(enumValue);
131
+ return (
132
+ !isNull(enumValue) &&
133
+ !isUndefined(enumType) &&
134
+ !isJsonType(enumType) &&
135
+ !isReservedString(enumValue)
136
+ );
137
+ });
74
138
  if (
75
- type !== STRING &&
76
- type !== NUMBER &&
77
- type !== BOOLEAN &&
78
- type !== OBJECT &&
79
- type !== ARRAY
139
+ !isEnum &&
140
+ (!isUndefined(enumValues) || !isCellOrValueSchemaTypes(type))
80
141
  ) {
81
142
  return void 0;
82
143
  }
83
- const cellOrValueSchema = {[TYPE]: type};
144
+ const cellOrValueSchema = isEnum ? {[ENUM]: enumValues} : {[TYPE]: type};
84
145
  ifNotUndefined(defaultValue, (defaultValue2) => {
85
146
  cellOrValueSchema[DEFAULT] = defaultValue2;
86
147
  });
@@ -130,8 +191,8 @@ const createCustomSchematizer = (
130
191
  });
131
192
  };
132
193
 
133
- const ENUM = 'enum';
134
194
  const LITERAL = 'literal';
195
+ const ZOD_UNION = 'union';
135
196
  const getDef = (schema) => schema?.def ?? schema?._zod?.def;
136
197
  const unwrapSchema = (schema, defaultValue, allowNull, required = true) => {
137
198
  const def = getDef(schema);
@@ -144,11 +205,69 @@ const unwrapSchema = (schema, defaultValue, allowNull, required = true) => {
144
205
  ? unwrapSchema(def.innerType, def.defaultValue, allowNull, false)
145
206
  : type === RECORD
146
207
  ? [{type: OBJECT}, defaultValue, allowNull ?? false, required]
147
- : type === ENUM
148
- ? [{[TYPE]: STRING}, defaultValue, allowNull ?? false, required]
149
- : type === LITERAL && arrayEvery(def.values, isString)
150
- ? [{[TYPE]: STRING}, defaultValue, allowNull ?? false, required]
151
- : [schema, defaultValue, allowNull ?? false, required];
208
+ : type === ZOD_UNION
209
+ ? unwrapUnion(def, defaultValue, allowNull, required)
210
+ : type === ENUM
211
+ ? [
212
+ {[ENUM]: objValues(def.entries)},
213
+ defaultValue,
214
+ allowNull ?? false,
215
+ required,
216
+ ]
217
+ : type === LITERAL
218
+ ? [
219
+ {[ENUM]: def.values},
220
+ defaultValue,
221
+ allowNull ?? false,
222
+ required,
223
+ ]
224
+ : [schema, defaultValue, allowNull ?? false, required];
225
+ };
226
+ const unwrapUnion = (def, defaultValue, allowNull, required = true) => {
227
+ const nonNullOptions = arrayFilter(
228
+ def.options,
229
+ (option) => getDef(option)?.type !== NULL,
230
+ );
231
+ const hasNull = nonNullOptions.length !== def.options.length;
232
+ const enumValues = [];
233
+ const allEnums = arrayEvery(nonNullOptions, (option) => {
234
+ const optionDef = getDef(option);
235
+ const values =
236
+ optionDef?.type === LITERAL
237
+ ? optionDef.values
238
+ : optionDef?.type === ENUM
239
+ ? objValues(optionDef.entries)
240
+ : void 0;
241
+ if (isUndefined(values)) {
242
+ return false;
243
+ }
244
+ arrayForEach(values, (value) => arrayPush(enumValues, value));
245
+ return true;
246
+ });
247
+ const types = [];
248
+ if (!allEnums) {
249
+ arrayForEach(nonNullOptions, (option) => {
250
+ const optionDef = getDef(option);
251
+ const optionType = optionDef?.type;
252
+ if (optionType === LITERAL) {
253
+ arrayForEach(optionDef.values, (value) =>
254
+ arrayPush(types, getCellOrValueType(value)),
255
+ );
256
+ } else if (optionType === ENUM) {
257
+ arrayForEach(objValues(optionDef.entries), (value) =>
258
+ arrayPush(types, getCellOrValueType(value)),
259
+ );
260
+ } else {
261
+ arrayPush(types, optionType === RECORD ? OBJECT : optionType);
262
+ }
263
+ });
264
+ }
265
+ return [
266
+ allEnums ? {[ENUM]: enumValues} : {type: getTypeOrTypeUnion(types)},
267
+ defaultValue,
268
+ allowNull || hasNull,
269
+ required,
270
+ ];
152
271
  };
153
272
  const getProperties = (schema) => getDef(schema)?.shape;
154
273
  const createZodSchematizer = () =>
@@ -6,27 +6,38 @@ const NUMBER = getTypeOf(0);
6
6
  const OBJECT = 'object';
7
7
  const ARRAY = 'array';
8
8
  const TYPE = 'type';
9
+ const ENUM = 'enum';
9
10
  const DEFAULT = 'default';
10
11
  const ALLOW_NULL = 'allowNull';
12
+ const NULL = 'null';
11
13
  const NULLABLE = 'nullable';
12
14
  const OPTIONAL = 'optional';
13
15
  const REQUIRED = 'required';
14
16
  const RECORD = 'record';
17
+ const UNDEFINED = '\uFFFC';
18
+ const JSON_PREFIX = '\uFFFD';
15
19
 
16
20
  const getIfNotFunction = (predicate) => (value, then, otherwise) =>
17
21
  predicate(value)
18
22
  ? /* istanbul ignore next */
19
23
  otherwise?.()
20
24
  : then(value);
25
+ const isFiniteNumber = isFinite;
21
26
  const isNullish = (thing) => thing == null;
22
27
  const isUndefined = (thing) => thing === void 0;
28
+ const isNull = (thing) => thing === null;
23
29
  const ifNotNullish = getIfNotFunction(isNullish);
24
30
  const ifNotUndefined = getIfNotFunction(isUndefined);
31
+ const isTypeStringOrBoolean = (type) => type == STRING || type == BOOLEAN;
25
32
  const isString = (thing) => getTypeOf(thing) == STRING;
33
+ const isArray = (thing) => Array.isArray(thing);
26
34
  const size = (thing) => thing.length;
27
35
 
36
+ const arrayIndexOf = (array, value) => array.indexOf(value);
28
37
  const arrayEvery = (array, cb) => array.every(cb);
29
38
  const arrayForEach = (array, cb) => array.forEach(cb);
39
+ const arrayFilter = (array, cb) => array.filter(cb);
40
+ const arrayPush = (array, ...values) => array.push(...values);
30
41
 
31
42
  const object = Object;
32
43
  const getPrototypeOf = (obj) => object.getPrototypeOf(obj);
@@ -59,9 +70,48 @@ const objNew = (entries = []) => {
59
70
  };
60
71
  const objForEach = (obj, cb) =>
61
72
  arrayForEach(objIds(obj), (id) => cb(obj[id], id));
73
+ const objValues = (obj) => object.values(obj);
62
74
  const objSize = (obj) => size(objIds(obj));
63
75
  const objIsEmpty = (obj) => isObject(obj) && objSize(obj) == 0;
64
76
 
77
+ const getCellOrValueType = (cellOrValue) => {
78
+ if (isNull(cellOrValue)) {
79
+ return NULL;
80
+ }
81
+ if (isArray(cellOrValue)) {
82
+ return ARRAY;
83
+ }
84
+ if (isObject(cellOrValue)) {
85
+ return OBJECT;
86
+ }
87
+ const type = getTypeOf(cellOrValue);
88
+ return isTypeStringOrBoolean(type) ||
89
+ (type == NUMBER && isFiniteNumber(cellOrValue))
90
+ ? type
91
+ : void 0;
92
+ };
93
+ const isJsonType = (type) => type == OBJECT || type == ARRAY;
94
+ const isCellOrValueSchemaType = (type) =>
95
+ isTypeStringOrBoolean(type) || type == NUMBER || isJsonType(type);
96
+ const isCellOrValueSchemaTypes = (types) =>
97
+ isArray(types)
98
+ ? !isUndefined(types[0]) && arrayEvery(types, isCellOrValueSchemaType)
99
+ : isCellOrValueSchemaType(types);
100
+ const isEncodedJson = (value) => isString(value) && value[0] == JSON_PREFIX;
101
+ const isReservedString = (value, encoded = 0) =>
102
+ value === UNDEFINED || (!encoded && isEncodedJson(value));
103
+
104
+ const getTypeOrTypeUnion = (types) => {
105
+ if (!arrayEvery(types, isCellOrValueSchemaType)) {
106
+ return;
107
+ }
108
+ const uniqueTypes = arrayFilter(
109
+ types,
110
+ (type, index) => arrayIndexOf(types, type) == index,
111
+ );
112
+ return uniqueTypes[1] ? uniqueTypes : uniqueTypes[0];
113
+ };
114
+
65
115
  const createCustomSchematizer = (
66
116
  unwrapSchema,
67
117
  getProperties,
@@ -71,16 +121,27 @@ const createCustomSchematizer = (
71
121
  const [unwrapped, defaultValue, allowNull, unwrappedRequired = required] =
72
122
  unwrapSchema(schema, void 0, void 0, required);
73
123
  const type = unwrapped?.type;
124
+ const enumValues = unwrapped?.[ENUM];
125
+ const isEnum =
126
+ isUndefined(type) &&
127
+ isArray(enumValues) &&
128
+ !isUndefined(enumValues[0]) &&
129
+ arrayEvery(enumValues, (enumValue) => {
130
+ const enumType = getCellOrValueType(enumValue);
131
+ return (
132
+ !isNull(enumValue) &&
133
+ !isUndefined(enumType) &&
134
+ !isJsonType(enumType) &&
135
+ !isReservedString(enumValue)
136
+ );
137
+ });
74
138
  if (
75
- type !== STRING &&
76
- type !== NUMBER &&
77
- type !== BOOLEAN &&
78
- type !== OBJECT &&
79
- type !== ARRAY
139
+ !isEnum &&
140
+ (!isUndefined(enumValues) || !isCellOrValueSchemaTypes(type))
80
141
  ) {
81
142
  return void 0;
82
143
  }
83
- const cellOrValueSchema = {[TYPE]: type};
144
+ const cellOrValueSchema = isEnum ? {[ENUM]: enumValues} : {[TYPE]: type};
84
145
  ifNotUndefined(defaultValue, (defaultValue2) => {
85
146
  cellOrValueSchema[DEFAULT] = defaultValue2;
86
147
  });
@@ -130,8 +191,8 @@ const createCustomSchematizer = (
130
191
  });
131
192
  };
132
193
 
133
- const ENUM = 'enum';
134
194
  const LITERAL = 'literal';
195
+ const ZOD_UNION = 'union';
135
196
  const getDef = (schema) => schema?.def ?? schema?._zod?.def;
136
197
  const unwrapSchema = (schema, defaultValue, allowNull, required = true) => {
137
198
  const def = getDef(schema);
@@ -144,11 +205,69 @@ const unwrapSchema = (schema, defaultValue, allowNull, required = true) => {
144
205
  ? unwrapSchema(def.innerType, def.defaultValue, allowNull, false)
145
206
  : type === RECORD
146
207
  ? [{type: OBJECT}, defaultValue, allowNull ?? false, required]
147
- : type === ENUM
148
- ? [{[TYPE]: STRING}, defaultValue, allowNull ?? false, required]
149
- : type === LITERAL && arrayEvery(def.values, isString)
150
- ? [{[TYPE]: STRING}, defaultValue, allowNull ?? false, required]
151
- : [schema, defaultValue, allowNull ?? false, required];
208
+ : type === ZOD_UNION
209
+ ? unwrapUnion(def, defaultValue, allowNull, required)
210
+ : type === ENUM
211
+ ? [
212
+ {[ENUM]: objValues(def.entries)},
213
+ defaultValue,
214
+ allowNull ?? false,
215
+ required,
216
+ ]
217
+ : type === LITERAL
218
+ ? [
219
+ {[ENUM]: def.values},
220
+ defaultValue,
221
+ allowNull ?? false,
222
+ required,
223
+ ]
224
+ : [schema, defaultValue, allowNull ?? false, required];
225
+ };
226
+ const unwrapUnion = (def, defaultValue, allowNull, required = true) => {
227
+ const nonNullOptions = arrayFilter(
228
+ def.options,
229
+ (option) => getDef(option)?.type !== NULL,
230
+ );
231
+ const hasNull = nonNullOptions.length !== def.options.length;
232
+ const enumValues = [];
233
+ const allEnums = arrayEvery(nonNullOptions, (option) => {
234
+ const optionDef = getDef(option);
235
+ const values =
236
+ optionDef?.type === LITERAL
237
+ ? optionDef.values
238
+ : optionDef?.type === ENUM
239
+ ? objValues(optionDef.entries)
240
+ : void 0;
241
+ if (isUndefined(values)) {
242
+ return false;
243
+ }
244
+ arrayForEach(values, (value) => arrayPush(enumValues, value));
245
+ return true;
246
+ });
247
+ const types = [];
248
+ if (!allEnums) {
249
+ arrayForEach(nonNullOptions, (option) => {
250
+ const optionDef = getDef(option);
251
+ const optionType = optionDef?.type;
252
+ if (optionType === LITERAL) {
253
+ arrayForEach(optionDef.values, (value) =>
254
+ arrayPush(types, getCellOrValueType(value)),
255
+ );
256
+ } else if (optionType === ENUM) {
257
+ arrayForEach(objValues(optionDef.entries), (value) =>
258
+ arrayPush(types, getCellOrValueType(value)),
259
+ );
260
+ } else {
261
+ arrayPush(types, optionType === RECORD ? OBJECT : optionType);
262
+ }
263
+ });
264
+ }
265
+ return [
266
+ allEnums ? {[ENUM]: enumValues} : {type: getTypeOrTypeUnion(types)},
267
+ defaultValue,
268
+ allowNull || hasNull,
269
+ required,
270
+ ];
152
271
  };
153
272
  const getProperties = (schema) => getDef(schema)?.shape;
154
273
  const createZodSchematizer = () =>
@@ -6,21 +6,31 @@ const NUMBER = getTypeOf(0);
6
6
  const OBJECT = 'object';
7
7
  const ARRAY = 'array';
8
8
  const TYPE = 'type';
9
+ const ENUM = 'enum';
9
10
  const DEFAULT = 'default';
10
11
  const ALLOW_NULL = 'allowNull';
12
+ const NULL = 'null';
11
13
  const REQUIRED = 'required';
14
+ const UNDEFINED = '\uFFFC';
15
+ const JSON_PREFIX = '\uFFFD';
12
16
 
13
17
  const getIfNotFunction = (predicate) => (value, then, otherwise) =>
14
18
  predicate(value)
15
19
  ? /* istanbul ignore next */
16
20
  otherwise?.()
17
21
  : then(value);
22
+ const isFiniteNumber = isFinite;
18
23
  const isNullish = (thing) => thing == null;
19
24
  const isUndefined = (thing) => thing === void 0;
25
+ const isNull = (thing) => thing === null;
20
26
  const ifNotNullish = getIfNotFunction(isNullish);
21
27
  const ifNotUndefined = getIfNotFunction(isUndefined);
28
+ const isTypeStringOrBoolean = (type) => type == STRING || type == BOOLEAN;
29
+ const isString = (thing) => getTypeOf(thing) == STRING;
30
+ const isArray = (thing) => Array.isArray(thing);
22
31
  const size = (thing) => thing.length;
23
32
 
33
+ const arrayEvery = (array, cb) => array.every(cb);
24
34
  const arrayForEach = (array, cb) => array.forEach(cb);
25
35
 
26
36
  const object = Object;
@@ -57,6 +67,33 @@ const objForEach = (obj, cb) =>
57
67
  const objSize = (obj) => size(objIds(obj));
58
68
  const objIsEmpty = (obj) => isObject(obj) && objSize(obj) == 0;
59
69
 
70
+ const getCellOrValueType = (cellOrValue) => {
71
+ if (isNull(cellOrValue)) {
72
+ return NULL;
73
+ }
74
+ if (isArray(cellOrValue)) {
75
+ return ARRAY;
76
+ }
77
+ if (isObject(cellOrValue)) {
78
+ return OBJECT;
79
+ }
80
+ const type = getTypeOf(cellOrValue);
81
+ return isTypeStringOrBoolean(type) ||
82
+ (type == NUMBER && isFiniteNumber(cellOrValue))
83
+ ? type
84
+ : void 0;
85
+ };
86
+ const isJsonType = (type) => type == OBJECT || type == ARRAY;
87
+ const isCellOrValueSchemaType = (type) =>
88
+ isTypeStringOrBoolean(type) || type == NUMBER || isJsonType(type);
89
+ const isCellOrValueSchemaTypes = (types) =>
90
+ isArray(types)
91
+ ? !isUndefined(types[0]) && arrayEvery(types, isCellOrValueSchemaType)
92
+ : isCellOrValueSchemaType(types);
93
+ const isEncodedJson = (value) => isString(value) && value[0] == JSON_PREFIX;
94
+ const isReservedString = (value, encoded = 0) =>
95
+ value === UNDEFINED || (!encoded && isEncodedJson(value));
96
+
60
97
  const createCustomSchematizer = (
61
98
  unwrapSchema,
62
99
  getProperties,
@@ -66,16 +103,27 @@ const createCustomSchematizer = (
66
103
  const [unwrapped, defaultValue, allowNull, unwrappedRequired = required] =
67
104
  unwrapSchema(schema, void 0, void 0, required);
68
105
  const type = unwrapped?.type;
106
+ const enumValues = unwrapped?.[ENUM];
107
+ const isEnum =
108
+ isUndefined(type) &&
109
+ isArray(enumValues) &&
110
+ !isUndefined(enumValues[0]) &&
111
+ arrayEvery(enumValues, (enumValue) => {
112
+ const enumType = getCellOrValueType(enumValue);
113
+ return (
114
+ !isNull(enumValue) &&
115
+ !isUndefined(enumType) &&
116
+ !isJsonType(enumType) &&
117
+ !isReservedString(enumValue)
118
+ );
119
+ });
69
120
  if (
70
- type !== STRING &&
71
- type !== NUMBER &&
72
- type !== BOOLEAN &&
73
- type !== OBJECT &&
74
- type !== ARRAY
121
+ !isEnum &&
122
+ (!isUndefined(enumValues) || !isCellOrValueSchemaTypes(type))
75
123
  ) {
76
124
  return void 0;
77
125
  }
78
- const cellOrValueSchema = {[TYPE]: type};
126
+ const cellOrValueSchema = isEnum ? {[ENUM]: enumValues} : {[TYPE]: type};
79
127
  ifNotUndefined(defaultValue, (defaultValue2) => {
80
128
  cellOrValueSchema[DEFAULT] = defaultValue2;
81
129
  });
package/store/index.js CHANGED
@@ -7,6 +7,7 @@ const FUNCTION = getTypeOf(getTypeOf);
7
7
  const OBJECT = 'object';
8
8
  const ARRAY = 'array';
9
9
  const TYPE = 'type';
10
+ const ENUM = 'enum';
10
11
  const DEFAULT = 'default';
11
12
  const ALLOW_NULL = 'allowNull';
12
13
  const NULL = 'null';
@@ -173,6 +174,14 @@ const getCellOrValueType = (cellOrValue) => {
173
174
  : void 0;
174
175
  };
175
176
  const isJsonType = (type) => type == OBJECT || type == ARRAY;
177
+ const isCellOrValueSchemaType = (type) =>
178
+ isTypeStringOrBoolean(type) || type == NUMBER || isJsonType(type);
179
+ const isCellOrValueSchemaTypes = (types) =>
180
+ isArray(types)
181
+ ? !isUndefined(types[0]) && arrayEvery(types, isCellOrValueSchemaType)
182
+ : isCellOrValueSchemaType(types);
183
+ const cellOrValueSchemaTypeIncludes = (types, type) =>
184
+ isArray(types) ? arrayHas(types, type) : types == type;
176
185
  const encodeIfJson = (value) =>
177
186
  isObject(value) || isArray(value) ? JSON_PREFIX + jsonString(value) : value;
178
187
  const isEncodedJson = (value) => isString(value) && value[0] == JSON_PREFIX;
@@ -560,13 +569,29 @@ const createStore = () => {
560
569
  const validateCellOrValueSchema = (schema) => {
561
570
  if (
562
571
  !objValidate(schema, (_child, id2) =>
563
- arrayHas([TYPE, DEFAULT, ALLOW_NULL, REQUIRED], id2),
572
+ arrayHas([TYPE, ENUM, DEFAULT, ALLOW_NULL, REQUIRED], id2),
564
573
  )
565
574
  ) {
566
575
  return false;
567
576
  }
568
577
  const type = schema[TYPE];
569
- if (!isTypeStringOrBoolean(type) && type != NUMBER && !isJsonType(type)) {
578
+ const enumValues = schema[ENUM];
579
+ if (
580
+ isUndefined(enumValues)
581
+ ? !isCellOrValueSchemaTypes(type)
582
+ : !isUndefined(type) ||
583
+ !isArray(enumValues) ||
584
+ isUndefined(enumValues[0]) ||
585
+ !arrayEvery(enumValues, (enumValue) => {
586
+ const enumType = getCellOrValueType(enumValue);
587
+ return (
588
+ !isNull(enumValue) &&
589
+ !isUndefined(enumType) &&
590
+ !isJsonType(enumType) &&
591
+ !isReservedString(enumValue)
592
+ );
593
+ })
594
+ ) {
570
595
  return false;
571
596
  }
572
597
  const defaultValue = schema[DEFAULT];
@@ -575,7 +600,12 @@ const createStore = () => {
575
600
  }
576
601
  if (!isNull(defaultValue)) {
577
602
  if (
578
- getCellOrValueType(defaultValue) != type ||
603
+ (isUndefined(enumValues)
604
+ ? !cellOrValueSchemaTypeIncludes(
605
+ type,
606
+ getCellOrValueType(defaultValue),
607
+ )
608
+ : !arrayHas(enumValues, defaultValue)) ||
579
609
  isReservedString(defaultValue)
580
610
  ) {
581
611
  objDel(schema, DEFAULT);
@@ -602,13 +632,15 @@ const createStore = () => {
602
632
  isObject(tables) ? objMap(tables, cloneTable) : tables;
603
633
  const cloneValues = (values) =>
604
634
  isObject(values) ? objMap(values, getArg) : values;
605
- const isValidEncodedJson = (cellOrValue, type) =>
635
+ const isValidEncodedJson = (cellOrValue, types) =>
606
636
  acceptingEncodedData == 1 &&
607
637
  isEncodedJson(cellOrValue) &&
608
638
  tryReturn(() => {
609
639
  const encodedType = getCellOrValueType(decodeIfJson(cellOrValue));
610
640
  return (
611
- isJsonType(encodedType) && (isUndefined(type) || type == encodedType)
641
+ isJsonType(encodedType) &&
642
+ (isUndefined(types) ||
643
+ cellOrValueSchemaTypeIncludes(types, encodedType))
612
644
  );
613
645
  }, false) == true;
614
646
  const validateContent = isArray;
@@ -661,7 +693,8 @@ const createStore = () => {
661
693
  : isReservedString(cell, acceptingEncodedData)
662
694
  ? cellInvalid(tableId, rowId, cellId, cell, cellSchema[DEFAULT])
663
695
  : isEncodedJson(cell)
664
- ? isValidEncodedJson(cell, cellSchema[TYPE])
696
+ ? isUndefined(cellSchema[ENUM]) &&
697
+ isValidEncodedJson(cell, cellSchema[TYPE])
665
698
  ? cell
666
699
  : cellInvalid(
667
700
  tableId,
@@ -670,23 +703,36 @@ const createStore = () => {
670
703
  cell,
671
704
  cellSchema[DEFAULT],
672
705
  )
673
- : getCellOrValueType(cell) === cellSchema[TYPE]
674
- ? encodeValid(cell, () =>
675
- cellInvalid(
706
+ : isUndefined(cellSchema[ENUM])
707
+ ? cellOrValueSchemaTypeIncludes(
708
+ cellSchema[TYPE],
709
+ getCellOrValueType(cell),
710
+ )
711
+ ? encodeValid(cell, () =>
712
+ cellInvalid(
713
+ tableId,
714
+ rowId,
715
+ cellId,
716
+ cell,
717
+ cellSchema[DEFAULT],
718
+ ),
719
+ )
720
+ : cellInvalid(
721
+ tableId,
722
+ rowId,
723
+ cellId,
724
+ cell,
725
+ cellSchema[DEFAULT],
726
+ )
727
+ : arrayHas(cellSchema[ENUM], cell)
728
+ ? cell
729
+ : cellInvalid(
676
730
  tableId,
677
731
  rowId,
678
732
  cellId,
679
733
  cell,
680
734
  cellSchema[DEFAULT],
681
735
  ),
682
- )
683
- : cellInvalid(
684
- tableId,
685
- rowId,
686
- cellId,
687
- cell,
688
- cellSchema[DEFAULT],
689
- ),
690
736
  () => cellInvalid(tableId, rowId, cellId, cell),
691
737
  )
692
738
  : isUndefined(getCellOrValueType(cell)) ||
@@ -731,14 +777,22 @@ const createStore = () => {
731
777
  : isReservedString(value, acceptingEncodedData)
732
778
  ? valueInvalid(valueId, value, valueSchema[DEFAULT])
733
779
  : isEncodedJson(value)
734
- ? isValidEncodedJson(value, valueSchema[TYPE])
780
+ ? isUndefined(valueSchema[ENUM]) &&
781
+ isValidEncodedJson(value, valueSchema[TYPE])
735
782
  ? value
736
783
  : valueInvalid(valueId, value, valueSchema[DEFAULT])
737
- : getCellOrValueType(value) === valueSchema[TYPE]
738
- ? encodeValid(value, () =>
739
- valueInvalid(valueId, value, valueSchema[DEFAULT]),
784
+ : isUndefined(valueSchema[ENUM])
785
+ ? cellOrValueSchemaTypeIncludes(
786
+ valueSchema[TYPE],
787
+ getCellOrValueType(value),
740
788
  )
741
- : valueInvalid(valueId, value, valueSchema[DEFAULT]),
789
+ ? encodeValid(value, () =>
790
+ valueInvalid(valueId, value, valueSchema[DEFAULT]),
791
+ )
792
+ : valueInvalid(valueId, value, valueSchema[DEFAULT])
793
+ : arrayHas(valueSchema[ENUM], value)
794
+ ? value
795
+ : valueInvalid(valueId, value, valueSchema[DEFAULT]),
742
796
  () => valueInvalid(valueId, value),
743
797
  )
744
798
  : isUndefined(getCellOrValueType(value)) ||