@effect-app/vue-components 0.0.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 (35) hide show
  1. package/README.md +184 -0
  2. package/dist/types/components/OmegaForm/OmegaErrors.vue.d.ts +2 -0
  3. package/dist/types/components/OmegaForm/OmegaErrorsContext.d.ts +35 -0
  4. package/dist/types/components/OmegaForm/OmegaFormStuff.d.ts +85 -0
  5. package/dist/types/components/OmegaForm/OmegaInput.vue.d.ts +38 -0
  6. package/dist/types/components/OmegaForm/OmegaInternalInput.vue.d.ts +25 -0
  7. package/dist/types/components/OmegaForm/OmegaWrapper.vue.d.ts +43 -0
  8. package/dist/types/components/OmegaForm/getOmegaStore.d.ts +3 -0
  9. package/dist/types/components/OmegaForm/index.d.ts +52 -0
  10. package/dist/types/components/OmegaForm/useOmegaForm.d.ts +6 -0
  11. package/dist/types/components/TestComponent.vue.d.ts +6 -0
  12. package/dist/types/components/index.d.ts +3 -0
  13. package/dist/types/constants/index.d.ts +1 -0
  14. package/dist/types/index.d.ts +9 -0
  15. package/dist/types/utils/index.d.ts +7 -0
  16. package/dist/vue-components.css +1 -0
  17. package/dist/vue-components.es.js +624 -0
  18. package/package.json +48 -0
  19. package/src/assets/.keep +0 -0
  20. package/src/components/OmegaForm/OmegaErrors.vue +143 -0
  21. package/src/components/OmegaForm/OmegaErrorsContext.ts +64 -0
  22. package/src/components/OmegaForm/OmegaFormStuff.ts +575 -0
  23. package/src/components/OmegaForm/OmegaInput.vue +91 -0
  24. package/src/components/OmegaForm/OmegaInternalInput.vue +216 -0
  25. package/src/components/OmegaForm/OmegaWrapper.vue +137 -0
  26. package/src/components/OmegaForm/getOmegaStore.ts +32 -0
  27. package/src/components/OmegaForm/index.ts +29 -0
  28. package/src/components/OmegaForm/useOmegaForm.ts +61 -0
  29. package/src/components/TestComponent.vue +15 -0
  30. package/src/components/index.ts +6 -0
  31. package/src/components/style.css +3 -0
  32. package/src/constants/index.ts +1 -0
  33. package/src/env.d.ts +8 -0
  34. package/src/index.ts +17 -0
  35. package/src/utils/index.ts +12 -0
