@ram_28/kf-ai-sdk 2.0.17 → 2.0.19

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/dist/{FileField-BWrSHNRq.js → FileField-CZjS2uLh.js} +3 -3
  2. package/dist/{FileField-eDeuzln8.cjs → FileField-DU4UWo_t.cjs} +1 -1
  3. package/dist/auth/authClient.d.ts.map +1 -1
  4. package/dist/auth.cjs +1 -1
  5. package/dist/auth.mjs +101 -105
  6. package/dist/bdo/core/Item.d.ts +0 -4
  7. package/dist/bdo/core/Item.d.ts.map +1 -1
  8. package/dist/bdo/fields/ReferenceField.d.ts +1 -1
  9. package/dist/bdo/fields/ReferenceField.d.ts.map +1 -1
  10. package/dist/bdo/fields/SelectField.d.ts +1 -1
  11. package/dist/bdo/fields/SelectField.d.ts.map +1 -1
  12. package/dist/bdo/fields/UserField.d.ts +1 -1
  13. package/dist/bdo/fields/UserField.d.ts.map +1 -1
  14. package/dist/bdo.cjs +1 -1
  15. package/dist/bdo.mjs +52 -61
  16. package/dist/components/hooks/useBDOForm/createItemProxy.d.ts +2 -3
  17. package/dist/components/hooks/useBDOForm/createItemProxy.d.ts.map +1 -1
  18. package/dist/form.cjs +1 -1
  19. package/dist/form.mjs +226 -243
  20. package/dist/workflow.cjs +1 -1
  21. package/dist/workflow.mjs +1 -1
  22. package/docs/README.md +6 -0
  23. package/docs/examples/fields/complex-fields.md +248 -0
  24. package/docs/examples/fields/primitive-fields.md +217 -0
  25. package/docs/fields/README.md +141 -0
  26. package/docs/fields/api_reference.md +134 -0
  27. package/docs/useActivityForm/README.md +4 -1
  28. package/docs/useBDOForm/README.md +4 -1
  29. package/package.json +1 -1
  30. package/sdk/auth/authClient.ts +15 -21
  31. package/sdk/bdo/core/Item.ts +1 -10
  32. package/sdk/bdo/fields/ReferenceField.ts +1 -1
  33. package/sdk/bdo/fields/SelectField.ts +1 -1
  34. package/sdk/bdo/fields/UserField.ts +1 -1
  35. package/sdk/components/hooks/useBDOForm/createItemProxy.ts +17 -58
