@usertour/helpers 0.0.48 → 0.0.49

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,25 @@ 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) => {
327
+ const { id, cvid, createdAt, updatedAt, versionId, trigger, target, data, ...rest } = step;
311
328
  return {
312
329
  ...rest,
313
- data,
314
- trigger,
315
- target,
316
- name,
330
+ data: data ? processQuestionElements(data) : data,
331
+ trigger: trigger ? duplicateTriggers(trigger) : trigger,
332
+ target: duplicateTarget(target)
333
+ };
334
+ };
335
+ var duplicateStepWithRename = (originalStep, sequence, existingStepNames) => {
336
+ const duplicated = duplicateStep(originalStep);
337
+ return {
338
+ ...duplicated,
339
+ name: generateUniqueCopyName(originalStep.name, existingStepNames),
317
340
  sequence
318
341
  };
319
342
  };
@@ -910,8 +933,8 @@ describe("duplicateData", () => {
910
933
  expect(result).toEqual(data);
911
934
  });
912
935
  });
913
- describe("createStepCopy", () => {
914
- test("should create a copy of the step with new name", () => {
936
+ describe("duplicateStepWithRename", () => {
937
+ test("should duplicate the step with new name", () => {
915
938
  const originalStep = {
916
939
  id: "step-1",
917
940
  cvid: "cvid-1",
@@ -923,7 +946,7 @@ describe("createStepCopy", () => {
923
946
  createdAt: /* @__PURE__ */ new Date(),
924
947
  updatedAt: /* @__PURE__ */ new Date()
925
948
  };
926
- const result = createStepCopy(originalStep, 1);
949
+ const result = duplicateStepWithRename(originalStep, 1);
927
950
  expect(result.name).toBe("Original Step (copy)");
928
951
  expect(result.sequence).toBe(1);
929
952
  expect(result).not.toHaveProperty("id");
@@ -941,10 +964,10 @@ describe("createStepCopy", () => {
941
964
  data: [],
942
965
  target: void 0
943
966
  };
944
- const result = createStepCopy(originalStep, 1, ["Step (copy)"]);
967
+ const result = duplicateStepWithRename(originalStep, 1, ["Step (copy)"]);
945
968
  expect(result.name).toBe("Step (copy 2)");
946
969
  });
947
- test("should process triggers in step copy", () => {
970
+ test("should process triggers in step duplicate", () => {
948
971
  var _a;
949
972
  const originalStep = {
950
973
  id: "step-1",
@@ -961,10 +984,10 @@ describe("createStepCopy", () => {
961
984
  data: [],
962
985
  target: void 0
963
986
  };
964
- const result = createStepCopy(originalStep, 1);
987
+ const result = duplicateStepWithRename(originalStep, 1);
965
988
  expect((_a = result.trigger) == null ? void 0 : _a[0].id).toBe("mock-cuid");
966
989
  });
967
- test("should process target in step copy", () => {
990
+ test("should process target in step duplicate", () => {
968
991
  var _a, _b;
969
992
  const originalStep = {
970
993
  id: "step-1",
@@ -977,7 +1000,7 @@ describe("createStepCopy", () => {
977
1000
  actions: [{ id: "action-1", type: "test", operators: "and", data: {} }]
978
1001
  }
979
1002
  };
980
- const result = createStepCopy(originalStep, 1);
1003
+ const result = duplicateStepWithRename(originalStep, 1);
981
1004
  expect((_b = (_a = result.target) == null ? void 0 : _a.actions) == null ? void 0 : _b[0].id).toBe("regenerated-action-1");
982
1005
  });
983
1006
  test("should handle step without trigger", () => {
@@ -990,7 +1013,7 @@ describe("createStepCopy", () => {
990
1013
  data: [],
991
1014
  target: void 0
992
1015
  };
993
- const result = createStepCopy(originalStep, 1);
1016
+ const result = duplicateStepWithRename(originalStep, 1);
994
1017
  expect(result.trigger).toEqual([]);
995
1018
  });
996
1019
  test("should handle step without data", () => {
@@ -1003,7 +1026,7 @@ describe("createStepCopy", () => {
1003
1026
  data: void 0,
1004
1027
  target: void 0
1005
1028
  };
1006
- const result = createStepCopy(originalStep, 1);
1029
+ const result = duplicateStepWithRename(originalStep, 1);
1007
1030
  expect(result.data).toEqual([]);
1008
1031
  });
1009
1032
  });
@@ -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-BCAOJ3IY.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,31 @@ 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) => {
209
+ const { id, cvid, createdAt, updatedAt, versionId, trigger, target, data, ...rest } = step;
193
210
  return {
194
211
  ...rest,
195
- data,
196
- trigger,
197
- target,
198
- name,
212
+ data: data ? processQuestionElements(data) : data,
213
+ trigger: trigger ? duplicateTriggers(trigger) : trigger,
214
+ target: duplicateTarget(target)
215
+ };
216
+ };
217
+ var duplicateSteps = (steps) => {
218
+ if (!isArray(steps)) {
219
+ return [];
220
+ }
221
+ return steps.map((step) => duplicateStep(step));
222
+ };
223
+ var duplicateStepWithRename = (originalStep, sequence, existingStepNames) => {
224
+ const duplicated = duplicateStep(originalStep);
225
+ return {
226
+ ...duplicated,
227
+ name: generateUniqueCopyName(originalStep.name, existingStepNames),
199
228
  sequence
200
229
  };
201
230
  };
@@ -212,7 +241,10 @@ export {
212
241
  duplicateTriggers,
213
242
  duplicateTarget,
214
243
  duplicateChecklistData,
244
+ duplicateLauncherData,
215
245
  duplicateConfig,
216
246
  duplicateData,
217
- createStepCopy
247
+ duplicateStep,
248
+ duplicateSteps,
249
+ duplicateStepWithRename
218
250
  };
@@ -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,43 @@ 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) => {
350
+ const { id, cvid, createdAt, updatedAt, versionId, trigger, target, data, ...rest } = step;
331
351
  return {
332
352
  ...rest,
333
- data,
334
- trigger,
335
- target,
336
- name,
353
+ data: data ? processQuestionElements(data) : data,
354
+ trigger: trigger ? duplicateTriggers(trigger) : trigger,
355
+ target: duplicateTarget(target)
356
+ };
357
+ };
358
+ var duplicateSteps = (steps) => {
359
+ if (!isArray(steps)) {
360
+ return [];
361
+ }
362
+ return steps.map((step) => duplicateStep(step));
363
+ };
364
+ var duplicateStepWithRename = (originalStep, sequence, existingStepNames) => {
365
+ const duplicated = duplicateStep(originalStep);
366
+ return {
367
+ ...duplicated,
368
+ name: generateUniqueCopyName(originalStep.name, existingStepNames),
337
369
  sequence
338
370
  };
339
371
  };
340
372
  // Annotate the CommonJS export names for ESM import in node:
341
373
  0 && (module.exports = {
342
- createStepCopy,
343
374
  duplicateChecklistData,
344
375
  duplicateConfig,
345
376
  duplicateData,
377
+ duplicateLauncherData,
378
+ duplicateStep,
379
+ duplicateStepWithRename,
380
+ duplicateSteps,
346
381
  duplicateTarget,
347
382
  duplicateTriggers,
348
383
  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,47 @@ 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
+ */
67
+ type StepLike = {
68
+ id?: string;
69
+ cvid?: string;
70
+ createdAt?: string | Date;
71
+ updatedAt?: string | Date;
72
+ versionId?: string;
73
+ data?: ContentEditorRoot[];
74
+ trigger?: StepTrigger[];
75
+ target?: Step['target'];
76
+ [key: string]: unknown;
77
+ };
78
+ /**
79
+ * Core function to duplicate a single step by removing database-specific fields
80
+ * and regenerating IDs in triggers, target actions, and question elements
81
+ * @param step - The step to duplicate
82
+ * @returns A new step object with regenerated IDs, without id/cvid/timestamps/versionId
83
+ */
84
+ declare const duplicateStep: <T extends StepLike>(step: T) => Omit<T, "id" | "cvid" | "createdAt" | "updatedAt" | "versionId">;
85
+ /**
86
+ * Process multiple steps for duplication
87
+ * Works with both Prisma Step type (server) and @usertour/types Step (client)
88
+ * @param steps - Array of steps to process
89
+ * @returns Array of steps ready for creation with regenerated IDs
90
+ */
91
+ declare const duplicateSteps: <T extends StepLike>(steps: T[]) => Omit<T, "id" | "cvid" | "createdAt" | "updatedAt" | "versionId">[];
92
+ /**
93
+ * Duplicate a single step with a new unique name and sequence
94
+ * Used for UI operations when duplicating a step within the same version
95
+ * @param originalStep - The step to duplicate
96
+ * @param sequence - The new sequence number for the duplicated step
97
+ * @param existingStepNames - Optional array of existing step names to avoid conflicts
98
+ * @returns A new step object ready for creation
99
+ */
100
+ declare const duplicateStepWithRename: (originalStep: Step, sequence: number, existingStepNames?: string[]) => Omit<Step, 'id' | 'cvid' | 'updatedAt' | 'createdAt'>;
56
101
 
57
- export { createStepCopy, duplicateChecklistData, duplicateConfig, duplicateData, duplicateTarget, duplicateTriggers, extractQuestionData, generateUniqueCopyName, hasMissingRequiredData, isClickableElement, isMissingRequiredData, isQuestionElement, isRestrictedType, processQuestionElements };
102
+ 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,47 @@ 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
+ */
67
+ type StepLike = {
68
+ id?: string;
69
+ cvid?: string;
70
+ createdAt?: string | Date;
71
+ updatedAt?: string | Date;
72
+ versionId?: string;
73
+ data?: ContentEditorRoot[];
74
+ trigger?: StepTrigger[];
75
+ target?: Step['target'];
76
+ [key: string]: unknown;
77
+ };
78
+ /**
79
+ * Core function to duplicate a single step by removing database-specific fields
80
+ * and regenerating IDs in triggers, target actions, and question elements
81
+ * @param step - The step to duplicate
82
+ * @returns A new step object with regenerated IDs, without id/cvid/timestamps/versionId
83
+ */
84
+ declare const duplicateStep: <T extends StepLike>(step: T) => Omit<T, "id" | "cvid" | "createdAt" | "updatedAt" | "versionId">;
85
+ /**
86
+ * Process multiple steps for duplication
87
+ * Works with both Prisma Step type (server) and @usertour/types Step (client)
88
+ * @param steps - Array of steps to process
89
+ * @returns Array of steps ready for creation with regenerated IDs
90
+ */
91
+ declare const duplicateSteps: <T extends StepLike>(steps: T[]) => Omit<T, "id" | "cvid" | "createdAt" | "updatedAt" | "versionId">[];
92
+ /**
93
+ * Duplicate a single step with a new unique name and sequence
94
+ * Used for UI operations when duplicating a step within the same version
95
+ * @param originalStep - The step to duplicate
96
+ * @param sequence - The new sequence number for the duplicated step
97
+ * @param existingStepNames - Optional array of existing step names to avoid conflicts
98
+ * @returns A new step object ready for creation
99
+ */
100
+ declare const duplicateStepWithRename: (originalStep: Step, sequence: number, existingStepNames?: string[]) => Omit<Step, 'id' | 'cvid' | 'updatedAt' | 'createdAt'>;
56
101
 
57
- export { createStepCopy, duplicateChecklistData, duplicateConfig, duplicateData, duplicateTarget, duplicateTriggers, extractQuestionData, generateUniqueCopyName, hasMissingRequiredData, isClickableElement, isMissingRequiredData, isQuestionElement, isRestrictedType, processQuestionElements };
102
+ 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-BCAOJ3IY.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,31 @@ 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) => {
1906
+ const { id, cvid, createdAt, updatedAt, versionId, trigger, target, data, ...rest } = step;
1887
1907
  return {
1888
1908
  ...rest,
1889
- data,
1890
- trigger,
1891
- target,
1892
- name,
1909
+ data: data ? processQuestionElements(data) : data,
1910
+ trigger: trigger ? duplicateTriggers(trigger) : trigger,
1911
+ target: duplicateTarget(target)
1912
+ };
1913
+ };
1914
+ var duplicateSteps = (steps) => {
1915
+ if (!isArray(steps)) {
1916
+ return [];
1917
+ }
1918
+ return steps.map((step) => duplicateStep(step));
1919
+ };
1920
+ var duplicateStepWithRename = (originalStep, sequence, existingStepNames) => {
1921
+ const duplicated = duplicateStep(originalStep);
1922
+ return {
1923
+ ...duplicated,
1924
+ name: generateUniqueCopyName(originalStep.name, existingStepNames),
1893
1925
  sequence
1894
1926
  };
1895
1927
  };
@@ -1909,7 +1941,6 @@ var createStepCopy = (originalStep, sequence, existingStepNames) => {
1909
1941
  convertSettings,
1910
1942
  convertTimeConditionLegacyToV2,
1911
1943
  convertToCssVars,
1912
- createStepCopy,
1913
1944
  cuid,
1914
1945
  deepClone,
1915
1946
  defaultContentConfig,
@@ -1918,6 +1949,10 @@ var createStepCopy = (originalStep, sequence, existingStepNames) => {
1918
1949
  duplicateChecklistData,
1919
1950
  duplicateConfig,
1920
1951
  duplicateData,
1952
+ duplicateLauncherData,
1953
+ duplicateStep,
1954
+ duplicateStepWithRename,
1955
+ duplicateSteps,
1921
1956
  duplicateTarget,
1922
1957
  duplicateTriggers,
1923
1958
  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-BCAOJ3IY.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.49",
4
4
  "type": "module",
5
5
  "description": "Utility functions and helpers shared across the UserTour project",
6
6
  "homepage": "https://www.usertour.io",