@@ -0,0 +1,575 @@
1
+ import { pipe, S, Option, type Record, type Effect } from "effect-app"
2
+ /* eslint-disable @typescript-eslint/no-explicit-any */
3
+ import {
4
+ type FormAsyncValidateOrFn,
5
+ type FormValidateOrFn,
6
+ type StandardSchemaV1,
7
+ type FormApi,
8
+ type VueFormApi,
9
+ type FieldComponent,
10
+ type FormOptions,
11
+ type DeepKeys,
12
+ type FieldValidateOrFn,
13
+ type FieldAsyncValidateOrFn,
14
+ type FormState,
15
+ } from "@tanstack/vue-form"
16
+ import type { Component } from "vue"
17
+ import { useIntl } from "../../utils"
18
+
19
+ export type TypeOverride =
20
+ | "string"
21
+ | "number"
22
+ | "select"
23
+ | "multiple"
24
+ | "boolean"
25
+
26
+ export interface OmegaError {
27
+ label: string
28
+ inputId: string
29
+ errors: readonly string[]
30
+ }
31
+
32
+ const isArrayOfString = S.NonEmptyArray(S.String)
33
+
34
+ export type FormProps<To, From> = Omit<
35
+ FormOptions<
36
+ To,
37
+ FormValidateOrFn<To> | undefined,
38
+ FormValidateOrFn<To> | undefined,
39
+ StandardSchemaV1<To, From>,
40
+ FormValidateOrFn<To> | undefined,
41
+ FormAsyncValidateOrFn<To> | undefined,
42
+ FormValidateOrFn<To> | undefined,
43
+ FormAsyncValidateOrFn<To> | undefined,
44
+ FormAsyncValidateOrFn<To> | undefined,
45
+ FormAsyncValidateOrFn<To> | undefined
46
+ >,
47
+ "onSubmit"
48
+ > & {
49
+ onSubmit?: (props: {
50
+ formApi: OmegaFormParams<To, From>
51
+ meta: any
52
+ value: From
53
+ }) => Promise<any> | any
54
+ }
55
+
56
+ export type OmegaFormParams<To, From> = FormApi<
57
+ To,
58
+ FormValidateOrFn<To> | undefined,
59
+ FormValidateOrFn<To> | undefined,
60
+ StandardSchemaV1<To, From>,
61
+ FormValidateOrFn<To> | undefined,
62
+ FormAsyncValidateOrFn<To> | undefined,
63
+ FormValidateOrFn<To> | undefined,
64
+ FormAsyncValidateOrFn<To> | undefined,
65
+ FormAsyncValidateOrFn<To> | undefined,
66
+ FormAsyncValidateOrFn<To> | undefined
67
+ >
68
+
69
+ export type OmegaFormState<To, From> = FormState<
70
+ To,
71
+ FormValidateOrFn<To> | undefined,
72
+ FormValidateOrFn<To> | undefined,
73
+ StandardSchemaV1<To, From>,
74
+ FormValidateOrFn<To> | undefined,
75
+ FormAsyncValidateOrFn<To> | undefined,
76
+ FormValidateOrFn<To> | undefined,
77
+ FormAsyncValidateOrFn<To> | undefined,
78
+ FormAsyncValidateOrFn<To> | undefined
79
+ >
80
+
81
+ export type OmegaFormApi<To, From> = OmegaFormParams<To, From> &
82
+ VueFormApi<
83
+ To,
84
+ FormValidateOrFn<To> | undefined,
85
+ FormValidateOrFn<To> | undefined,
86
+ StandardSchemaV1<To, From>,
87
+ FormValidateOrFn<To> | undefined,
88
+ FormAsyncValidateOrFn<To> | undefined,
89
+ FormValidateOrFn<To> | undefined,
90
+ FormAsyncValidateOrFn<To> | undefined,
91
+ FormAsyncValidateOrFn<To> | undefined,
92
+ FormAsyncValidateOrFn<To> | undefined
93
+ >
94
+
95
+ export type FormComponent<T, S> = FieldComponent<
96
+ T,
97
+ FormValidateOrFn<T> | undefined,
98
+ FormValidateOrFn<T> | undefined,
99
+ StandardSchemaV1<T, S>,
100
+ FormValidateOrFn<T> | undefined,
101
+ FormAsyncValidateOrFn<T> | undefined,
102
+ FormValidateOrFn<T> | undefined,
103
+ FormAsyncValidateOrFn<T> | undefined,
104
+ FormAsyncValidateOrFn<T> | undefined,
105
+ FormAsyncValidateOrFn<T> | undefined
106
+ > &
107
+ Component
108
+
109
+ export type FormType<T, S> = OmegaFormApi<T, S> & {
110
+ Field: Component
111
+ }
112
+
113
+ export type PrefixFromDepth<
114
+ K extends string | number,
115
+ _TDepth extends any[],
116
+ > = K
117
+
118
+ export type PrefixObjectAccessor<
119
+ T extends object,
120
+ TDepth extends any[] = [],
121
+ > = {
122
+ [K in keyof T]-?: K extends string | number
123
+ ?
124
+ | PrefixFromDepth<K, TDepth>
125
+ | `${PrefixFromDepth<K, TDepth>}${DeepKeys<T[K], [TDepth]>}`
126
+ : never
127
+ }[keyof T]
128
+
129
+ export type NestedKeyOf<T> = T extends object ? PrefixObjectAccessor<T> : never
130
+
131
+ export type FieldValidators<T> = {
132
+ onChangeAsync?: FieldAsyncValidateOrFn<T, any, any>
133
+ onChange?: FieldValidateOrFn<T, any, any>
134
+ onBlur?: FieldValidateOrFn<T, any, any>
135
+ onBlurAsync?: FieldAsyncValidateOrFn<T, any, any>
136
+ }
137
+
138
+ // Field metadata type definitions
139
+ export type BaseFieldMeta = {
140
+ required: boolean
141
+ nullableOrUndefined?: false | "undefined" | "null"
142
+ }
143
+
144
+ export type StringFieldMeta = BaseFieldMeta & {
145
+ type: "string"
146
+ maxLength?: number
147
+ minLength?: number
148
+ format?: string
149
+ }
150
+
151
+ export type NumberFieldMeta = BaseFieldMeta & {
152
+ type: "number"
153
+ minimum?: number
154
+ maximum?: number
155
+ exclusiveMinimum?: number
156
+ exclusiveMaximum?: number
157
+ }
158
+
159
+ export type SelectFieldMeta = BaseFieldMeta & {
160
+ type: "select"
161
+ members: any[]
162
+ }
163
+
164
+ export type MultipleFieldMeta = BaseFieldMeta & {
165
+ type: "multiple"
166
+ members: any[]
167
+ }
168
+
169
+ export type BooleanFieldMeta = BaseFieldMeta & {
170
+ type: "boolean"
171
+ }
172
+
173
+ export type UnknownFieldMeta = BaseFieldMeta & {
174
+ type: "unknown"
175
+ }
176
+
177
+ export type FieldMeta =
178
+ | StringFieldMeta
179
+ | NumberFieldMeta
180
+ | SelectFieldMeta
181
+ | MultipleFieldMeta
182
+ | BooleanFieldMeta
183
+ | UnknownFieldMeta
184
+
185
+ export type MetaRecord<T = string> = {
186
+ [K in NestedKeyOf<T>]?: FieldMeta
187
+ }
188
+
189
+ export type FilterItems = {
190
+ items: readonly [string, ...string[]]
191
+ message:
192
+ | string
193
+ | Effect.Effect<string, never, never>
194
+ | { readonly message: string | Effect.Effect<string> }
195
+ }
196
+
197
+ type CreateMeta = {
198
+ parent?: string
199
+ meta?: Record<string, any>
200
+ nullableOrUndefined?: false | "undefined" | "null"
201
+ } & (
202
+ | {
203
+ propertySignatures: readonly S.AST.PropertySignature[]
204
+ property?: never
205
+ }
206
+ | {
207
+ propertySignatures?: never
208
+ property: S.AST.AST
209
+ }
210
+ )
211
+
212
+ const getNullableOrUndefined = (property: S.AST.AST) => {
213
+ return (
214
+ S.AST.isUnion(property) &&
215
+ property.types.find(_ => _._tag === "UndefinedKeyword" || _ === S.Null.ast)
216
+ )
217
+ }
218
+
219
+ const isNullableOrUndefined = (property: false | S.AST.AST | undefined) => {
220
+ if (!property || !S.AST.isUnion(property)) return false
221
+ if (property.types.find(_ => _._tag === "UndefinedKeyword"))
222
+ return "undefined"
223
+ if (property.types.find(_ => _ === S.Null.ast)) return "null"
224
+ return false
225
+ }
226
+
227
+ const createMeta = <T = any>(
228
+ { meta = {}, parent = "", property, propertySignatures }: CreateMeta,
229
+ acc: Partial<MetaRecord<T>> = {},
230
+ ): MetaRecord<T> | FieldMeta => {
231
+ if (property && property._tag === "Transformation") {
232
+ return createMeta<T>({
233
+ parent,
234
+ meta,
235
+ property: property.from,
236
+ })
237
+ }
238
+
239
+ if (property?._tag === "TypeLiteral" && "propertySignatures" in property) {
240
+ return createMeta<T>({
241
+ meta,
242
+ propertySignatures: property.propertySignatures,
243
+ })
244
+ }
245
+
246
+ if (propertySignatures) {
247
+ for (const p of propertySignatures) {
248
+ const key = parent ? `${parent}.${p.name.toString()}` : p.name.toString()
249
+ const nullableOrUndefined = isNullableOrUndefined(p.type)
250
+ const isRequired = meta["required"] ?? !nullableOrUndefined
251
+
252
+ let typeToProcess = p.type
253
+ if (S.AST.isUnion(p.type)) {
254
+ typeToProcess = p.type.types.find(
255
+ t => t._tag !== "UndefinedKeyword" && t !== S.Null.ast,
256
+ )!
257
+ }
258
+
259
+ if ("propertySignatures" in typeToProcess) {
260
+ Object.assign(
261
+ acc,
262
+ createMeta<T>({
263
+ parent: key,
264
+ propertySignatures: typeToProcess.propertySignatures,
265
+ meta: { required: isRequired, nullableOrUndefined },
266
+ }),
267
+ )
268
+ } else {
269
+ const newMeta = createMeta<T>({
270
+ parent: key,
271
+ property: p.type,
272
+ meta: { required: isRequired, nullableOrUndefined },
273
+ })
274
+ acc[key as NestedKeyOf<T>] = newMeta as FieldMeta
275
+ }
276
+ }
277
+ return acc
278
+ }
279
+
280
+ if (property) {
281
+ const nullableOrUndefined = getNullableOrUndefined(property)
282
+
283
+ if (!Object.hasOwnProperty.call(meta, "required")) {
284
+ meta["required"] = !nullableOrUndefined
285
+ }
286
+
287
+ if (S.AST.isUnion(property)) {
288
+ const nonNullType = property.types.find(
289
+ t => t._tag !== "UndefinedKeyword" && t !== S.Null.ast,
290
+ )!
291
+
292
+ if ("propertySignatures" in nonNullType) {
293
+ return createMeta<T>({
294
+ propertySignatures: nonNullType.propertySignatures,
295
+ parent,
296
+ meta,
297
+ })
298
+ }
299
+
300
+ if (property.types.every(S.AST.isLiteral)) {
301
+ return {
302
+ ...meta,
303
+ type: "select",
304
+ members: property.types.map(t => t.literal),
305
+ } as FieldMeta
306
+ }
307
+
308
+ return {
309
+ ...meta,
310
+ ...createMeta<T>({
311
+ parent,
312
+ meta,
313
+ property: nonNullType,
314
+ }),
315
+ } as FieldMeta
316
+ }
317
+
318
+ if (S.AST.isTupleType(property)) {
319
+ return {
320
+ ...meta,
321
+ type: "multiple",
322
+ members: property.elements,
323
+ } as FieldMeta
324
+ }
325
+
326
+ const JSONAnnotation = S.AST.getAnnotation(
327
+ property,
328
+ S.AST.JSONSchemaAnnotationId,
329
+ ).pipe(Option.getOrElse(() => ({}))) as Record<string, unknown>
330
+
331
+ meta = { ...meta, ...JSONAnnotation }
332
+
333
+ if ("from" in property) {
334
+ return createMeta<T>({
335
+ parent,
336
+ meta,
337
+ property: property.from,
338
+ })
339
+ } else {
340
+ meta["type"] = S.AST.getAnnotation(
341
+ property,
342
+ S.AST.TitleAnnotationId,
343
+ ).pipe(
344
+ Option.getOrElse(() => {
345
+ return "unknown"
346
+ }),
347
+ )
348
+ }
349
+
350
+ return meta as FieldMeta
351
+ }
352
+
353
+ return acc
354
+ }
355
+
356
+ const flattenMeta = <From, To>(
357
+ schema: S.Schema<From, To, never>,
358
+ ): MetaRecord<To> => {
359
+ const ast = schema.ast
360
+ const result: MetaRecord<To> = {}
361
+
362
+ if (ast._tag === "Transformation" || ast._tag === "Refinement") {
363
+ return flattenMeta(S.make(ast.from))
364
+ }
365
+
366
+ if ("propertySignatures" in ast) {
367
+ const meta = createMeta<To>({
368
+ propertySignatures: ast.propertySignatures,
369
+ })
370
+
371
+ if (Object.values(meta).every(value => value && "type" in value)) {
372
+ return meta as MetaRecord<To>
373
+ }
374
+
375
+ const flattenObject = (
376
+ obj: Record<string, any>,
377
+ parentKey: string = "",
378
+ ) => {
379
+ for (const key in obj) {
380
+ const newKey = parentKey ? `${parentKey}.${key}` : key
381
+ if (obj[key] && typeof obj[key] === "object" && "type" in obj[key]) {
382
+ result[newKey as NestedKeyOf<To>] = obj[key] as FieldMeta
383
+ } else if (obj[key] && typeof obj[key] === "object") {
384
+ flattenObject(obj[key], newKey)
385
+ }
386
+ }
387
+ }
388
+
389
+ flattenObject(meta)
390
+ }
391
+
392
+ return result
393
+ }
394
+
395
+ export const duplicateSchema = <From, To>(
396
+ schema: S.Schema<From, To, never>,
397
+ ) => {
398
+ return S.extend(schema, S.Struct({}))
399
+ }
400
+
401
+ export const generateMetaFromSchema = <From, To>(
402
+ schema: S.Schema<From, To, never>,
403
+ ): {
404
+ schema: S.Schema<From, To, never>
405
+ meta: MetaRecord<To>
406
+ filterItems?: FilterItems
407
+ } => {
408
+ const meta = flattenMeta(schema)
409
+
410
+ const filterItems = pipe(
411
+ schema.ast,
412
+ Option.liftPredicate(s => s._tag === "Refinement" && "filter" in s),
413
+ Option.flatMap(s => S.AST.getJSONSchemaAnnotation(s)),
414
+ Option.filter(s => "items" in s),
415
+ Option.filterMap(({ items }) =>
416
+ S.decodeUnknownOption(isArrayOfString)(items),
417
+ ),
418
+ Option.zipWith(
419
+ S.AST.getMessageAnnotation(schema.ast),
420
+ (items, message) => ({
421
+ items,
422
+ message: message("" as unknown as S.ParseResult.ParseIssue),
423
+ }),
424
+ ),
425
+ Option.getOrUndefined,
426
+ )
427
+ return { schema, meta, filterItems }
428
+ }
429
+
430
+ export const generateInputStandardSchemaFromFieldMeta = (
431
+ meta: FieldMeta,
432
+ ): StandardSchemaV1<any, any> => {
433
+ const { trans } = useIntl()
434
+ let schema: S.Schema<any, any, never>
435
+ switch (meta.type) {
436
+ case "string":
437
+ schema = S.String.annotations({
438
+ message: () => trans("validation.empty"),
439
+ })
440
+
441
+ if (meta.format === "email") {
442
+ schema = S.compose(
443
+ schema,
444
+ S.Email.annotations({
445
+ message: () => trans("validation.email.invalid"),
446
+ }),
447
+ )
448
+ }
449
+
450
+ if (meta.required) {
451
+ schema.annotations({
452
+ message: () => trans("validation.empty"),
453
+ })
454
+ }
455
+
456
+ if (meta.maxLength) {
457
+ schema = schema.pipe(S.maxLength(meta.maxLength)).annotations({
458
+ message: () =>
459
+ trans("validation.string.maxLength", {
460
+ maxLength: meta.maxLength,
461
+ }),
462
+ })
463
+ }
464
+ if (meta.minLength) {
465
+ schema = schema.pipe(S.minLength(meta.minLength)).annotations({
466
+ message: () =>
467
+ trans("validation.string.minLength", {
468
+ minLength: meta.minLength,
469
+ }),
470
+ })
471
+ }
472
+ break
473
+
474
+ case "number":
475
+ schema = S.Number.annotations({
476
+ message: () => trans("validation.empty"),
477
+ })
478
+
479
+ if (meta.required) {
480
+ schema.annotations({
481
+ message: () => trans("validation.empty"),
482
+ })
483
+ }
484
+ if (meta.minimum) {
485
+ schema = schema.pipe(S.greaterThanOrEqualTo(meta.minimum)).annotations({
486
+ message: () =>
487
+ trans("validation.number.min", {
488
+ minimum: meta.minimum,
489
+ isExclusive: true,
490
+ }),
491
+ })
492
+ }
493
+ if (meta.maximum) {
494
+ schema = schema.pipe(S.lessThanOrEqualTo(meta.maximum)).annotations({
495
+ message: () =>
496
+ trans("validation.number.max", {
497
+ maximum: meta.maximum,
498
+ isExclusive: true,
499
+ }),
500
+ })
501
+ }
502
+ if (meta.exclusiveMinimum) {
503
+ schema = schema.pipe(S.greaterThan(meta.exclusiveMinimum)).annotations({
504
+ message: () =>
505
+ trans("validation.number.min", {
506
+ minimum: meta.exclusiveMinimum,
507
+ isExclusive: false,
508
+ }),
509
+ })
510
+ }
511
+ if (meta.exclusiveMaximum) {
512
+ schema = schema.pipe(S.lessThan(meta.exclusiveMaximum)).annotations({
513
+ message: () =>
514
+ trans("validation.number.max", {
515
+ maximum: meta.exclusiveMaximum,
516
+ isExclusive: false,
517
+ }),
518
+ })
519
+ }
520
+ break
521
+ case "select":
522
+ schema = S.Literal(...meta.members).annotations({
523
+ message: () => ({
524
+ message: trans("validation.not_a_valid", {
525
+ type: "select",
526
+ message: meta.members.join(", "),
527
+ }),
528
+ override: true,
529
+ }),
530
+ })
531
+
532
+ break
533
+
534
+ case "multiple":
535
+ schema = S.Array(S.String).annotations({
536
+ message: () =>
537
+ trans("validation.not_a_valid", {
538
+ type: "multiple",
539
+ message: meta.members.join(", "),
540
+ }),
541
+ })
542
+ break
543
+
544
+ case "boolean":
545
+ schema = S.Boolean
546
+ break
547
+ // todo: switch must be exhaustive or have default case, otherwise falls through with schema undefined.
548
+
549
+ case "unknown":
550
+ schema = S.Unknown
551
+ break
552
+ }
553
+ if (!meta.required) {
554
+ schema = S.NullishOr(schema)
555
+ } else {
556
+ schema.pipe(
557
+ S.annotations({
558
+ message: () => trans("validation.empty"),
559
+ }),
560
+ )
561
+ }
562
+ const result = S.standardSchemaV1(schema)
563
+ return result
564
+ }
565
+
566
+ export const nullableInput = <A, I, R>(
567
+ schema: S.Schema<A, I, R>,
568
+ defaultValue: () => A,
569
+ ) =>
570
+ S.NullOr(schema).pipe(
571
+ S.transform(S.typeSchema(schema), {
572
+ decode: input => input ?? defaultValue(),
573
+ encode: input => input,
574
+ }),
575
+ )
@@ -0,0 +1,91 @@
1
+ <template>
2
+ <component
3
+ :is="form.Field"
4
+ :name="name"
5
+ :validators="{
6
+ onChange: schema,
7
+ ...validators,
8
+ }"
9
+ >
10
+ <template
11
+ #default="{
12
+ field,
13
+ }: {
14
+ // TODO: exact type
15
+ field: FieldApi<
16
+ any,
17
+ any,
18
+ any,
19
+ any,
20
+ any,
21
+ any,
22
+ any,
23
+ any,
24
+ any,
25
+ any,
26
+ any,
27
+ any,
28
+ any,
29
+ any,
30
+ any,
31
+ any,
32
+ any,
33
+ any,
34
+ any
35
+ >
36
+ }"
37
+ >
38
+ <slot
39
+ :field="field"
40
+ :label="label"
41
+ :options="options"
42
+ :meta="meta"
43
+ :type="type"
44
+ >
45
+ <OmegaInternalInput
46
+ :field="field"
47
+ :label="label"
48
+ :options="options"
49
+ :meta="meta"
50
+ :type="type"
51
+ />
52
+ </slot>
53
+ </template>
54
+ </component>
55
+ </template>
56
+
57
+ <script setup lang="ts" generic="From, To">
58
+ import { computed } from "vue"
59
+ import {
60
+ generateInputStandardSchemaFromFieldMeta,
61
+ type FieldValidators,
62
+ type FormType,
63
+ type MetaRecord,
64
+ type NestedKeyOf,
65
+ type TypeOverride,
66
+ } from "./OmegaFormStuff"
67
+ import OmegaInternalInput from "./OmegaInternalInput.vue"
68
+ import type { FieldApi } from "@tanstack/vue-form"
69
+
70
+ const props = defineProps<{
71
+ form: FormType<From, To> & {
72
+ meta: MetaRecord<To>
73
+ }
74
+ name: NestedKeyOf<To>
75
+ validators?: FieldValidators<From>
76
+ label: string
77
+ options?: { title: string; value: string }[]
78
+ type?: TypeOverride
79
+ }>()
80
+
81
+ const meta = computed(() => {
82
+ return props.form.meta[props.name]
83
+ })
84
+
85
+ const schema = computed(() => {
86
+ if (!meta.value) {
87
+ throw new Error("Meta is undefined")
88
+ }
89
+ return generateInputStandardSchemaFromFieldMeta(meta.value)
90
+ })
91
+ </script>