@usertour/helpers 0.0.47 → 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.
@@ -0,0 +1,250 @@
1
+ import {
2
+ regenerateConditionIds
3
+ } from "./chunk-SIG4WTEF.js";
4
+ import {
5
+ cuid,
6
+ uuidV4
7
+ } from "./chunk-3KG2HTZ3.js";
8
+ import {
9
+ isArray,
10
+ isEmptyString,
11
+ isObject
12
+ } from "./chunk-GFH3VWOC.js";
13
+
14
+ // src/content-helper.ts
15
+ import { ContentDataType, ContentEditorElementType } from "@usertour/types";
16
+ var isRestrictedType = (type) => {
17
+ const restrictedTypes = [
18
+ ContentEditorElementType.NPS,
19
+ ContentEditorElementType.STAR_RATING,
20
+ ContentEditorElementType.SCALE,
21
+ ContentEditorElementType.SINGLE_LINE_TEXT,
22
+ ContentEditorElementType.MULTI_LINE_TEXT,
23
+ ContentEditorElementType.MULTIPLE_CHOICE
24
+ ];
25
+ return restrictedTypes.includes(type);
26
+ };
27
+ var isMissingRequiredData = (element) => {
28
+ var _a, _b, _c, _d;
29
+ if (isRestrictedType(element.type)) {
30
+ return isEmptyString((_a = element.data) == null ? void 0 : _a.name);
31
+ }
32
+ if (element.type === ContentEditorElementType.BUTTON) {
33
+ if (isEmptyString((_b = element.data) == null ? void 0 : _b.text)) {
34
+ return true;
35
+ }
36
+ if (!((_c = element == null ? void 0 : element.data) == null ? void 0 : _c.actions) || ((_d = element == null ? void 0 : element.data) == null ? void 0 : _d.actions.length) === 0) {
37
+ return true;
38
+ }
39
+ }
40
+ return false;
41
+ };
42
+ var hasMissingRequiredData = (contents) => {
43
+ return contents.some(
44
+ (group) => group.children.some(
45
+ (column) => column.children.some((item) => isMissingRequiredData(item.element))
46
+ )
47
+ );
48
+ };
49
+ var isQuestionElement = (element) => {
50
+ return element.type === ContentEditorElementType.SINGLE_LINE_TEXT || element.type === ContentEditorElementType.MULTI_LINE_TEXT || element.type === ContentEditorElementType.NPS || element.type === ContentEditorElementType.STAR_RATING || element.type === ContentEditorElementType.SCALE || element.type === ContentEditorElementType.MULTIPLE_CHOICE;
51
+ };
52
+ var isClickableElement = (element) => {
53
+ return element.type === ContentEditorElementType.BUTTON || isQuestionElement(element);
54
+ };
55
+ var extractQuestionData = (data) => {
56
+ const result = [];
57
+ function isQuestionRootElement(item) {
58
+ return "element" in item && isQuestionElement(item.element);
59
+ }
60
+ function traverse(item) {
61
+ if (isQuestionRootElement(item)) {
62
+ result.push(item.element);
63
+ }
64
+ if ("children" in item && item.children) {
65
+ for (const child of item.children) {
66
+ traverse(child);
67
+ }
68
+ }
69
+ }
70
+ for (const item of data) {
71
+ traverse(item);
72
+ }
73
+ return result;
74
+ };
75
+ var processQuestionElements = (contents) => {
76
+ if (!contents || !isArray(contents) || contents.length === 0) {
77
+ return [];
78
+ }
79
+ return contents.map((group) => ({
80
+ ...group,
81
+ children: group.children.map((column) => ({
82
+ ...column,
83
+ children: column.children.map((item) => {
84
+ var _a, _b;
85
+ const element = item.element;
86
+ if (isQuestionElement(element)) {
87
+ const questionElement = element;
88
+ const updatedElement = {
89
+ ...questionElement,
90
+ data: {
91
+ ...questionElement.data,
92
+ cvid: cuid(),
93
+ ...((_a = questionElement.data) == null ? void 0 : _a.actions) && isArray(questionElement.data.actions) ? { actions: regenerateConditionIds(questionElement.data.actions) } : {}
94
+ }
95
+ };
96
+ return {
97
+ ...item,
98
+ element: updatedElement
99
+ };
100
+ }
101
+ if (element.type === ContentEditorElementType.BUTTON) {
102
+ const buttonElement = element;
103
+ if (((_b = buttonElement.data) == null ? void 0 : _b.actions) && isArray(buttonElement.data.actions)) {
104
+ return {
105
+ ...item,
106
+ element: {
107
+ ...buttonElement,
108
+ data: {
109
+ ...buttonElement.data,
110
+ actions: regenerateConditionIds(buttonElement.data.actions)
111
+ }
112
+ }
113
+ };
114
+ }
115
+ }
116
+ return item;
117
+ })
118
+ }))
119
+ }));
120
+ };
121
+ var generateUniqueCopyName = (originalName, existingNames) => {
122
+ let name = `${originalName} (copy)`;
123
+ if (existingNames == null ? void 0 : existingNames.includes(name)) {
124
+ let number = 2;
125
+ while (existingNames.includes(`${originalName} (copy ${number})`)) {
126
+ number++;
127
+ }
128
+ name = `${originalName} (copy ${number})`;
129
+ }
130
+ return name;
131
+ };
132
+ var duplicateTriggers = (triggers) => {
133
+ if (!isArray(triggers)) {
134
+ return triggers;
135
+ }
136
+ return triggers.map((trigger) => ({
137
+ ...trigger,
138
+ id: cuid(),
139
+ actions: isArray(trigger.actions) ? regenerateConditionIds(trigger.actions) : trigger.actions,
140
+ conditions: isArray(trigger.conditions) ? regenerateConditionIds(trigger.conditions) : trigger.conditions
141
+ }));
142
+ };
143
+ var duplicateTarget = (target) => {
144
+ if (!target) {
145
+ return void 0;
146
+ }
147
+ if (target.actions && isArray(target.actions)) {
148
+ return {
149
+ ...target,
150
+ actions: regenerateConditionIds(target.actions)
151
+ };
152
+ }
153
+ return target;
154
+ };
155
+ var duplicateChecklistData = (data) => {
156
+ if (!data || !isObject(data) || !isArray(data.items)) {
157
+ return data;
158
+ }
159
+ const checklistData = data;
160
+ return {
161
+ ...checklistData,
162
+ content: processQuestionElements(checklistData.content),
163
+ items: checklistData.items.map((item) => ({
164
+ ...item,
165
+ id: uuidV4(),
166
+ clickedActions: isArray(item.clickedActions) ? regenerateConditionIds(item.clickedActions) : item.clickedActions,
167
+ completeConditions: isArray(item.completeConditions) ? regenerateConditionIds(item.completeConditions) : item.completeConditions,
168
+ onlyShowTaskConditions: isArray(item.onlyShowTaskConditions) ? regenerateConditionIds(item.onlyShowTaskConditions) : item.onlyShowTaskConditions
169
+ }))
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
+ };
189
+ var duplicateConfig = (config) => {
190
+ if (!config) {
191
+ return config;
192
+ }
193
+ return {
194
+ ...config,
195
+ autoStartRules: config.autoStartRules ? regenerateConditionIds(config.autoStartRules) : config.autoStartRules,
196
+ hideRules: config.hideRules ? regenerateConditionIds(config.hideRules) : config.hideRules
197
+ };
198
+ };
199
+ var duplicateData = (data, contentType) => {
200
+ if (contentType === ContentDataType.CHECKLIST) {
201
+ return duplicateChecklistData(data);
202
+ }
203
+ if (contentType === ContentDataType.LAUNCHER) {
204
+ return duplicateLauncherData(data);
205
+ }
206
+ return data;
207
+ };
208
+ var duplicateStep = (step) => {
209
+ const { id, cvid, createdAt, updatedAt, versionId, trigger, target, data, ...rest } = step;
210
+ return {
211
+ ...rest,
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),
228
+ sequence
229
+ };
230
+ };
231
+
232
+ export {
233
+ isRestrictedType,
234
+ isMissingRequiredData,
235
+ hasMissingRequiredData,
236
+ isQuestionElement,
237
+ isClickableElement,
238
+ extractQuestionData,
239
+ processQuestionElements,
240
+ generateUniqueCopyName,
241
+ duplicateTriggers,
242
+ duplicateTarget,
243
+ duplicateChecklistData,
244
+ duplicateLauncherData,
245
+ duplicateConfig,
246
+ duplicateData,
247
+ duplicateStep,
248
+ duplicateSteps,
249
+ duplicateStepWithRename
250
+ };
@@ -30,7 +30,15 @@ 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,
33
+ duplicateChecklistData: () => duplicateChecklistData,
34
+ duplicateConfig: () => duplicateConfig,
35
+ duplicateData: () => duplicateData,
36
+ duplicateLauncherData: () => duplicateLauncherData,
37
+ duplicateStep: () => duplicateStep,
38
+ duplicateStepWithRename: () => duplicateStepWithRename,
39
+ duplicateSteps: () => duplicateSteps,
40
+ duplicateTarget: () => duplicateTarget,
41
+ duplicateTriggers: () => duplicateTriggers,
34
42
  extractQuestionData: () => extractQuestionData,
