@dragonmastery/zinia-forms-core 0.3.5 → 0.3.6

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.
package/dist/index.d.ts CHANGED
@@ -116,7 +116,6 @@ interface ArrayFieldProps<FormType, ItemType> {
116
116
  minItems?: number;
117
117
  maxItems?: number;
118
118
  allowReordering?: boolean;
119
- autoPrefixFields?: boolean;
120
119
  ariaLabels?: {
121
120
  addButton?: string;
122
121
  removeButton?: string;
@@ -382,6 +381,14 @@ type FieldPathToEnum<T, P extends Path<T>> = P extends keyof T ? T[P] extends st
382
381
  * ArrayItemType<{tasks: Task[]}, 'tasks'> = Task
383
382
  */
384
383
  type ArrayItemType<T, P extends Path<T>> = P extends keyof T ? T[P] extends ReadonlyArray<infer Item> ? Item : T[P] extends Array<infer Item> ? Item : never : never;
384
+ /**
385
+ * Type-safe fields object that provides autocomplete for field names
386
+ * Maps each key of T to a string (the prefixed field name)
387
+ * All fields return strings regardless of whether the actual field is optional
388
+ */
389
+ type FieldNames<T> = T extends Record<string, any> ? {
390
+ [K in keyof T]-?: string;
391
+ } : Record<string, string>;
385
392
  /**
386
393
  * Type for array field components with properly typed slots
387
394
  */
@@ -389,7 +396,7 @@ type ArrayFieldComponent<T, P extends Path<T>> = vue.FunctionalComponent<Omit<Ar
389
396
  itemRenderer: (props: {
390
397
  item: ArrayItemType<T, P>;
391
398
  index: number;
392
- getFieldName: (fieldPath: string) => string;
399
+ fields: FieldNames<ArrayItemType<T, P>>;
393
400
  }) => any;
394
401
  availableItemRenderer: (props: {
395
402
  item: ArrayItemType<T, P>;
@@ -526,7 +533,7 @@ interface FieldMetadata {
526
533
  */
527
534
  interface SchemaFieldMetadata {
528
535
  /** The input type for rendering the field */
529
- inputType?: 'text' | 'email' | 'tel' | 'number' | 'select' | 'checkbox' | 'radio' | 'textarea' | 'password' | 'currency' | 'date' | 'time' | 'datetime-local' | 'combobox';
536
+ inputType?: 'text' | 'email' | 'tel' | 'number' | 'select' | 'checkbox' | 'radio' | 'textarea' | 'password' | 'currency' | 'date' | 'time' | 'datetime-local' | 'combobox' | 'array';
530
537
  /** Placeholder text for the field */
531
538
  placeholder?: string;
532
539
  /** The display label for the field */
@@ -1117,7 +1124,7 @@ interface StyleCreators {
1117
1124
  itemRenderer: (props: {
1118
1125
  item: ItemType;
1119
1126
  index: number;
1120
- getFieldName: (fieldPath: string) => string;
1127
+ fields: FieldNames<ItemType>;
1121
1128
  }) => any;
1122
1129
  availableItemRenderer: (props: {
1123
1130
  item: ItemType;
@@ -1325,7 +1332,9 @@ declare function useForm<T extends z.ZodObject<any>, CalcType = (values: z.infer
1325
1332
  itemRenderer: (props: {
1326
1333
  item: any;
1327
1334
  index: number;
1328
- getFieldName: (fieldPath: string) => string;
1335
+ fields: Record<string, string> | {
1336
+ [x: string]: string;
1337
+ };
1329
1338
  }) => any;
1330
1339
  availableItemRenderer: (props: {
1331
1340
  item: any;
@@ -1444,7 +1453,7 @@ declare function createTypedArrayField<T, P extends Path<T>>(baseArrayField: Fun
1444
1453
  itemRenderer: (props: {
1445
1454
  item: ArrayItemType<T, P>;
1446
1455
  index: number;
1447
- getFieldName: (fieldPath: string) => string;
1456
+ fields: FieldNames<ArrayItemType<T, P>>;
1448
1457
  }) => any;
1449
1458
  availableItemRenderer: (props: {
1450
1459
  item: ArrayItemType<T, P>;
@@ -1483,7 +1492,9 @@ declare function generateFieldComponents<T extends z.ZodObject<any>>(schema: T,
1483
1492
  itemRenderer: (props: {
1484
1493
  item: any;
1485
1494
  index: number;
1486
- getFieldName: (fieldPath: string) => string;
1495
+ fields: Record<string, string> | {
1496
+ [x: string]: string;
1497
+ };
1487
1498
  }) => any;
1488
1499
  availableItemRenderer: (props: {
1489
1500
  item: any;
package/dist/index.js CHANGED
@@ -277,6 +277,12 @@ function generateFieldComponents(schema, fieldsMetadata, styleName) {
277
277
  fields[typedPath] = dateFieldComponent;
278
278
  components[componentName] = dateFieldComponent;
279
279
  return;
280
+ // Skip the type-based switch below
281
+ case "array":
282
+ const arrayFieldComponent = typedArrayFieldFactory(typedPath, fieldMeta);
283
+ fields[typedPath] = arrayFieldComponent;
284
+ components[componentName] = arrayFieldComponent;
285
+ return;
280
286
  }
281
287
  }
282
288
  switch (fieldMeta.type) {
@@ -515,21 +521,51 @@ var SchemaCache = class {
515
521
  * @returns The field schema or null if not found
516
522
  */
517
523
  getFieldSchema(schema, path, formData) {
524
+ console.log(`[SchemaCache] getFieldSchema called with path: "${path}"`);
518
525
  if (this.cache.has(path)) {
526
+ console.log(`[SchemaCache] Found cached schema for path: "${path}"`);
519
527
  return this.cache.get(path);
520
528
  }
521
529
  const segments = path.split(".");
530
+ console.log(`[SchemaCache] Path segments:`, segments);
522
531
  let currentSchema = schema;
532
+ console.log(`[SchemaCache] Starting schema type:`, currentSchema.constructor.name);
523
533
  for (let i = 0; i < segments.length; i++) {
524
534
  const segment = segments[i];
535
+ console.log(`[SchemaCache] Processing segment [${i}]: "${segment}"`);
536
+ console.log(`[SchemaCache] Current schema type before unwrap:`, currentSchema?.constructor?.name);
525
537
  currentSchema = unwrapSchemaForTraversal(currentSchema);
526
- if (!currentSchema) return null;
538
+ console.log(`[SchemaCache] Current schema type after unwrap:`, currentSchema?.constructor?.name);
539
+ if (!currentSchema) {
540
+ console.log(`[SchemaCache] ERROR: currentSchema is null after unwrap at segment "${segment}"`);
541
+ return null;
542
+ }
527
543
  if (currentSchema instanceof z.ZodObject) {
544
+ console.log(`[SchemaCache] Current schema is ZodObject, accessing shape["${segment}"]`);
545
+ console.log(`[SchemaCache] Available shape keys:`, Object.keys(currentSchema.shape));
528
546
  currentSchema = currentSchema.shape[segment];
547
+ console.log(`[SchemaCache] Got schema from shape, type:`, currentSchema?.constructor?.name);
548
+ if (!currentSchema) {
549
+ console.log(`[SchemaCache] ERROR: No schema found in shape for key "${segment}"`);
550
+ return null;
551
+ }
529
552
  } else if (currentSchema instanceof z.ZodArray) {
530
- currentSchema = currentSchema.element;
531
- if (!isNaN(Number(segment)) && i < segments.length - 1) {
532
- continue;
553
+ console.log(`[SchemaCache] Current schema is ZodArray, segment: "${segment}"`);
554
+ if (!isNaN(Number(segment))) {
555
+ console.log(`[SchemaCache] Segment is numeric (array index), getting element schema`);
556
+ currentSchema = currentSchema._def.type;
557
+ console.log(`[SchemaCache] Element schema type before unwrap:`, currentSchema?.constructor?.name);
558
+ currentSchema = unwrapSchemaForTraversal(currentSchema);
559
+ console.log(`[SchemaCache] Element schema type after unwrap:`, currentSchema?.constructor?.name);
560
+ if (i < segments.length - 1) {
561
+ console.log(`[SchemaCache] More segments remaining, continuing to next segment`);
562
+ continue;
563
+ }
564
+ console.log(`[SchemaCache] Last segment, returning element schema`);
565
+ break;
566
+ } else {
567
+ console.log(`[SchemaCache] ERROR: Segment "${segment}" is not numeric but schema is ZodArray`);
568
+ return null;
533
569
  }
534
570
  } else if (currentSchema instanceof z.ZodDiscriminatedUnion) {
535
571
  const discriminator = currentSchema._def.discriminator;
@@ -588,8 +624,12 @@ var SchemaCache = class {
588
624
  }
589
625
  }
590
626
  currentSchema = unwrapSchemaForTraversal(currentSchema);
627
+ console.log(`[SchemaCache] Final schema type:`, currentSchema?.constructor?.name);
591
628
  if (currentSchema) {
592
629
  this.cache.set(path, currentSchema);
630
+ console.log(`[SchemaCache] \u2705 Successfully found and cached schema for path: "${path}"`);
631
+ } else {
632
+ console.log(`[SchemaCache] \u274C ERROR: Final schema is null for path: "${path}"`);
593
633
  }
594
634
  return currentSchema;
595
635
  }
@@ -603,16 +643,21 @@ var SchemaCache = class {
603
643
 
604
644
  // src/validation/fieldValidation.ts
605
645
  function validateField(schema, formData, path, schemaCache) {
646
+ console.log(`[validateField] Validating path: "${path}"`);
606
647
  const cache = schemaCache || new SchemaCache();
607
648
  const fieldSchema = cache.getFieldSchema(schema, path, formData);
608
649
  if (!fieldSchema) {
650
+ console.log(`[validateField] \u274C ERROR: Invalid field path "${path}" - schema not found`);
609
651
  return {
610
652
  success: false,
611
653
  error: "Invalid field path"
612
654
  };
613
655
  }
656
+ console.log(`[validateField] Found schema for path "${path}", type:`, fieldSchema.constructor.name);
614
657
  const value = getValueByPath(formData, path);
658
+ console.log(`[validateField] Value at path "${path}":`, value);
615
659
  const result = fieldSchema.safeParse(value);
660
+ console.log(`[validateField] Validation result for "${path}":`, result.success ? "\u2705 SUCCESS" : "\u274C FAILED", result.success ? "" : result.error.errors[0]?.message);
616
661
  if (result.success) {
617
662
  return {
618
663
  success: true
@@ -3567,10 +3612,14 @@ function createDaisyUIArrayField() {
3567
3612
  const fieldMetadata = formState.fieldsMetadata[props.name] || {};
3568
3613
  const arrayValue = formState.getValue(props.name) || [];
3569
3614
  const getFieldName = (fieldPath, index) => {
3570
- if (props.autoPrefixFields) {
3571
- return `${props.name}.${index}.${fieldPath}`;
3572
- }
3573
- return fieldPath;
3615
+ return `${props.name}.${index}.${fieldPath}`;
3616
+ };
3617
+ const generateFieldsProxy = (index) => {
3618
+ return new Proxy({}, {
3619
+ get: (_target, prop) => {
3620
+ return getFieldName(prop, index);
3621
+ }
3622
+ });
3574
3623
  };
3575
3624
  const instance = getCurrentInstance();
3576
3625
  const addItem = (item) => {
@@ -3713,7 +3762,8 @@ function createDaisyUIArrayField() {
3713
3762
  /* @__PURE__ */ jsx("div", { class: "flex-1", children: slots.itemRenderer?.({
3714
3763
  item,
3715
3764
  index,
3716
- getFieldName: (fieldPath) => getFieldName(fieldPath, index)
3765
+ // Type-safe fields object with autocomplete
3766
+ fields: generateFieldsProxy(index)
3717
3767
  }) || (props.itemRenderer ? props.itemRenderer(item, index) : JSON.stringify(item)) }),
3718
3768
  /* @__PURE__ */ jsxs("div", { class: "flex items-center space-x-1 ml-2", children: [
3719
3769
  props.allowReordering && /* @__PURE__ */ jsxs("div", { class: "flex space-x-1", children: [
@@ -3805,7 +3855,6 @@ function createDaisyUIArrayField() {
3805
3855
  "minItems",
3806
3856
  "maxItems",
3807
3857
  "allowReordering",
3808
- "autoPrefixFields",
3809
3858
  "ariaLabels"
3810
3859
  ];
3811
3860
  return DaisyUIArrayField;
@@ -5564,6 +5613,7 @@ function createDaisyUITextareaField() {
5564
5613
  }
5565
5614
  function createDaisyUITextField() {
5566
5615
  const DaisyUITextField = (props, { attrs }) => {
5616
+ console.log(`[TextField] Rendering with name prop: "${props.name}"`);
5567
5617
  const formState = inject(ZINIA_FORM_KEY);
5568
5618
  if (!formState) {
5569
5619
  console.error("TextField: formState is required but was not injected");