@@ -21,9 +21,8 @@ import type {
21
21
  * Key principle: Item has NO state. It's a view over RHF's state.
22
22
  * Editable fields get set(), readonly fields do not.
23
23
  *
24
- * Draft-based upload: In create mode (no _id), upload() automatically creates
25
- * a draft record via draftInteraction() to get an _id, then uploads immediately.
26
- * On form submit, if a draft _id exists, update() is used instead of create().
24
+ * In create mode (no _id), attachment and fetch operations use 'draft' as the
25
+ * instanceId, which the backend accepts as a placeholder.
27
26
  *
28
27
  * @param bdo - The BDO instance for field metadata
29
28
  * @param form - The RHF useForm return object
@@ -36,34 +35,11 @@ export function createItemProxy<B extends BaseBdo<any, any, any>>(
36
35
  const fields = bdo.getFields();
37
36
  const accessorCache = new Map<string, EditableFormFieldAccessorType<unknown> | ReadonlyFormFieldAccessorType<unknown>>();
38
37
 
39
- // Draft tracking for create mode — shared across all attachment fields in this form
40
38
  const boIdShared = bdo.getBoId();
41
- let draftId: string | null = null;
42
- let draftPromise: Promise<string> | null = null;
43
-
44
- /**
45
- * Ensures a record _id exists for attachment uploads.
46
- * In edit mode, returns the existing _id.
47
- * In create mode, creates a draft record via draftInteraction() to get an _id.
48
- * The draft _id is shared across all attachment fields and only created once.
49
- */
50
- async function ensureDraft(): Promise<string> {
51
- // If form already has an _id (edit mode or previous draft), use it
52
- const existing = form.getValues("_id" as Path<FieldValues>) as string | undefined;
53
- if (existing) return existing;
54
- if (draftId) return draftId;
55
- if (!draftPromise) {
56
- draftPromise = api(boIdShared).draftInteraction({}).then((d: any) => {
57
- draftId = d._id;
58
- form.setValue("_id" as Path<FieldValues>, draftId as any, { shouldDirty: false });
59
- return draftId!;
60
- }).catch((err: Error) => {
61
- draftPromise = null;
62
- throw err;
63
- });
64
- }
65
- return draftPromise;
66
- }
39
+
40
+ /** Returns the real _id in edit mode, or 'draft' in create mode */
41
+ const getInstanceId = (): string =>
42
+ (form.getValues("_id" as Path<FieldValues>) as string) || "draft";
67
43
 
68
44
  return new Proxy({} as FormItemType<ExtractEditableType<B>, ExtractReadonlyType<B>>, {
69
45
  get(_, prop: string | symbol) {
@@ -87,11 +63,6 @@ export function createItemProxy<B extends BaseBdo<any, any, any>>(
87
63
  return () => form.trigger();
88
64
  }
89
65
 
90
- // Internal: check if a draft was created (used by handleSubmit)
91
- if (prop === "_hasDraft") {
92
- return () => !!draftId;
93
- }
94
-
95
66
  // Return cached accessor if available
96
67
  if (accessorCache.has(prop)) {
97
68
  return accessorCache.get(prop);
@@ -182,17 +153,12 @@ export function createItemProxy<B extends BaseBdo<any, any, any>>(
182
153
  // Enrich Image/File field accessors with attachment methods (draft-based upload)
183
154
  if (fieldMeta.Type === "Image" || fieldMeta.Type === "File") {
184
155
  const boId = boIdShared;
185
- const requireInstanceId = (): string => {
186
- const id = form.getValues("_id" as Path<FieldValues>) as string | undefined;
187
- if (!id) throw new Error("Save the record before attachment operations");
188
- return id;
189
- };
190
156
 
191
157
  if (fieldMeta.Type === "Image") {
192
158
  // Image: single file upload — always uploads immediately (draft in create mode)
193
159
  (accessor as any).upload = async (file: File): Promise<FileType> => {
194
160
  validateFileExtension(file.name, "Image");
195
- const id = await ensureDraft();
161
+ const id = getInstanceId();
196
162
 
197
163
  const [uploadInfo] = await api(boId).getUploadUrl(id, prop, [
198
164
  { FileName: file.name, Size: file.size, FileExtension: extractFileExtension(file.name) },
@@ -216,7 +182,7 @@ export function createItemProxy<B extends BaseBdo<any, any, any>>(
216
182
 
217
183
  (accessor as any).deleteAttachment = async (): Promise<void> => {
218
184
  const val = form.getValues(prop as Path<FieldValues>) as any;
219
- const instanceId = requireInstanceId();
185
+ const instanceId = getInstanceId();
220
186
  if (!(val?._id)) throw new Error(`${prop} has no image to delete`);
221
187
  await api(boId).deleteAttachment(instanceId, prop, val._id);
222
188
  form.setValue(prop as Path<FieldValues>, null as any, { shouldDirty: true });
@@ -224,7 +190,7 @@ export function createItemProxy<B extends BaseBdo<any, any, any>>(
224
190
 
225
191
  (accessor as any).getDownloadUrl = async (viewType?: AttachmentViewType): Promise<FileDownloadResponseType> => {
226
192
  const val = form.getValues(prop as Path<FieldValues>) as any;
227
- const instanceId = requireInstanceId();
193
+ const instanceId = getInstanceId();
228
194
  if (!(val?._id)) throw new Error(`${prop} has no image`);
229
195
  return api(boId).getDownloadUrl(instanceId, prop, val._id, viewType);
230
196
  };
@@ -232,7 +198,7 @@ export function createItemProxy<B extends BaseBdo<any, any, any>>(
232
198
  // File field — multi-file, always uploads immediately (draft in create mode)
233
199
  (accessor as any).upload = async (files: File[]): Promise<FileType[]> => {
234
200
  for (const file of files) validateFileExtension(file.name, "File");
235
- const id = await ensureDraft();
201
+ const id = getInstanceId();
236
202
 
237
203
  const requests = files.map((file) => ({
238
204
  FileName: file.name,
@@ -264,7 +230,7 @@ export function createItemProxy<B extends BaseBdo<any, any, any>>(
264
230
 
265
231
  (accessor as any).deleteAttachment = async (attachmentId: string): Promise<void> => {
266
232
  const current = (form.getValues(prop as Path<FieldValues>) as any[]) ?? [];
267
- const instanceId = requireInstanceId();
233
+ const instanceId = getInstanceId();
268
234
  await api(boId).deleteAttachment(instanceId, prop, attachmentId);
269
235
  form.setValue(
270
236
  prop as Path<FieldValues>,
@@ -277,13 +243,13 @@ export function createItemProxy<B extends BaseBdo<any, any, any>>(
277
243
  attachmentId: string,
278
244
  viewType?: AttachmentViewType,
279
245
  ): Promise<FileDownloadResponseType> => {
280
- const instanceId = requireInstanceId();
246
+ const instanceId = getInstanceId();
281
247
  return api(boId).getDownloadUrl(instanceId, prop, attachmentId, viewType);
282
248
  };
283
249
  (accessor as any).getDownloadUrls = async (
284
250
  viewType?: AttachmentViewType,
285
251
  ): Promise<FileDownloadResponseType[]> => {
286
- const instanceId = requireInstanceId();
252
+ const instanceId = getInstanceId();
287
253
  return api(boId).getDownloadUrls(instanceId, prop, viewType);
288
254
  };
289
255
  }
@@ -314,16 +280,11 @@ export function createItemProxy<B extends BaseBdo<any, any, any>>(
314
280
  // Enrich readonly Image/File field accessors with download methods
315
281
  if (fieldMeta.Type === "Image" || fieldMeta.Type === "File") {
316
282
  const boId = boIdShared;
317
- const requireInstanceId = (): string => {
318
- const id = form.getValues("_id" as Path<FieldValues>) as string | undefined;
319
- if (!id) throw new Error("Cannot perform attachment operation: item has no _id. Save the item first.");
320
- return id;
321
- };
322
283
 
323
284
  if (fieldMeta.Type === "Image") {
324
285
  (accessor as any).getDownloadUrl = async (viewType?: AttachmentViewType): Promise<FileDownloadResponseType> => {
325
286
  const val = form.getValues(prop as Path<FieldValues>) as any;
326
- const instanceId = requireInstanceId();
287
+ const instanceId = getInstanceId();
327
288
  if (!(val?._id)) throw new Error(`${prop} has no image to download`);
328
289
  return api(boId).getDownloadUrl(instanceId, prop, val._id, viewType);
329
290
  };
@@ -332,13 +293,13 @@ export function createItemProxy<B extends BaseBdo<any, any, any>>(
332
293
  attachmentId: string,
333
294
  viewType?: AttachmentViewType,
334
295
  ): Promise<FileDownloadResponseType> => {
335
- const instanceId = requireInstanceId();
296
+ const instanceId = getInstanceId();
336
297
  return api(boId).getDownloadUrl(instanceId, prop, attachmentId, viewType);
337
298
  };
338
299
  (accessor as any).getDownloadUrls = async (
339
300
  viewType?: AttachmentViewType,
340
301
  ): Promise<FileDownloadResponseType[]> => {
341
- const instanceId = requireInstanceId();
302
+ const instanceId = getInstanceId();
342
303
  return api(boId).getDownloadUrls(instanceId, prop, viewType);
343
304
  };
344
305
  }
@@ -352,8 +313,6 @@ export function createItemProxy<B extends BaseBdo<any, any, any>>(
352
313
  if (typeof prop === "symbol") return false;
353
314
  if (prop === "_id" || prop === "toJSON" || prop === "validate")
354
315
  return true;
355
- if (prop === "_hasDraft")
356
- return true;
357
316
  return prop in fields;
358
317
  },
359
318
 
@@ -365,7 +324,7 @@ export function createItemProxy<B extends BaseBdo<any, any, any>>(
365
324
  if (typeof prop === "symbol") return undefined;
366
325
  return {
367
326
  configurable: true,
368
- enumerable: prop !== "toJSON" && prop !== "validate" && prop !== "_hasDraft",
327
+ enumerable: prop !== "toJSON" && prop !== "validate",
369
328
  };
370
329
  },
371
330
  });