35
43
  generateUniqueCopyName: () => generateUniqueCopyName,
36
44
  hasMissingRequiredData: () => hasMissingRequiredData,
@@ -38,9 +46,7 @@ __export(content_helper_exports, {
38
46
  isMissingRequiredData: () => isMissingRequiredData,
39
47
  isQuestionElement: () => isQuestionElement,
40
48
  isRestrictedType: () => isRestrictedType,
41
- processQuestionElements: () => processQuestionElements,
42
- regenerateTarget: () => regenerateTarget,
43
- regenerateTrigger: () => regenerateTrigger
49
+ processQuestionElements: () => processQuestionElements
44
50
  });
45
51
  module.exports = __toCommonJS(content_helper_exports);
46
52
  var import_types3 = require("@usertour/types");
@@ -126,6 +132,9 @@ var ObjProto = Object.prototype;
126
132
  var objToString = ObjProto.toString;
127
133
  var objHasOwn = ObjProto.hasOwnProperty;
128
134
  var isArray = nativeIsArray || ((obj) => objToString.call(obj) === "[object Array]");
135
+ var isObject = (x) => {
136
+ return x === Object(x) && !isArray(x);
137
+ };
129
138
  var isString = (x) => {
130
139
  return objToString.call(x) === "[object String]";
131
140
  };
