@usertour/helpers 0.0.48 → 0.0.50

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.
@@ -277,6 +277,7 @@ var duplicateChecklistData = (data) => {
277
277
  const checklistData = data;
278
278
  return {
279
279
  ...checklistData,
280
+ content: processQuestionElements(checklistData.content),
280
281
  items: checklistData.items.map((item) => ({
281
282
  ...item,
282
283
  id: uuidV4(),
@@ -286,6 +287,23 @@ var duplicateChecklistData = (data) => {
286
287
  }))
287
288
  };
288
289
  };
290
+ var duplicateLauncherData = (data) => {
291
+ if (!data || !isObject(data)) {
292
+ return data;
293
+ }
294
+ const launcherData = data;
295
+ return {
296
+ ...launcherData,
297
+ behavior: launcherData.behavior ? {
298
+ ...launcherData.behavior,
299
+ actions: isArray(launcherData.behavior.actions) ? regenerateConditionIds(launcherData.behavior.actions) : launcherData.behavior.actions
300
+ } : launcherData.behavior,
301
+ tooltip: launcherData.tooltip ? {
302
+ ...launcherData.tooltip,
303
+ content: processQuestionElements(launcherData.tooltip.content)
304
+ } : launcherData.tooltip
305
+ };
306
+ };
289
307
  var duplicateConfig = (config) => {
290
308
  if (!config) {
291
309
  return config;
@@ -300,20 +318,27 @@ var duplicateData = (data, contentType) => {
300
318
  if (contentType === import_types3.ContentDataType.CHECKLIST) {
301
319
  return duplicateChecklistData(data);
302
320
  }
321
+ if (contentType === import_types3.ContentDataType.LAUNCHER) {
322
+ return duplicateLauncherData(data);
323
+ }
303
324
  return data;
304
325
  };
305
- var createStepCopy = (originalStep, sequence, existingStepNames) => {
306
- const { id, cvid, updatedAt, createdAt, ...rest } = originalStep;
307
- const name = generateUniqueCopyName(originalStep == null ? void 0 : originalStep.name, existingStepNames);
308
- const trigger = (originalStep == null ? void 0 : originalStep.trigger) ? duplicateTriggers(originalStep == null ? void 0 : originalStep.trigger) : [];
309
- const data = (originalStep == null ? void 0 : originalStep.data) ? processQuestionElements(originalStep == null ? void 0 : originalStep.data) : [];
310
- const target = duplicateTarget(originalStep == null ? void 0 : originalStep.target);
326
+ var duplicateStep = (step, options) => {
327
+ var _a;
328
+ const { id, cvid, createdAt, updatedAt, versionId, trigger, target, data, ...rest } = step;
329
+ const preserveUndefined = (_a = options == null ? void 0 : options.preserveUndefined) != null ? _a : false;
311
330
  return {
312
331
  ...rest,
313
- data,
314
- trigger,
315
- target,
316
- name,
332
+ data: data ? processQuestionElements(data) : preserveUndefined ? data : [],
333
+ trigger: trigger ? duplicateTriggers(trigger) : preserveUndefined ? trigger : [],
334
+ target: duplicateTarget(target)
335
+ };
336
+ };
337
+ var duplicateStepWithRename = (originalStep, sequence, existingStepNames) => {
338
+ const duplicated = duplicateStep(originalStep);
339
+ return {
340
+ ...duplicated,
341
+ name: generateUniqueCopyName(originalStep.name, existingStepNames),
317
342
  sequence
318
343
  };
319
344
  };
@@ -910,8 +935,8 @@ describe("duplicateData", () => {
910
935
  expect(result).toEqual(data);
911
936
  });
912
937
  });
913
- describe("createStepCopy", () => {
914
- test("should create a copy of the step with new name", () => {
938
+ describe("duplicateStepWithRename", () => {
939
+ test("should duplicate the step with new name", () => {
915
940
  const originalStep = {
916
941
  id: "step-1",
917
942
  cvid: "cvid-1",
@@ -923,7 +948,7 @@ describe("createStepCopy", () => {
923
948
  createdAt: /* @__PURE__ */ new Date(),
924
949
  updatedAt: /* @__PURE__ */ new Date()
925
950
  };
926
- const result = createStepCopy(originalStep, 1);
951
+ const result = duplicateStepWithRename(originalStep, 1);
927
952
  expect(result.name).toBe("Original Step (copy)");
928
953
  expect(result.sequence).toBe(1);
929
954
  expect(result).not.toHaveProperty("id");
@@ -941,10 +966,10 @@ describe("createStepCopy", () => {
941
966
  data: [],
942
967
  target: void 0
943
968
  };
944
- const result = createStepCopy(originalStep, 1, ["Step (copy)"]);
969
+ const result = duplicateStepWithRename(originalStep, 1, ["Step (copy)"]);
945
970
  expect(result.name).toBe("Step (copy 2)");
946
971
  });
947
- test("should process triggers in step copy", () => {
972
+ test("should process triggers in step duplicate", () => {
948
973
  var _a;
949
974
  const originalStep = {
950
975
  id: "step-1",
@@ -961,10 +986,10 @@ describe("createStepCopy", () => {
961
986
  data: [],
962
987
  target: void 0
963
988
  };
964
- const result = createStepCopy(originalStep, 1);
989
+ const result = duplicateStepWithRename(originalStep, 1);
965
990
  expect((_a = result.trigger) == null ? void 0 : _a[0].id).toBe("mock-cuid");
966
991
  });
967
- test("should process target in step copy", () => {
992
+ test("should process target in step duplicate", () => {
968
993
  var _a, _b;
969
994
  const originalStep = {
970
995
  id: "step-1",
@@ -977,7 +1002,7 @@ describe("createStepCopy", () => {
977
1002
  actions: [{ id: "action-1", type: "test", operators: "and", data: {} }]
978
1003
  }
979
1004
  };
980
- const result = createStepCopy(originalStep, 1);
1005
+ const result = duplicateStepWithRename(originalStep, 1);
981
1006
  expect((_b = (_a = result.target) == null ? void 0 : _a.actions) == null ? void 0 : _b[0].id).toBe("regenerated-action-1");
982
1007
  });
983
1008
  test("should handle step without trigger", () => {
@@ -990,7 +1015,7 @@ describe("createStepCopy", () => {
990
1015
  data: [],
991
1016
  target: void 0
992
1017
  };
993
- const result = createStepCopy(originalStep, 1);
1018
+ const result = duplicateStepWithRename(originalStep, 1);
994
1019
  expect(result.trigger).toEqual([]);
995
1020
  });
996
1021
  test("should handle step without data", () => {
@@ -1003,7 +1028,7 @@ describe("createStepCopy", () => {
1003
1028
  data: void 0,
1004
1029
  target: void 0
1005
1030
  };
1006
- const result = createStepCopy(originalStep, 1);
1031
+ const result = duplicateStepWithRename(originalStep, 1);
1007
1032
  expect(result.data).toEqual([]);
1008
1033
  });
1009
1034
  });
@@ -1,8 +1,8 @@
1
1
  import {
2
- createStepCopy,
3
2
  duplicateChecklistData,
4
3
  duplicateConfig,
5
4
  duplicateData,
5
+ duplicateStepWithRename,
6
6
  duplicateTarget,
7
7
  duplicateTriggers,
8
8
  extractQuestionData,
@@ -13,7 +13,7 @@ import {
13
13
  isQuestionElement,
14
14
  isRestrictedType,
15
15
  processQuestionElements
16
- } from "../chunk-7GJAPR7Y.js";
16
+ } from "../chunk-JTRQ5CEL.js";
17
17
  import "../chunk-7ODE2AIC.js";
18
18
  import "../chunk-SIG4WTEF.js";
19
19
  import "../chunk-YYIGUZNZ.js";
@@ -617,8 +617,8 @@ describe("duplicateData", () => {
617
617
  expect(result).toEqual(data);
618
618
  });
619
619
  });
620
- describe("createStepCopy", () => {
621
- test("should create a copy of the step with new name", () => {
620
+ describe("duplicateStepWithRename", () => {
621
+ test("should duplicate the step with new name", () => {
622
622
  const originalStep = {
623
623
  id: "step-1",
624
624
  cvid: "cvid-1",
@@ -630,7 +630,7 @@ describe("createStepCopy", () => {
630
630
  createdAt: /* @__PURE__ */ new Date(),
631
631
  updatedAt: /* @__PURE__ */ new Date()
632
632
  };
633
- const result = createStepCopy(originalStep, 1);
633
+ const result = duplicateStepWithRename(originalStep, 1);
634
634
  expect(result.name).toBe("Original Step (copy)");
635
635
  expect(result.sequence).toBe(1);
636
636
  expect(result).not.toHaveProperty("id");
@@ -648,10 +648,10 @@ describe("createStepCopy", () => {
648
648
  data: [],
649
649
  target: void 0
650
650
  };
651
- const result = createStepCopy(originalStep, 1, ["Step (copy)"]);
651
+ const result = duplicateStepWithRename(originalStep, 1, ["Step (copy)"]);
652
652
  expect(result.name).toBe("Step (copy 2)");
653
653
  });
654
- test("should process triggers in step copy", () => {
654
+ test("should process triggers in step duplicate", () => {
655
655
  var _a;
656
656
  const originalStep = {
657
657
  id: "step-1",
@@ -668,10 +668,10 @@ describe("createStepCopy", () => {
668
668
  data: [],
669
669
  target: void 0
670
670
  };
671
- const result = createStepCopy(originalStep, 1);
671
+ const result = duplicateStepWithRename(originalStep, 1);
672
672
  expect((_a = result.trigger) == null ? void 0 : _a[0].id).toBe("mock-cuid");
673
673
  });
674
- test("should process target in step copy", () => {
674
+ test("should process target in step duplicate", () => {
675
675
  var _a, _b;
676
676
  const originalStep = {
677
677
  id: "step-1",
@@ -684,7 +684,7 @@ describe("createStepCopy", () => {
684
684
  actions: [{ id: "action-1", type: "test", operators: "and", data: {} }]
685
685
  }
686
686
  };
687
- const result = createStepCopy(originalStep, 1);
687
+ const result = duplicateStepWithRename(originalStep, 1);
688
688
  expect((_b = (_a = result.target) == null ? void 0 : _a.actions) == null ? void 0 : _b[0].id).toBe("regenerated-action-1");
689
689
  });
690
690
  test("should handle step without trigger", () => {
@@ -697,7 +697,7 @@ describe("createStepCopy", () => {
697
697
  data: [],
698
698
  target: void 0
699
699
  };
700
- const result = createStepCopy(originalStep, 1);
700
+ const result = duplicateStepWithRename(originalStep, 1);
701
701
  expect(result.trigger).toEqual([]);
702
702
  });
703
703
  test("should handle step without data", () => {
@@ -710,7 +710,7 @@ describe("createStepCopy", () => {
710
710
  data: void 0,
711
711
  target: void 0
712
712
  };
713
- const result = createStepCopy(originalStep, 1);
713
+ const result = duplicateStepWithRename(originalStep, 1);
714
714
  expect(result.data).toEqual([]);
715
715
  });
716
716
  });
@@ -159,6 +159,7 @@ var duplicateChecklistData = (data) => {
159
159
  const checklistData = data;
160
160
  return {
161
161
  ...checklistData,
162
+ content: processQuestionElements(checklistData.content),
162
163
  items: checklistData.items.map((item) => ({
163
164
  ...item,
164
165
  id: uuidV4(),
@@ -168,6 +169,23 @@ var duplicateChecklistData = (data) => {
168
169
  }))
169
170
  };
170
171
  };
172
+ var duplicateLauncherData = (data) => {
173
+ if (!data || !isObject(data)) {
174
+ return data;
175
+ }
176
+ const launcherData = data;
177
+ return {
178
+ ...launcherData,
179
+ behavior: launcherData.behavior ? {
180
+ ...launcherData.behavior,
181
+ actions: isArray(launcherData.behavior.actions) ? regenerateConditionIds(launcherData.behavior.actions) : launcherData.behavior.actions
182
+ } : launcherData.behavior,
183
+ tooltip: launcherData.tooltip ? {
184
+ ...launcherData.tooltip,
185
+ content: processQuestionElements(launcherData.tooltip.content)
186
+ } : launcherData.tooltip
187
+ };
188
+ };
171
189
  var duplicateConfig = (config) => {
172
190
  if (!config) {
173
191
  return config;
@@ -182,20 +200,33 @@ var duplicateData = (data, contentType) => {
182
200
  if (contentType === ContentDataType.CHECKLIST) {
183
201
  return duplicateChecklistData(data);
184
202
  }
203
+ if (contentType === ContentDataType.LAUNCHER) {
204
+ return duplicateLauncherData(data);
205
+ }
185
206
  return data;
186
207
  };
187
- var createStepCopy = (originalStep, sequence, existingStepNames) => {
188
- const { id, cvid, updatedAt, createdAt, ...rest } = originalStep;
189
- const name = generateUniqueCopyName(originalStep == null ? void 0 : originalStep.name, existingStepNames);
190
- const trigger = (originalStep == null ? void 0 : originalStep.trigger) ? duplicateTriggers(originalStep == null ? void 0 : originalStep.trigger) : [];
191
- const data = (originalStep == null ? void 0 : originalStep.data) ? processQuestionElements(originalStep == null ? void 0 : originalStep.data) : [];
192
- const target = duplicateTarget(originalStep == null ? void 0 : originalStep.target);
208
+ var duplicateStep = (step, options) => {
209
+ var _a;
210
+ const { id, cvid, createdAt, updatedAt, versionId, trigger, target, data, ...rest } = step;
211
+ const preserveUndefined = (_a = options == null ? void 0 : options.preserveUndefined) != null ? _a : false;
193
212
  return {
194
213
  ...rest,
195
- data,
196
- trigger,
197
- target,
198
- name,
214
+ data: data ? processQuestionElements(data) : preserveUndefined ? data : [],
215
+ trigger: trigger ? duplicateTriggers(trigger) : preserveUndefined ? trigger : [],
216
+ target: duplicateTarget(target)
217
+ };
218
+ };
219
+ var duplicateSteps = (steps) => {
220
+ if (!isArray(steps)) {
221
+ return [];
222
+ }
223
+ return steps.map((step) => duplicateStep(step, { preserveUndefined: true }));
224
+ };
225
+ var duplicateStepWithRename = (originalStep, sequence, existingStepNames) => {
226
+ const duplicated = duplicateStep(originalStep);
227
+ return {
228
+ ...duplicated,
229
+ name: generateUniqueCopyName(originalStep.name, existingStepNames),
199
230
  sequence
200
231
  };
201
232
  };
@@ -212,7 +243,10 @@ export {
212
243
  duplicateTriggers,
213
244
  duplicateTarget,
214
245
  duplicateChecklistData,
246
+ duplicateLauncherData,
215
247
  duplicateConfig,
216
248
  duplicateData,
217
- createStepCopy
249
+ duplicateStep,
250
+ duplicateSteps,
251
+ duplicateStepWithRename
218
252
  };
@@ -30,10 +30,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/content-helper.ts
31
31
  var content_helper_exports = {};
32
32
  __export(content_helper_exports, {
33
- createStepCopy: () => createStepCopy,
34
33
  duplicateChecklistData: () => duplicateChecklistData,
35
34
  duplicateConfig: () => duplicateConfig,
36
35
  duplicateData: () => duplicateData,
36
+ duplicateLauncherData: () => duplicateLauncherData,
37
+ duplicateStep: () => duplicateStep,
38
+ duplicateStepWithRename: () => duplicateStepWithRename,
39
+ duplicateSteps: () => duplicateSteps,
37
40
  duplicateTarget: () => duplicateTarget,
38
41
  duplicateTriggers: () => duplicateTriggers,
39
42
  extractQuestionData: () => extractQuestionData,
@@ -297,6 +300,7 @@ var duplicateChecklistData = (data) => {
297
300
  const checklistData = data;
298
301
  return {
299
302
  ...checklistData,
303
+ content: processQuestionElements(checklistData.content),
300
304
  items: checklistData.items.map((item) => ({
301
305
  ...item,
302
306
  id: uuidV4(),
@@ -306,6 +310,23 @@ var duplicateChecklistData = (data) => {
306
310
  }))
307
311
  };
308
312
  };
313
+ var duplicateLauncherData = (data) => {
314
+ if (!data || !isObject(data)) {
315
+ return data;
316
+ }
317
+ const launcherData = data;
318
+ return {
319
+ ...launcherData,
320
+ behavior: launcherData.behavior ? {
321
+ ...launcherData.behavior,
322
+ actions: isArray(launcherData.behavior.actions) ? regenerateConditionIds(launcherData.behavior.actions) : launcherData.behavior.actions
323
+ } : launcherData.behavior,
324
+ tooltip: launcherData.tooltip ? {
325
+ ...launcherData.tooltip,
326
+ content: processQuestionElements(launcherData.tooltip.content)
327
+ } : launcherData.tooltip
328
+ };
329
+ };
309
330
  var duplicateConfig = (config) => {
310
331
  if (!config) {
311
332
  return config;
@@ -320,29 +341,45 @@ var duplicateData = (data, contentType) => {
320
341
  if (contentType === import_types3.ContentDataType.CHECKLIST) {
321
342
  return duplicateChecklistData(data);
322
343
  }
344
+ if (contentType === import_types3.ContentDataType.LAUNCHER) {
345
+ return duplicateLauncherData(data);
346
+ }
323
347
  return data;
324
348
  };
325
- var createStepCopy = (originalStep, sequence, existingStepNames) => {
326
- const { id, cvid, updatedAt, createdAt, ...rest } = originalStep;
327
- const name = generateUniqueCopyName(originalStep == null ? void 0 : originalStep.name, existingStepNames);
328
- const trigger = (originalStep == null ? void 0 : originalStep.trigger) ? duplicateTriggers(originalStep == null ? void 0 : originalStep.trigger) : [];
329
- const data = (originalStep == null ? void 0 : originalStep.data) ? processQuestionElements(originalStep == null ? void 0 : originalStep.data) : [];
330
- const target = duplicateTarget(originalStep == null ? void 0 : originalStep.target);
349
+ var duplicateStep = (step, options) => {
350
+ var _a;
351
+ const { id, cvid, createdAt, updatedAt, versionId, trigger, target, data, ...rest } = step;
352
+ const preserveUndefined = (_a = options == null ? void 0 : options.preserveUndefined) != null ? _a : false;
331
353
  return {
332
354
  ...rest,
333
- data,
334
- trigger,
335
- target,
336
- name,
355
+ data: data ? processQuestionElements(data) : preserveUndefined ? data : [],
356
+ trigger: trigger ? duplicateTriggers(trigger) : preserveUndefined ? trigger : [],
357
+ target: duplicateTarget(target)
358
+ };
359
+ };
360
+ var duplicateSteps = (steps) => {
361
+ if (!isArray(steps)) {
362
+ return [];
363
+ }
364
+ return steps.map((step) => duplicateStep(step, { preserveUndefined: true }));
365
+ };
366
+ var duplicateStepWithRename = (originalStep, sequence, existingStepNames) => {
367
+ const duplicated = duplicateStep(originalStep);
368
+ return {
369
+ ...duplicated,
370
+ name: generateUniqueCopyName(originalStep.name, existingStepNames),
337
371
  sequence
338
372
  };
339
373
  };
340
374
  // Annotate the CommonJS export names for ESM import in node:
341
375
  0 && (module.exports = {
342
- createStepCopy,
343
376
  duplicateChecklistData,
344
377
  duplicateConfig,
345
378
  duplicateData,
379
+ duplicateLauncherData,
380
+ duplicateStep,
381
+ duplicateStepWithRename,
382
+ duplicateSteps,
346
383
  duplicateTarget,
347
384
  duplicateTriggers,
348
385
  extractQuestionData,
@@ -35,10 +35,18 @@ declare const duplicateTarget: (target: Step['target']) => Step['target'];
35
35
  /**
36
36
  * Process ChecklistData to regenerate condition IDs in RulesCondition[] fields
37
37
  * Handles clickedActions, completeConditions, and onlyShowTaskConditions for each item
38
+ * Also processes content field using processQuestionElements
38
39
  * @param data - The checklist data to process
39
40
  * @returns Processed checklist data with regenerated condition IDs
40
41
  */
41
42
  declare const duplicateChecklistData: (data: unknown) => unknown;
43
+ /**
44
+ * Process LauncherData to regenerate condition IDs in behavior.actions
45
+ * Also processes tooltip.content using processQuestionElements
46
+ * @param data - The launcher data to process
47
+ * @returns Processed launcher data with regenerated condition IDs
48
+ */
49
+ declare const duplicateLauncherData: (data: unknown) => unknown;
42
50
  /**
43
51
  * Process version config to regenerate condition IDs in autoStartRules and hideRules
44
52
  * @param config - The content config object to process
@@ -48,10 +56,52 @@ declare const duplicateConfig: (config: ContentConfigObject) => ContentConfigObj
48
56
  /**
49
57
  * Process version data based on content type to regenerate condition IDs
50
58
  * @param data - The version data to process
51
- * @param contentType - The type of content (checklist, flow, etc.)
59
+ * @param contentType - The type of content (checklist, launcher, flow, etc.)
52
60
  * @returns Processed data with regenerated condition IDs
53
61
  */
54
62
  declare const duplicateData: (data: unknown, contentType: string) => unknown;
55
- declare const createStepCopy: (originalStep: Step, sequence: number, existingStepNames?: string[]) => Step;
63
+ /**
64
+ * Step-like type that works with both Prisma Step and @usertour/types Step
65
+ * This allows the function to be used in both server and client contexts
66
+ * Uses unknown for data/trigger to accept Prisma's JsonValue type
67
+ */
68
+ type StepLike = {
69
+ id?: string;
70
+ cvid?: string;
71
+ createdAt?: string | Date;
72
+ updatedAt?: string | Date;
73
+ versionId?: string;
74
+ data?: unknown;
75
+ trigger?: unknown;
76
+ target?: unknown;
77
+ [key: string]: unknown;
78
+ };
79
+ /**
80
+ * Core function to duplicate a single step by removing database-specific fields
81
+ * and regenerating IDs in triggers, target actions, and question elements
82
+ * @param step - The step to duplicate
83
+ * @param options - Options for duplication behavior
84
+ * @param options.preserveUndefined - If true, undefined data/trigger remain undefined; if false (default), they become empty arrays
85
+ * @returns A new step object with regenerated IDs, without id/cvid/timestamps/versionId
86
+ */
87
+ declare const duplicateStep: <T extends StepLike>(step: T, options?: {
88
+ preserveUndefined?: boolean;
89
+ }) => Omit<T, "id" | "cvid" | "createdAt" | "updatedAt" | "versionId">;
90
+ /**
91
+ * Process multiple steps for duplication
92
+ * Works with both Prisma Step type (server) and @usertour/types Step (client)
93
+ * @param steps - Array of steps to process
94
+ * @returns Array of steps ready for creation with regenerated IDs
95
+ */
96
+ declare const duplicateSteps: <T extends StepLike>(steps: T[]) => Omit<T, "id" | "cvid" | "createdAt" | "updatedAt" | "versionId">[];
97
+ /**
98
+ * Duplicate a single step with a new unique name and sequence
99
+ * Used for UI operations when duplicating a step within the same version
100
+ * @param originalStep - The step to duplicate
101
+ * @param sequence - The new sequence number for the duplicated step
102
+ * @param existingStepNames - Optional array of existing step names to avoid conflicts
103
+ * @returns A new step object ready for creation
104
+ */
105
+ declare const duplicateStepWithRename: (originalStep: Step, sequence: number, existingStepNames?: string[]) => Omit<Step, 'id' | 'cvid' | 'updatedAt' | 'createdAt'>;
56
106
 
57
- export { createStepCopy, duplicateChecklistData, duplicateConfig, duplicateData, duplicateTarget, duplicateTriggers, extractQuestionData, generateUniqueCopyName, hasMissingRequiredData, isClickableElement, isMissingRequiredData, isQuestionElement, isRestrictedType, processQuestionElements };
107
+ export { duplicateChecklistData, duplicateConfig, duplicateData, duplicateLauncherData, duplicateStep, duplicateStepWithRename, duplicateSteps, duplicateTarget, duplicateTriggers, extractQuestionData, generateUniqueCopyName, hasMissingRequiredData, isClickableElement, isMissingRequiredData, isQuestionElement, isRestrictedType, processQuestionElements };
@@ -35,10 +35,18 @@ declare const duplicateTarget: (target: Step['target']) => Step['target'];
35
35
  /**
36
36
  * Process ChecklistData to regenerate condition IDs in RulesCondition[] fields
37
37
  * Handles clickedActions, completeConditions, and onlyShowTaskConditions for each item
38
+ * Also processes content field using processQuestionElements
38
39
  * @param data - The checklist data to process
39
40
  * @returns Processed checklist data with regenerated condition IDs
40
41
  */
41
42
  declare const duplicateChecklistData: (data: unknown) => unknown;
43
+ /**
44
+ * Process LauncherData to regenerate condition IDs in behavior.actions
45
+ * Also processes tooltip.content using processQuestionElements
46
+ * @param data - The launcher data to process
47
+ * @returns Processed launcher data with regenerated condition IDs
48
+ */
49
+ declare const duplicateLauncherData: (data: unknown) => unknown;
42
50
  /**
43
51
  * Process version config to regenerate condition IDs in autoStartRules and hideRules
44
52
  * @param config - The content config object to process
@@ -48,10 +56,52 @@ declare const duplicateConfig: (config: ContentConfigObject) => ContentConfigObj
48
56
  /**
49
57
  * Process version data based on content type to regenerate condition IDs
50
58
  * @param data - The version data to process
51
- * @param contentType - The type of content (checklist, flow, etc.)
59
+ * @param contentType - The type of content (checklist, launcher, flow, etc.)
52
60
  * @returns Processed data with regenerated condition IDs
53
61
  */
54
62
  declare const duplicateData: (data: unknown, contentType: string) => unknown;
55
- declare const createStepCopy: (originalStep: Step, sequence: number, existingStepNames?: string[]) => Step;
63
+ /**
64
+ * Step-like type that works with both Prisma Step and @usertour/types Step
65
+ * This allows the function to be used in both server and client contexts
66
+ * Uses unknown for data/trigger to accept Prisma's JsonValue type
67
+ */
68
+ type StepLike = {
69
+ id?: string;
70
+ cvid?: string;
71
+ createdAt?: string | Date;
72
+ updatedAt?: string | Date;
73
+ versionId?: string;
74
+ data?: unknown;
75
+ trigger?: unknown;
76
+ target?: unknown;
77
+ [key: string]: unknown;
78
+ };
79
+ /**
80
+ * Core function to duplicate a single step by removing database-specific fields
81
+ * and regenerating IDs in triggers, target actions, and question elements
82
+ * @param step - The step to duplicate
83
+ * @param options - Options for duplication behavior
84
+ * @param options.preserveUndefined - If true, undefined data/trigger remain undefined; if false (default), they become empty arrays
85
+ * @returns A new step object with regenerated IDs, without id/cvid/timestamps/versionId
86
+ */
87
+ declare const duplicateStep: <T extends StepLike>(step: T, options?: {
88
+ preserveUndefined?: boolean;
89
+ }) => Omit<T, "id" | "cvid" | "createdAt" | "updatedAt" | "versionId">;
90
+ /**
91
+ * Process multiple steps for duplication
92
+ * Works with both Prisma Step type (server) and @usertour/types Step (client)
93
+ * @param steps - Array of steps to process
94
+ * @returns Array of steps ready for creation with regenerated IDs
95
+ */
96
+ declare const duplicateSteps: <T extends StepLike>(steps: T[]) => Omit<T, "id" | "cvid" | "createdAt" | "updatedAt" | "versionId">[];
97
+ /**
98
+ * Duplicate a single step with a new unique name and sequence
99
+ * Used for UI operations when duplicating a step within the same version
100
+ * @param originalStep - The step to duplicate
101
+ * @param sequence - The new sequence number for the duplicated step
102
+ * @param existingStepNames - Optional array of existing step names to avoid conflicts
103
+ * @returns A new step object ready for creation
104
+ */
105
+ declare const duplicateStepWithRename: (originalStep: Step, sequence: number, existingStepNames?: string[]) => Omit<Step, 'id' | 'cvid' | 'updatedAt' | 'createdAt'>;
56
106
 
57
- export { createStepCopy, duplicateChecklistData, duplicateConfig, duplicateData, duplicateTarget, duplicateTriggers, extractQuestionData, generateUniqueCopyName, hasMissingRequiredData, isClickableElement, isMissingRequiredData, isQuestionElement, isRestrictedType, processQuestionElements };
107
+ export { duplicateChecklistData, duplicateConfig, duplicateData, duplicateLauncherData, duplicateStep, duplicateStepWithRename, duplicateSteps, duplicateTarget, duplicateTriggers, extractQuestionData, generateUniqueCopyName, hasMissingRequiredData, isClickableElement, isMissingRequiredData, isQuestionElement, isRestrictedType, processQuestionElements };
@@ -1,8 +1,11 @@
1
1
  import {
2
- createStepCopy,
3
2
  duplicateChecklistData,
4
3
  duplicateConfig,
5
4
  duplicateData,
5
+ duplicateLauncherData,
6
+ duplicateStep,
7
+ duplicateStepWithRename,
8
+ duplicateSteps,
6
9
  duplicateTarget,
7
10
  duplicateTriggers,
8
11
  extractQuestionData,
@@ -13,7 +16,7 @@ import {
13
16
  isQuestionElement,
14
17
  isRestrictedType,
15
18
  processQuestionElements
16
- } from "./chunk-7GJAPR7Y.js";
19
+ } from "./chunk-JTRQ5CEL.js";
17
20
  import "./chunk-7ODE2AIC.js";
18
21
  import "./chunk-SIG4WTEF.js";
19
22
  import "./chunk-YYIGUZNZ.js";
@@ -24,10 +27,13 @@ import "./chunk-JQWKLXW6.js";
24
27
  import "./chunk-GFH3VWOC.js";
25
28
  import "./chunk-XEO3YXBM.js";
26
29
  export {
27
- createStepCopy,
28
30
  duplicateChecklistData,
29
31
  duplicateConfig,
30
32
  duplicateData,
33
+ duplicateLauncherData,
34
+ duplicateStep,
35
+ duplicateStepWithRename,
36
+ duplicateSteps,
31
37
  duplicateTarget,
32
38
  duplicateTriggers,
33
39
  extractQuestionData,
package/dist/index.cjs CHANGED
@@ -49,7 +49,6 @@ __export(src_exports, {
49
49
  convertSettings: () => convertSettings,
50
50
  convertTimeConditionLegacyToV2: () => convertTimeConditionLegacyToV2,
51
51
  convertToCssVars: () => convertToCssVars,
52
- createStepCopy: () => createStepCopy,
53
52
  cuid: () => cuid,
54
53
  deepClone: () => deepClone,
55
54
  defaultContentConfig: () => defaultContentConfig,
@@ -58,6 +57,10 @@ __export(src_exports, {
58
57
  duplicateChecklistData: () => duplicateChecklistData,
59
58
  duplicateConfig: () => duplicateConfig,
60
59
  duplicateData: () => duplicateData,
60
+ duplicateLauncherData: () => duplicateLauncherData,
61
+ duplicateStep: () => duplicateStep,
62
+ duplicateStepWithRename: () => duplicateStepWithRename,
63
+ duplicateSteps: () => duplicateSteps,
61
64
  duplicateTarget: () => duplicateTarget,
62
65
  duplicateTriggers: () => duplicateTriggers,
63
66
  evalCode: () => evalCode,
@@ -1853,6 +1856,7 @@ var duplicateChecklistData = (data) => {
1853
1856
  const checklistData = data;
1854
1857
  return {
1855
1858
  ...checklistData,
1859
+ content: processQuestionElements(checklistData.content),
1856
1860
  items: checklistData.items.map((item) => ({
1857
1861
  ...item,
1858
1862
  id: uuidV4(),
@@ -1862,6 +1866,23 @@ var duplicateChecklistData = (data) => {
1862
1866
  }))
1863
1867
  };
1864
1868
  };
1869
+ var duplicateLauncherData = (data) => {
1870
+ if (!data || !isObject(data)) {
1871
+ return data;
1872
+ }
1873
+ const launcherData = data;
1874
+ return {
1875
+ ...launcherData,
1876
+ behavior: launcherData.behavior ? {
1877
+ ...launcherData.behavior,
1878
+ actions: isArray(launcherData.behavior.actions) ? regenerateConditionIds(launcherData.behavior.actions) : launcherData.behavior.actions
1879
+ } : launcherData.behavior,
1880
+ tooltip: launcherData.tooltip ? {
1881
+ ...launcherData.tooltip,
1882
+ content: processQuestionElements(launcherData.tooltip.content)
1883
+ } : launcherData.tooltip
1884
+ };
1885
+ };
1865
1886
  var duplicateConfig = (config) => {
1866
1887
  if (!config) {
1867
1888
  return config;
@@ -1876,20 +1897,33 @@ var duplicateData = (data, contentType) => {
1876
1897
  if (contentType === import_types7.ContentDataType.CHECKLIST) {
1877
1898
  return duplicateChecklistData(data);
1878
1899
  }
1900
+ if (contentType === import_types7.ContentDataType.LAUNCHER) {
1901
+ return duplicateLauncherData(data);
1902
+ }
1879
1903
  return data;
1880
1904
  };
1881
- var createStepCopy = (originalStep, sequence, existingStepNames) => {
1882
- const { id, cvid, updatedAt, createdAt, ...rest } = originalStep;
1883
- const name = generateUniqueCopyName(originalStep == null ? void 0 : originalStep.name, existingStepNames);
1884
- const trigger = (originalStep == null ? void 0 : originalStep.trigger) ? duplicateTriggers(originalStep == null ? void 0 : originalStep.trigger) : [];
1885
- const data = (originalStep == null ? void 0 : originalStep.data) ? processQuestionElements(originalStep == null ? void 0 : originalStep.data) : [];
1886
- const target = duplicateTarget(originalStep == null ? void 0 : originalStep.target);
1905
+ var duplicateStep = (step, options) => {
1906
+ var _a;
1907
+ const { id, cvid, createdAt, updatedAt, versionId, trigger, target, data, ...rest } = step;
1908
+ const preserveUndefined = (_a = options == null ? void 0 : options.preserveUndefined) != null ? _a : false;
1887
1909
  return {
1888
1910
  ...rest,
1889
- data,
1890
- trigger,
1891
- target,
1892
- name,
1911
+ data: data ? processQuestionElements(data) : preserveUndefined ? data : [],
1912
+ trigger: trigger ? duplicateTriggers(trigger) : preserveUndefined ? trigger : [],
1913
+ target: duplicateTarget(target)
1914
+ };
1915
+ };
1916
+ var duplicateSteps = (steps) => {
1917
+ if (!isArray(steps)) {
1918
+ return [];
1919
+ }
1920
+ return steps.map((step) => duplicateStep(step, { preserveUndefined: true }));
1921
+ };
1922
+ var duplicateStepWithRename = (originalStep, sequence, existingStepNames) => {
1923
+ const duplicated = duplicateStep(originalStep);
1924
+ return {
1925
+ ...duplicated,
1926
+ name: generateUniqueCopyName(originalStep.name, existingStepNames),
1893
1927
  sequence
1894
1928
  };
1895
1929
  };
@@ -1909,7 +1943,6 @@ var createStepCopy = (originalStep, sequence, existingStepNames) => {
1909
1943
  convertSettings,
1910
1944
  convertTimeConditionLegacyToV2,
1911
1945
  convertToCssVars,
1912
- createStepCopy,
1913
1946
  cuid,
1914
1947
  deepClone,
1915
1948
  defaultContentConfig,
@@ -1918,6 +1951,10 @@ var createStepCopy = (originalStep, sequence, existingStepNames) => {
1918
1951
  duplicateChecklistData,
1919
1952
  duplicateConfig,
1920
1953
  duplicateData,
1954
+ duplicateLauncherData,
1955
+ duplicateStep,
1956
+ duplicateStepWithRename,
1957
+ duplicateSteps,
1921
1958
  duplicateTarget,
1922
1959
  duplicateTriggers,
1923
1960
  evalCode,
package/dist/index.d.cts CHANGED
@@ -14,7 +14,7 @@ export { evaluateUrlCondition, isMatchUrlPattern } from './conditions/url.cjs';
14
14
  export { convertTimeConditionLegacyToV2, evaluateTimeCondition, isTimeConditionDataLegacy, isTimeConditionDataV2, normalizeTimeConditionData } from './conditions/time.cjs';
15
15
  export { evaluateAttributeCondition } from './conditions/attribute.cjs';
16
16
  export { capitalizeFirstLetter, filterNullAttributes, getAttributeType, isValidISO8601 } from './attribute.cjs';
17
- export { createStepCopy, duplicateChecklistData, duplicateConfig, duplicateData, duplicateTarget, duplicateTriggers, extractQuestionData, generateUniqueCopyName, hasMissingRequiredData, isClickableElement, isMissingRequiredData, isQuestionElement, isRestrictedType, processQuestionElements } from './content-helper.cjs';
17
+ export { duplicateChecklistData, duplicateConfig, duplicateData, duplicateLauncherData, duplicateStep, duplicateStepWithRename, duplicateSteps, duplicateTarget, duplicateTriggers, extractQuestionData, generateUniqueCopyName, hasMissingRequiredData, isClickableElement, isMissingRequiredData, isQuestionElement, isRestrictedType, processQuestionElements } from './content-helper.cjs';
18
18
  export { default as isEqual } from 'fast-deep-equal';
19
19
  import '@usertour/types';
20
20
  import './storage.cjs';
package/dist/index.d.ts CHANGED
@@ -14,7 +14,7 @@ export { evaluateUrlCondition, isMatchUrlPattern } from './conditions/url.js';
14
14
  export { convertTimeConditionLegacyToV2, evaluateTimeCondition, isTimeConditionDataLegacy, isTimeConditionDataV2, normalizeTimeConditionData } from './conditions/time.js';
15
15
  export { evaluateAttributeCondition } from './conditions/attribute.js';
16
16
  export { capitalizeFirstLetter, filterNullAttributes, getAttributeType, isValidISO8601 } from './attribute.js';
17
- export { createStepCopy, duplicateChecklistData, duplicateConfig, duplicateData, duplicateTarget, duplicateTriggers, extractQuestionData, generateUniqueCopyName, hasMissingRequiredData, isClickableElement, isMissingRequiredData, isQuestionElement, isRestrictedType, processQuestionElements } from './content-helper.js';
17
+ export { duplicateChecklistData, duplicateConfig, duplicateData, duplicateLauncherData, duplicateStep, duplicateStepWithRename, duplicateSteps, duplicateTarget, duplicateTriggers, extractQuestionData, generateUniqueCopyName, hasMissingRequiredData, isClickableElement, isMissingRequiredData, isQuestionElement, isRestrictedType, processQuestionElements } from './content-helper.js';
18
18
  export { default as isEqual } from 'fast-deep-equal';
19
19
  import '@usertour/types';
20
20
  import './storage.js';
package/dist/index.js CHANGED
@@ -23,10 +23,13 @@ import {
23
23
  } from "./chunk-FGFMTWFT.js";
24
24
  import "./chunk-3ZGH3NRU.js";
25
25
  import {
26
- createStepCopy,
27
26
  duplicateChecklistData,
28
27
  duplicateConfig,
29
28
  duplicateData,
29
+ duplicateLauncherData,
30
+ duplicateStep,
31
+ duplicateStepWithRename,
32
+ duplicateSteps,
30
33
  duplicateTarget,
31
34
  duplicateTriggers,
32
35
  extractQuestionData,
@@ -37,7 +40,7 @@ import {
37
40
  isQuestionElement,
38
41
  isRestrictedType,
39
42
  processQuestionElements
40
- } from "./chunk-7GJAPR7Y.js";
43
+ } from "./chunk-JTRQ5CEL.js";
41
44
  import "./chunk-7ODE2AIC.js";
42
45
  import {
43
46
  allConditionsHaveIds,
@@ -160,7 +163,6 @@ export {
160
163
  convertSettings,
161
164
  convertTimeConditionLegacyToV2,
162
165
  convertToCssVars,
163
- createStepCopy,
164
166
  cuid,
165
167
  deepClone,
166
168
  defaultContentConfig,
@@ -169,6 +171,10 @@ export {
169
171
  duplicateChecklistData,
170
172
  duplicateConfig,
171
173
  duplicateData,
174
+ duplicateLauncherData,
175
+ duplicateStep,
176
+ duplicateStepWithRename,
177
+ duplicateSteps,
172
178
  duplicateTarget,
173
179
  duplicateTriggers,
174
180
  evalCode,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usertour/helpers",
3
- "version": "0.0.48",
3
+ "version": "0.0.50",
4
4
  "type": "module",
5
5
  "description": "Utility functions and helpers shared across the UserTour project",
6
6
  "homepage": "https://www.usertour.io",