|
1 | | -import { ScriptData, Activity, Step, isActivity } from './types'; |
2 | | -import { createActivity, createStep } from './factories'; |
| 1 | +import { ScriptData, ScriptedActivity, ScriptedStep } from './types'; |
| 2 | +import { createMessage } from './factories'; |
3 | 3 |
|
4 | | -// Ensure activity has required structural defaults |
5 | | -export function normalizeActivity(raw: any): Activity { |
6 | | - if (isActivity(raw)) { |
7 | | - // ensure messages have seconds and required fields |
8 | | - const nodeType = (raw.nodeType === 'PerformanceCenterScriptedActivity') ? 'PerformanceCenterScriptedActivity' : 'RangeAnalysisScriptedActivity'; |
9 | | - const base = createActivity({ |
10 | | - nodeType, |
11 | | - id: raw.id || 'activity-unnamed', |
12 | | - introHeader: raw.introMessage?.header || 'Intro', |
13 | | - introDescription: raw.introMessage?.description || '', |
14 | | - }); |
15 | | - base.endMessage = { |
16 | | - header: raw.endMessage?.header || base.endMessage.header, |
17 | | - description: raw.endMessage?.description || base.endMessage.description, |
18 | | - seconds: raw.endMessage?.seconds ?? 3, |
19 | | - }; |
20 | | - base.steps = Array.isArray(raw.steps) ? raw.steps.map(s => normalizeStep(s, nodeType)) : []; |
21 | | - return base; |
22 | | - } |
23 | | - // fallback create new |
24 | | - return createActivity({ nodeType: 'RangeAnalysisScriptedActivity', id: 'activity-unnamed', introHeader: 'Intro' }); |
| 4 | +// Simple normalizer functions |
| 5 | +export function normalizeActivity(raw: any): ScriptedActivity { |
| 6 | + return raw as ScriptedActivity; |
25 | 7 | } |
26 | 8 |
|
27 | | -export function normalizeStep(raw: any, parentActivityType: 'RangeAnalysisScriptedActivity' | 'PerformanceCenterScriptedActivity'): Step { |
28 | | - const base = createStep({ |
29 | | - parentActivityType, |
30 | | - id: raw.id || 'step-unnamed', |
31 | | - introHeader: raw.introMessage?.header || 'Step Intro', |
32 | | - introDescription: raw.introMessage?.description || '', |
33 | | - successHeader: raw.successMessage?.header, |
34 | | - failHeader: raw.failMessage?.header, |
35 | | - }); |
36 | | - // merge logic specifics if present (preserve user-entered data) |
37 | | - if (raw.logic) { |
38 | | - base.logic = { ...base.logic, ...raw.logic }; |
39 | | - // Ensure setup presence and required properties |
40 | | - const stepType = base.nodeType; |
41 | | - if (!base.logic.setup || typeof base.logic.setup !== 'object') { |
42 | | - // leave base.logic.setup from factory |
43 | | - } else { |
44 | | - if (stepType === 'RangeAnalysisScriptedStep') { |
45 | | - base.logic.setup.nodeType = 'RangeAnalysisScriptedSetup'; |
46 | | - base.logic.setup.club = base.logic.setup.club || 'Drv'; |
47 | | - base.logic.setup.distance = base.logic.setup.distance ?? 200; |
48 | | - } else { // Performance Center |
49 | | - if (base.logic.setup.nodeType !== 'PerformanceCenterApproachScriptedSetup' && base.logic.setup.nodeType !== 'PerformanceCenterTeeShotsScriptedSetup') { |
50 | | - // default to Approach variant |
51 | | - base.logic.setup = { nodeType: 'PerformanceCenterApproachScriptedSetup', hole: 1, pin: 1, playerCategory: 'Handicap', hcp: 10, gender: 'Unspecified', minDistance: 50, maxDistance: 150 }; |
52 | | - } else { |
53 | | - // fill variant specifics |
54 | | - if (base.logic.setup.nodeType === 'PerformanceCenterApproachScriptedSetup') { |
55 | | - base.logic.setup.hole = base.logic.setup.hole || 1; |
56 | | - base.logic.setup.pin = base.logic.setup.pin || 1; |
57 | | - base.logic.setup.playerCategory = base.logic.setup.playerCategory || 'Handicap'; |
58 | | - base.logic.setup.hcp = base.logic.setup.hcp ?? 10; |
59 | | - base.logic.setup.gender = base.logic.setup.gender || 'Unspecified'; |
60 | | - base.logic.setup.minDistance = base.logic.setup.minDistance ?? 50; |
61 | | - base.logic.setup.maxDistance = base.logic.setup.maxDistance ?? 150; |
62 | | - } else { |
63 | | - base.logic.setup.hole = base.logic.setup.hole || 1; |
64 | | - base.logic.setup.playerCategory = base.logic.setup.playerCategory || 'Handicap'; |
65 | | - base.logic.setup.hcp = base.logic.setup.hcp ?? 10; |
66 | | - base.logic.setup.gender = base.logic.setup.gender || 'Unspecified'; |
67 | | - base.logic.setup.courseDistance = base.logic.setup.courseDistance ?? 6000; |
68 | | - } |
69 | | - } |
70 | | - } |
71 | | - } |
72 | | - // Ensure at least one condition in success/fail when arrays exist |
73 | | - const ensureConditions = (grp: any) => { |
74 | | - if (!grp) return grp; |
75 | | - if (!Array.isArray(grp.conditions) || grp.conditions.length === 0) { |
76 | | - grp.conditions = [{ parameter: 'Total', min: 0 }]; |
77 | | - } |
78 | | - grp.nodeType = grp.nodeType || (stepType === 'RangeAnalysisScriptedStep' ? 'RangeAnalysisScriptedConditions' : 'PerformanceCenterScriptedConditions'); |
79 | | - grp.shots = grp.shots || 1; |
80 | | - grp.conditionType = grp.conditionType || 'And'; |
81 | | - return grp; |
82 | | - }; |
83 | | - base.logic.successCondition = ensureConditions(base.logic.successCondition); |
84 | | - base.logic.failCondition = ensureConditions(base.logic.failCondition); |
85 | | - } |
86 | | - if (raw.ui) { |
87 | | - base.ui = { ...base.ui, ...raw.ui }; |
88 | | - } |
89 | | - return base; |
| 9 | +export function normalizeStep(raw: any, parentActivityType: string): ScriptedStep { |
| 10 | + return raw as ScriptedStep; |
90 | 11 | } |
91 | 12 |
|
92 | 13 | export function normalizeScript(raw: any): ScriptData { |
93 | | - const activities = Array.isArray(raw.activities) ? raw.activities.map((a: any) => normalizeActivity(a)) : []; |
94 | | - |
95 | | - // Build script object with explicit property order |
96 | | - const orderedResult: any = {}; |
97 | | - |
98 | | - // Force property order: id, startMode, endMode, activities |
99 | | - if (raw.id !== undefined && raw.id !== '') { |
100 | | - orderedResult.id = raw.id; |
101 | | - } |
102 | | - if (raw.startMode !== undefined) { |
103 | | - orderedResult.startMode = raw.startMode; |
104 | | - } |
105 | | - if (raw.endMode !== undefined) { |
106 | | - orderedResult.endMode = raw.endMode; |
107 | | - } |
108 | | - |
109 | | - // Always include activities (required property) last |
110 | | - orderedResult.activities = activities; |
111 | | - |
112 | | - // Ensure clean object with proper property order |
113 | | - return JSON.parse(JSON.stringify(orderedResult)) as ScriptData; |
| 14 | + return raw as ScriptData; |
114 | 15 | } |
0 commit comments