@@ -250,15 +259,29 @@ var processQuestionElements = (contents) => {
250
259
  }))
251
260
  }));
252
261
  };
253
- var regenerateTrigger = (trigger) => {
254
- return trigger.map((t) => ({
255
- ...t,
262
+ var generateUniqueCopyName = (originalName, existingNames) => {
263
+ let name = `${originalName} (copy)`;
264
+ if (existingNames == null ? void 0 : existingNames.includes(name)) {
265
+ let number = 2;
266
+ while (existingNames.includes(`${originalName} (copy ${number})`)) {
267
+ number++;
268
+ }
269
+ name = `${originalName} (copy ${number})`;
270
+ }
271
+ return name;
272
+ };
273
+ var duplicateTriggers = (triggers) => {
274
+ if (!isArray(triggers)) {
275
+ return triggers;
276
+ }
277
+ return triggers.map((trigger) => ({
278
+ ...trigger,
256
279
  id: cuid(),
257
- conditions: regenerateConditionIds(t.conditions),
258
- actions: regenerateConditionIds(t.actions)
280
+ actions: isArray(trigger.actions) ? regenerateConditionIds(trigger.actions) : trigger.actions,
281
+ conditions: isArray(trigger.conditions) ? regenerateConditionIds(trigger.conditions) : trigger.conditions
259
282
  }));
260
283
  };
261
- var regenerateTarget = (target) => {
284
+ var duplicateTarget = (target) => {
262
285
  if (!target) {
263
286
  return void 0;
264
287
  }
@@ -270,35 +293,93 @@ var regenerateTarget = (target) => {
270
293
  }
271
294
  return target;
272
295
  };
273
- var generateUniqueCopyName = (originalName, existingNames) => {
274
- let name = `${originalName} (copy)`;
275
- if (existingNames == null ? void 0 : existingNames.includes(name)) {
276
- let number = 2;
277
- while (existingNames.includes(`${originalName} (copy ${number})`)) {
278
- number++;
279
- }
280
- name = `${originalName} (copy ${number})`;
296
+ var duplicateChecklistData = (data) => {
297
+ if (!data || !isObject(data) || !isArray(data.items)) {
298
+ return data;
281
299
  }
282
- return name;
300
+ const checklistData = data;
301
+ return {
302
+ ...checklistData,
303
+ content: processQuestionElements(checklistData.content),
304
+ items: checklistData.items.map((item) => ({
305
+ ...item,
306
+ id: uuidV4(),
307
+ clickedActions: isArray(item.clickedActions) ? regenerateConditionIds(item.clickedActions) : item.clickedActions,
308
+ completeConditions: isArray(item.completeConditions) ? regenerateConditionIds(item.completeConditions) : item.completeConditions,
309
+ onlyShowTaskConditions: isArray(item.onlyShowTaskConditions) ? regenerateConditionIds(item.onlyShowTaskConditions) : item.onlyShowTaskConditions
310
+ }))
311
+ };
283
312
  };
284
- var createStepCopy = (originalStep, sequence, existingStepNames) => {
285
- const { id, cvid, updatedAt, createdAt, ...rest } = originalStep;
286
- const name = generateUniqueCopyName(originalStep == null ? void 0 : originalStep.name, existingStepNames);
287
- const trigger = (originalStep == null ? void 0 : originalStep.trigger) ? regenerateTrigger(originalStep == null ? void 0 : originalStep.trigger) : [];
288
- const data = (originalStep == null ? void 0 : originalStep.data) ? processQuestionElements(originalStep == null ? void 0 : originalStep.data) : [];
289
- const target = regenerateTarget(originalStep == null ? void 0 : originalStep.target);
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
+ };
330
+ var duplicateConfig = (config) => {
331
+ if (!config) {
332
+ return config;
333
+ }
334
+ return {
335
+ ...config,
336
+ autoStartRules: config.autoStartRules ? regenerateConditionIds(config.autoStartRules) : config.autoStartRules,
337
+ hideRules: config.hideRules ? regenerateConditionIds(config.hideRules) : config.hideRules
338
+ };
339
+ };
340
+ var duplicateData = (data, contentType) => {
341
+ if (contentType === import_types3.ContentDataType.CHECKLIST) {
342
+ return duplicateChecklistData(data);
343
+ }
344
+ if (contentType === import_types3.ContentDataType.LAUNCHER) {
345
+ return duplicateLauncherData(data);
346
+ }
347
+ return data;
348
+ };
349
+ var duplicateStep = (step) => {
350
+ const { id, cvid, createdAt, updatedAt, versionId, trigger, target, data, ...rest } = step;
290
351
  return {
291
352
  ...rest,
292
- data,
293
- trigger,
294
- target,
295
- 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),
296
369
  sequence
297
370
  };
298
371
  };
299
372
  // Annotate the CommonJS export names for ESM import in node:
300
373
  0 && (module.exports = {
301
- createStepCopy,
374
+ duplicateChecklistData,
375
+ duplicateConfig,
376
+ duplicateData,
377
+ duplicateLauncherData,
378
+ duplicateStep,
379
+ duplicateStepWithRename,
380
+ duplicateSteps,
381
+ duplicateTarget,
382
+ duplicateTriggers,
302
383
  extractQuestionData,
303
384
  generateUniqueCopyName,
304
385
  hasMissingRequiredData,
@@ -306,7 +387,5 @@ var createStepCopy = (originalStep, sequence, existingStepNames) => {
306
387
  isMissingRequiredData,
307
388
  isQuestionElement,
308
389
  isRestrictedType,
309
- processQuestionElements,
310
- regenerateTarget,
311
- regenerateTrigger
390
+ processQuestionElements
312
391
  });
@@ -1,4 +1,4 @@
1
- import { ContentEditorElementType, ContentEditorElement, ContentEditorRoot, ContentEditorClickableElement, ContentEditorQuestionElement, StepTrigger, Step } from '@usertour/types';
1
+ import { ContentEditorElementType, ContentEditorElement, ContentEditorRoot, ContentEditorClickableElement, ContentEditorQuestionElement, StepTrigger, Step, ContentConfigObject } from '@usertour/types';
2
2
 
3
3
  declare const isRestrictedType: (type: ContentEditorElementType) => boolean;
4
4
  declare const isMissingRequiredData: (element: ContentEditorElement) => boolean;
@@ -13,13 +13,6 @@ declare const extractQuestionData: (data: ContentEditorRoot[]) => ContentEditorQ
13
13
  * @returns A new array with question element cvids replaced by new cuids and actions regenerated
14
14
  */
15
15
  declare const processQuestionElements: (contents: ContentEditorRoot[] | undefined) => ContentEditorRoot[];
16
- declare const regenerateTrigger: (trigger: StepTrigger[]) => StepTrigger[];
17
- /**
18
- * Process target to regenerate condition IDs in actions field
19
- * @param target - The target object to process
20
- * @returns A new target object with regenerated action condition IDs, or undefined if target is undefined
21
- */
22
- declare const regenerateTarget: (target: Step['target']) => Step['target'];
23
16
  /**
24
17
  * Generate a unique copy name based on the original name and existing names
25
18
  * @param originalName - The original name to base the copy name on
@@ -27,6 +20,83 @@ declare const regenerateTarget: (target: Step['target']) => Step['target'];
27
20
  * @returns A unique name in the format "Name (copy)", "Name (copy 2)", etc.
28
21
  */
29
22
  declare const generateUniqueCopyName: (originalName: string, existingNames?: string[]) => string;
30
- declare const createStepCopy: (originalStep: Step, sequence: number, existingStepNames?: string[]) => Step;
23
+ /**
24
+ * Regenerate IDs for step triggers and their nested actions/conditions
25
+ * @param triggers - Array of step triggers to process
26
+ * @returns New array with regenerated IDs for triggers, actions, and conditions
27
+ */
28
+ declare const duplicateTriggers: (triggers: StepTrigger[]) => StepTrigger[];
29
+ /**
30
+ * Process target to regenerate condition IDs in actions field
31
+ * @param target - The target object to process
32
+ * @returns A new target object with regenerated action condition IDs, or undefined if target is undefined
33
+ */
34
+ declare const duplicateTarget: (target: Step['target']) => Step['target'];
35
+ /**
36
+ * Process ChecklistData to regenerate condition IDs in RulesCondition[] fields
37
+ * Handles clickedActions, completeConditions, and onlyShowTaskConditions for each item
38
+ * Also processes content field using processQuestionElements
39
+ * @param data - The checklist data to process
40
+ * @returns Processed checklist data with regenerated condition IDs
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;
50
+ /**
51
+ * Process version config to regenerate condition IDs in autoStartRules and hideRules
52
+ * @param config - The content config object to process
53
+ * @returns New config object with regenerated condition IDs
54
+ */
55
+ declare const duplicateConfig: (config: ContentConfigObject) => ContentConfigObject;
56
+ /**
57
+ * Process version data based on content type to regenerate condition IDs
58
+ * @param data - The version data to process
59
+ * @param contentType - The type of content (checklist, launcher, flow, etc.)
60
+ * @returns Processed data with regenerated condition IDs
61
+ */
62
+ declare const duplicateData: (data: unknown, contentType: string) => unknown;
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'>;
31
101
 
32
- export { createStepCopy, extractQuestionData, generateUniqueCopyName, hasMissingRequiredData, isClickableElement, isMissingRequiredData, isQuestionElement, isRestrictedType, processQuestionElements, regenerateTarget, regenerateTrigger };
102
+ export { duplicateChecklistData, duplicateConfig, duplicateData, duplicateLauncherData, duplicateStep, duplicateStepWithRename, duplicateSteps, duplicateTarget, duplicateTriggers, extractQuestionData, generateUniqueCopyName, hasMissingRequiredData, isClickableElement, isMissingRequiredData, isQuestionElement, isRestrictedType, processQuestionElements };
@@ -1,4 +1,4 @@
1
- import { ContentEditorElementType, ContentEditorElement, ContentEditorRoot, ContentEditorClickableElement, ContentEditorQuestionElement, StepTrigger, Step } from '@usertour/types';
1
+ import { ContentEditorElementType, ContentEditorElement, ContentEditorRoot, ContentEditorClickableElement, ContentEditorQuestionElement, StepTrigger, Step, ContentConfigObject } from '@usertour/types';
2
2
 
3
3
  declare const isRestrictedType: (type: ContentEditorElementType) => boolean;
4
4
  declare const isMissingRequiredData: (element: ContentEditorElement) => boolean;
@@ -13,13 +13,6 @@ declare const extractQuestionData: (data: ContentEditorRoot[]) => ContentEditorQ
13
13
  * @returns A new array with question element cvids replaced by new cuids and actions regenerated
14
14
  */
15
15
  declare const processQuestionElements: (contents: ContentEditorRoot[] | undefined) => ContentEditorRoot[];
16
- declare const regenerateTrigger: (trigger: StepTrigger[]) => StepTrigger[];
17
- /**
18
- * Process target to regenerate condition IDs in actions field
19
- * @param target - The target object to process
20
- * @returns A new target object with regenerated action condition IDs, or undefined if target is undefined
21
- */
22
- declare const regenerateTarget: (target: Step['target']) => Step['target'];
23
16
  /**
24
17
  * Generate a unique copy name based on the original name and existing names
25
18
  * @param originalName - The original name to base the copy name on
@@ -27,6 +20,83 @@ declare const regenerateTarget: (target: Step['target']) => Step['target'];
27
20
  * @returns A unique name in the format "Name (copy)", "Name (copy 2)", etc.
28
21
  */
29
22
  declare const generateUniqueCopyName: (originalName: string, existingNames?: string[]) => string;
30
- declare const createStepCopy: (originalStep: Step, sequence: number, existingStepNames?: string[]) => Step;
23
+ /**
24
+ * Regenerate IDs for step triggers and their nested actions/conditions
25
+ * @param triggers - Array of step triggers to process
26
+ * @returns New array with regenerated IDs for triggers, actions, and conditions
27
+ */
28
+ declare const duplicateTriggers: (triggers: StepTrigger[]) => StepTrigger[];
29
+ /**
30
+ * Process target to regenerate condition IDs in actions field
31
+ * @param target - The target object to process
32
+ * @returns A new target object with regenerated action condition IDs, or undefined if target is undefined
33
+ */
34
+ declare const duplicateTarget: (target: Step['target']) => Step['target'];
35
+ /**
36
+ * Process ChecklistData to regenerate condition IDs in RulesCondition[] fields
37
+ * Handles clickedActions, completeConditions, and onlyShowTaskConditions for each item
38
+ * Also processes content field using processQuestionElements
39
+ * @param data - The checklist data to process
40
+ * @returns Processed checklist data with regenerated condition IDs
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;
50
+ /**
51
+ * Process version config to regenerate condition IDs in autoStartRules and hideRules
52
+ * @param config - The content config object to process
53
+ * @returns New config object with regenerated condition IDs
54
+ */
55
+ declare const duplicateConfig: (config: ContentConfigObject) => ContentConfigObject;
56
+ /**
57
+ * Process version data based on content type to regenerate condition IDs
58
+ * @param data - The version data to process
59
+ * @param contentType - The type of content (checklist, launcher, flow, etc.)
60
+ * @returns Processed data with regenerated condition IDs
61
+ */
62
+ declare const duplicateData: (data: unknown, contentType: string) => unknown;
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'>;
31
101
 
32
- export { createStepCopy, extractQuestionData, generateUniqueCopyName, hasMissingRequiredData, isClickableElement, isMissingRequiredData, isQuestionElement, isRestrictedType, processQuestionElements, regenerateTarget, regenerateTrigger };
102
+ export { duplicateChecklistData, duplicateConfig, duplicateData, duplicateLauncherData, duplicateStep, duplicateStepWithRename, duplicateSteps, duplicateTarget, duplicateTriggers, extractQuestionData, generateUniqueCopyName, hasMissingRequiredData, isClickableElement, isMissingRequiredData, isQuestionElement, isRestrictedType, processQuestionElements };