@surveystudio/node-registery 1.1.0 → 1.3.0
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.
- package/README.md +8 -1
- package/dist/builder.d.mts +4 -4
- package/dist/{coreTypes-YSpR0Oyh.d.mts → coreTypes-CyFAym5A.d.mts} +1 -1
- package/dist/logic.d.mts +106 -4
- package/dist/logic.mjs +445 -12
- package/dist/runner.d.mts +2 -2
- package/dist/{types-CgiAR_DF.d.mts → types-4zXsOMLb.d.mts} +1 -1
- package/dist/{types-CjF8-OZi.d.mts → types-BMnck1ag.d.mts} +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Typed survey question node registry with separate entrypoints for pure logic, runner UI, and builder UI.
|
|
4
4
|
|
|
5
|
-
This package is currently in early migration. It exports
|
|
5
|
+
This package is currently in early migration. It exports migrated node logic for server runtimes and selected builder/runner UI adapters while the remaining SurveyChamp question nodes are being moved into the registry.
|
|
6
6
|
|
|
7
7
|
## Entrypoints
|
|
8
8
|
|
|
@@ -38,6 +38,13 @@ Migrated nodes:
|
|
|
38
38
|
- `dateInput`
|
|
39
39
|
- `multiInput`
|
|
40
40
|
- `zipCodeInput`
|
|
41
|
+
- `singleChoice` logic
|
|
42
|
+
- `multipleChoice` logic
|
|
43
|
+
- `dropdown` logic
|
|
44
|
+
- `ranking` logic
|
|
45
|
+
- `rating` logic
|
|
46
|
+
- `slider` logic
|
|
47
|
+
- `consent` logic
|
|
41
48
|
- `plainText`
|
|
42
49
|
|
|
43
50
|
The registry contract test intentionally fails until all planned question nodes are migrated.
|
package/dist/builder.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { B as BuilderRegistry, C as CompleteBuilderRegistry, N as NodeBuilder, a as NodeBuilderProps, b as NodeCanvasProps, Q as QuestionNodeDefinition, d as defineBuilderRegistry, c as defineQuestionNode } from './types-
|
|
2
|
-
import { J as JsonValue } from './coreTypes-
|
|
3
|
-
export { N as NodeManifest, P as PropertyField, a as PropertyFieldType, S as SelectOption } from './coreTypes-
|
|
4
|
-
import { P as PlainTextData, B as BaseTextData, M as MultiInputData, N as NumberInputData, T as TextInputData, Z as ZipCodeInputData } from './types-
|
|
1
|
+
export { B as BuilderRegistry, C as CompleteBuilderRegistry, N as NodeBuilder, a as NodeBuilderProps, b as NodeCanvasProps, Q as QuestionNodeDefinition, d as defineBuilderRegistry, c as defineQuestionNode } from './types-4zXsOMLb.mjs';
|
|
2
|
+
import { J as JsonValue } from './coreTypes-CyFAym5A.mjs';
|
|
3
|
+
export { N as NodeManifest, P as PropertyField, a as PropertyFieldType, S as SelectOption } from './coreTypes-CyFAym5A.mjs';
|
|
4
|
+
import { P as PlainTextData, B as BaseTextData, M as MultiInputData, N as NumberInputData, T as TextInputData, Z as ZipCodeInputData } from './types-BMnck1ag.mjs';
|
|
5
5
|
import 'react';
|
|
6
6
|
|
|
7
7
|
declare const plainTextBuilder: {
|
|
@@ -82,4 +82,4 @@ type RegistryKeySet = Readonly<Partial<Record<SurveyNodeType, unknown>>>;
|
|
|
82
82
|
declare function defineLogicRegistry<const TRegistry extends RegistryKeySet>(registry: TRegistry): TRegistry;
|
|
83
83
|
declare function createInitialData<TData extends NodeData>(manifest: NodeManifest<SurveyNodeType, TData>): TData;
|
|
84
84
|
|
|
85
|
-
export { type CompleteLogicRegistry as C, type DataType as D, type ExtractedValue as E, type JsonValue as J, type LogicRegistry as L, type NodeManifest as N, type PropertyField as P, type QuestionNodeType as Q, type SelectOption as S, type ValidationContext as V, type PropertyFieldType as a, type
|
|
85
|
+
export { type CompleteLogicRegistry as C, type DataType as D, type ExtractedValue as E, type JsonValue as J, type LogicRegistry as L, type NodeManifest as N, type PropertyField as P, type QuestionNodeType as Q, type SelectOption as S, type ValidationContext as V, type PropertyFieldType as a, type NodeData as b, type NodeLogic as c, type ExtractionContext as d, type NodeLogicContext as e, type ValidationResult as f, createInitialData as g, defineLogicRegistry as h, type SurveyNodeType as i, type NodeValue as j };
|
package/dist/logic.d.mts
CHANGED
|
@@ -1,9 +1,104 @@
|
|
|
1
|
-
import { P as PlainTextData, a as PlainTextValue, D as DateInputData, b as TextValue, E as EmailInputData, M as MultiInputData, c as MultiInputValue, N as NumberInputData, T as TextInputData, Z as ZipCodeInputData, B as BaseTextData } from './types-
|
|
2
|
-
import { b as NodeLogic } from './coreTypes-
|
|
3
|
-
export { C as CompleteLogicRegistry, D as DataType, E as ExtractedValue,
|
|
1
|
+
import { P as PlainTextData, a as PlainTextValue, D as DateInputData, b as TextValue, E as EmailInputData, M as MultiInputData, c as MultiInputValue, N as NumberInputData, T as TextInputData, Z as ZipCodeInputData, B as BaseTextData } from './types-BMnck1ag.mjs';
|
|
2
|
+
import { b as NodeData, J as JsonValue, c as NodeLogic } from './coreTypes-CyFAym5A.mjs';
|
|
3
|
+
export { C as CompleteLogicRegistry, D as DataType, E as ExtractedValue, d as ExtractionContext, L as LogicRegistry, e as NodeLogicContext, V as ValidationContext, f as ValidationResult, g as createInitialData, h as defineLogicRegistry } from './coreTypes-CyFAym5A.mjs';
|
|
4
|
+
|
|
5
|
+
type ConditionData$2 = {
|
|
6
|
+
id: string;
|
|
7
|
+
type: "group";
|
|
8
|
+
logicType: "AND" | "OR";
|
|
9
|
+
children: JsonValue[];
|
|
10
|
+
};
|
|
11
|
+
type ConsentData = NodeData & {
|
|
12
|
+
label: string;
|
|
13
|
+
description: string;
|
|
14
|
+
condition: ConditionData$2;
|
|
15
|
+
checkboxLabel: string;
|
|
16
|
+
disagreeLabel?: string;
|
|
17
|
+
};
|
|
18
|
+
type ConsentValue = boolean;
|
|
19
|
+
|
|
20
|
+
type ConditionData$1 = {
|
|
21
|
+
id: string;
|
|
22
|
+
type: "group";
|
|
23
|
+
logicType: "AND" | "OR";
|
|
24
|
+
children: JsonValue[];
|
|
25
|
+
};
|
|
26
|
+
type ScaleItem = NodeData & {
|
|
27
|
+
id?: string;
|
|
28
|
+
exportId?: string;
|
|
29
|
+
technicalId?: string;
|
|
30
|
+
label?: string;
|
|
31
|
+
value?: string;
|
|
32
|
+
};
|
|
33
|
+
type ScaleResponseMode = "single" | "multi";
|
|
34
|
+
type BaseScaleData = NodeData & {
|
|
35
|
+
label: string;
|
|
36
|
+
description: string;
|
|
37
|
+
condition: ConditionData$1;
|
|
38
|
+
responseMode?: ScaleResponseMode;
|
|
39
|
+
items: ScaleItem[];
|
|
40
|
+
};
|
|
41
|
+
type RatingData = BaseScaleData & {
|
|
42
|
+
maxRating: number;
|
|
43
|
+
};
|
|
44
|
+
type SliderData = BaseScaleData & {
|
|
45
|
+
min: number;
|
|
46
|
+
max: number;
|
|
47
|
+
step: number;
|
|
48
|
+
startValue: number;
|
|
49
|
+
};
|
|
50
|
+
type ScaleValue = number | Record<string, number>;
|
|
51
|
+
|
|
52
|
+
type ConditionData = {
|
|
53
|
+
id: string;
|
|
54
|
+
type: "group";
|
|
55
|
+
logicType: "AND" | "OR";
|
|
56
|
+
children: JsonValue[];
|
|
57
|
+
};
|
|
58
|
+
type ChoiceOption = NodeData & {
|
|
59
|
+
id?: string;
|
|
60
|
+
label: string;
|
|
61
|
+
value: string;
|
|
62
|
+
imageUrl?: string;
|
|
63
|
+
};
|
|
64
|
+
type BaseChoiceData = NodeData & {
|
|
65
|
+
label: string;
|
|
66
|
+
description: string;
|
|
67
|
+
condition: ConditionData;
|
|
68
|
+
options: ChoiceOption[];
|
|
69
|
+
randomizeOptions?: boolean;
|
|
70
|
+
};
|
|
71
|
+
type SingleChoiceData = BaseChoiceData & {
|
|
72
|
+
allowOther?: boolean;
|
|
73
|
+
otherLabel?: string;
|
|
74
|
+
};
|
|
75
|
+
type DropdownData = BaseChoiceData & {
|
|
76
|
+
searchable?: boolean;
|
|
77
|
+
};
|
|
78
|
+
type MultipleChoiceData = BaseChoiceData & {
|
|
79
|
+
minChoices?: number;
|
|
80
|
+
maxChoices?: number;
|
|
81
|
+
};
|
|
82
|
+
type RankingData = BaseChoiceData & {
|
|
83
|
+
maxRank?: number;
|
|
84
|
+
displayMode?: "drag" | "select";
|
|
85
|
+
};
|
|
86
|
+
type SingleChoiceValue = string;
|
|
87
|
+
type MultipleChoiceValue = string[];
|
|
88
|
+
type RankingValue = string[];
|
|
4
89
|
|
|
5
90
|
declare const plainTextLogic: NodeLogic<"plainText", PlainTextData, PlainTextValue>;
|
|
6
91
|
|
|
92
|
+
declare const consentLogic: NodeLogic<"consent", ConsentData, ConsentValue>;
|
|
93
|
+
|
|
94
|
+
declare const ratingLogic: NodeLogic<"rating", RatingData, ScaleValue>;
|
|
95
|
+
declare const sliderLogic: NodeLogic<"slider", SliderData, ScaleValue>;
|
|
96
|
+
|
|
97
|
+
declare const singleChoiceLogic: NodeLogic<"singleChoice", SingleChoiceData, SingleChoiceValue>;
|
|
98
|
+
declare const dropdownLogic: NodeLogic<"dropdown", DropdownData, SingleChoiceValue>;
|
|
99
|
+
declare const multipleChoiceLogic: NodeLogic<"multipleChoice", MultipleChoiceData, MultipleChoiceValue>;
|
|
100
|
+
declare const rankingLogic: NodeLogic<"ranking", RankingData, RankingValue>;
|
|
101
|
+
|
|
7
102
|
declare const textInputLogic: NodeLogic<"textInput", TextInputData, TextValue>;
|
|
8
103
|
declare const emailInputLogic: NodeLogic<"emailInput", EmailInputData, TextValue>;
|
|
9
104
|
declare const dateInputLogic: NodeLogic<"dateInput", DateInputData, TextValue>;
|
|
@@ -18,7 +113,14 @@ declare const logicRegistry: {
|
|
|
18
113
|
readonly dateInput: NodeLogic<"dateInput", BaseTextData, string>;
|
|
19
114
|
readonly multiInput: NodeLogic<"multiInput", MultiInputData, MultiInputValue>;
|
|
20
115
|
readonly zipCodeInput: NodeLogic<"zipCodeInput", ZipCodeInputData, string>;
|
|
116
|
+
readonly singleChoice: NodeLogic<"singleChoice", SingleChoiceData, string>;
|
|
117
|
+
readonly multipleChoice: NodeLogic<"multipleChoice", MultipleChoiceData, MultipleChoiceValue>;
|
|
118
|
+
readonly dropdown: NodeLogic<"dropdown", DropdownData, string>;
|
|
119
|
+
readonly ranking: NodeLogic<"ranking", RankingData, RankingValue>;
|
|
120
|
+
readonly rating: NodeLogic<"rating", RatingData, ScaleValue>;
|
|
121
|
+
readonly slider: NodeLogic<"slider", SliderData, ScaleValue>;
|
|
122
|
+
readonly consent: NodeLogic<"consent", ConsentData, boolean>;
|
|
21
123
|
readonly plainText: NodeLogic<"plainText", PlainTextData, PlainTextValue>;
|
|
22
124
|
};
|
|
23
125
|
|
|
24
|
-
export { NodeLogic, dateInputLogic, emailInputLogic, logicRegistry, multiInputLogic, numberInputLogic, plainTextLogic, textInputLogic, zipCodeInputLogic };
|
|
126
|
+
export { NodeLogic, consentLogic, dateInputLogic, dropdownLogic, emailInputLogic, logicRegistry, multiInputLogic, multipleChoiceLogic, numberInputLogic, plainTextLogic, rankingLogic, ratingLogic, singleChoiceLogic, sliderLogic, textInputLogic, zipCodeInputLogic };
|
package/dist/logic.mjs
CHANGED
|
@@ -67,30 +67,449 @@ var plainTextLogic = {
|
|
|
67
67
|
]
|
|
68
68
|
};
|
|
69
69
|
|
|
70
|
-
// src/nodes/
|
|
70
|
+
// src/nodes/consent/manifest.ts
|
|
71
71
|
var defaultCondition = {
|
|
72
72
|
id: "root",
|
|
73
73
|
type: "group",
|
|
74
74
|
logicType: "AND",
|
|
75
75
|
children: []
|
|
76
76
|
};
|
|
77
|
+
var consentDefaultData = {
|
|
78
|
+
label: "Consent",
|
|
79
|
+
description: "I agree to the terms and conditions.",
|
|
80
|
+
condition: defaultCondition,
|
|
81
|
+
checkboxLabel: "I agree",
|
|
82
|
+
disagreeLabel: "I do not agree to the terms"
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
// src/nodes/consent/logic.ts
|
|
86
|
+
var normalizeConsentValue = (value) => {
|
|
87
|
+
if (typeof value === "boolean") return value;
|
|
88
|
+
if (typeof value === "string") {
|
|
89
|
+
const normalized = value.trim().toLowerCase();
|
|
90
|
+
if (["true", "yes", "agree", "agreed", "1"].includes(normalized)) return true;
|
|
91
|
+
if (["false", "no", "disagree", "disagreed", "0"].includes(normalized)) return false;
|
|
92
|
+
}
|
|
93
|
+
if (typeof value === "number") return value !== 0;
|
|
94
|
+
return false;
|
|
95
|
+
};
|
|
96
|
+
var consentLogic = {
|
|
97
|
+
type: "consent",
|
|
98
|
+
dataType: "boolean",
|
|
99
|
+
defaultData: consentDefaultData,
|
|
100
|
+
defaultValue: false,
|
|
101
|
+
normalizeValue: normalizeConsentValue,
|
|
102
|
+
validate: () => ({ valid: true }),
|
|
103
|
+
extractValue: (value) => [
|
|
104
|
+
{
|
|
105
|
+
booleanValue: value,
|
|
106
|
+
textValue: value ? "Yes" : "No"
|
|
107
|
+
}
|
|
108
|
+
]
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
// src/nodes/scale/manifest.ts
|
|
112
|
+
var defaultCondition2 = {
|
|
113
|
+
id: "root",
|
|
114
|
+
type: "group",
|
|
115
|
+
logicType: "AND",
|
|
116
|
+
children: []
|
|
117
|
+
};
|
|
118
|
+
var baseScaleData = {
|
|
119
|
+
label: "",
|
|
120
|
+
description: "",
|
|
121
|
+
condition: defaultCondition2,
|
|
122
|
+
responseMode: "single",
|
|
123
|
+
items: []
|
|
124
|
+
};
|
|
125
|
+
var responseModeProperty = {
|
|
126
|
+
name: "responseMode",
|
|
127
|
+
label: "Response Mode",
|
|
128
|
+
type: "select",
|
|
129
|
+
defaultValue: "single",
|
|
130
|
+
options: [
|
|
131
|
+
{ label: "Single Question", value: "single" },
|
|
132
|
+
{ label: "Multiple Items", value: "multi" }
|
|
133
|
+
]
|
|
134
|
+
};
|
|
135
|
+
var commonProperties = [
|
|
136
|
+
responseModeProperty,
|
|
137
|
+
{ name: "label", label: "Question Label", type: "text" },
|
|
138
|
+
{ name: "description", label: "Description", type: "textarea" },
|
|
139
|
+
{
|
|
140
|
+
name: "condition",
|
|
141
|
+
label: "Logic Rule",
|
|
142
|
+
type: "condition",
|
|
143
|
+
defaultValue: defaultCondition2
|
|
144
|
+
},
|
|
145
|
+
{ name: "items", label: "Items", type: "options", defaultValue: [] }
|
|
146
|
+
];
|
|
147
|
+
var ratingDefaultData = {
|
|
148
|
+
...baseScaleData,
|
|
149
|
+
label: "Rating",
|
|
150
|
+
maxRating: 5
|
|
151
|
+
};
|
|
152
|
+
var sliderDefaultData = {
|
|
153
|
+
...baseScaleData,
|
|
154
|
+
label: "Slider / Scale",
|
|
155
|
+
min: 0,
|
|
156
|
+
max: 10,
|
|
157
|
+
step: 1,
|
|
158
|
+
startValue: 5
|
|
159
|
+
};
|
|
160
|
+
var ratingManifest = {
|
|
161
|
+
type: "rating",
|
|
162
|
+
label: "Rating",
|
|
163
|
+
description: "Star rating scale",
|
|
164
|
+
category: "choice",
|
|
165
|
+
dataType: "number",
|
|
166
|
+
defaultData: ratingDefaultData,
|
|
167
|
+
properties: [
|
|
168
|
+
...commonProperties,
|
|
169
|
+
{ name: "maxRating", label: "Max Stars", type: "number", defaultValue: 5 }
|
|
170
|
+
]
|
|
171
|
+
};
|
|
172
|
+
var sliderManifest = {
|
|
173
|
+
type: "slider",
|
|
174
|
+
label: "Slider / Scale",
|
|
175
|
+
description: "Single or multi-item scale",
|
|
176
|
+
category: "choice",
|
|
177
|
+
dataType: "number",
|
|
178
|
+
defaultData: sliderDefaultData,
|
|
179
|
+
properties: [
|
|
180
|
+
...commonProperties,
|
|
181
|
+
{ name: "min", label: "Minimum", type: "number", defaultValue: 0 },
|
|
182
|
+
{ name: "max", label: "Maximum", type: "number", defaultValue: 10 },
|
|
183
|
+
{ name: "step", label: "Step", type: "number", defaultValue: 1, min: 0 },
|
|
184
|
+
{ name: "startValue", label: "Start Value", type: "number", defaultValue: 5 }
|
|
185
|
+
]
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
// src/nodes/scale/logic.ts
|
|
189
|
+
var isRecord = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
190
|
+
var numberValue = (value) => {
|
|
191
|
+
const parsed = Number(value);
|
|
192
|
+
return Number.isFinite(parsed) ? parsed : 0;
|
|
193
|
+
};
|
|
194
|
+
var positiveNumber = (value) => {
|
|
195
|
+
const parsed = Number(value);
|
|
196
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
|
|
197
|
+
};
|
|
198
|
+
var itemsFor = (nodeData) => Array.isArray(nodeData.items) ? nodeData.items : [];
|
|
199
|
+
var inferMode = (nodeData) => {
|
|
200
|
+
if (nodeData.responseMode === "single" || nodeData.responseMode === "multi") return nodeData.responseMode;
|
|
201
|
+
return itemsFor(nodeData).length > 0 ? "multi" : "single";
|
|
202
|
+
};
|
|
203
|
+
var itemKey = (item) => item.exportId || item.technicalId || item.value || item.id;
|
|
204
|
+
var itemLabel = (item, fallback) => item.label || fallback;
|
|
205
|
+
var firstItemKey = (nodeData) => {
|
|
206
|
+
const firstItem = itemsFor(nodeData)[0];
|
|
207
|
+
return firstItem ? itemKey(firstItem) : void 0;
|
|
208
|
+
};
|
|
209
|
+
var normalizeScaleValue = (rawValue, nodeData) => {
|
|
210
|
+
const mode = inferMode(nodeData);
|
|
211
|
+
if (mode === "multi") {
|
|
212
|
+
if (isRecord(rawValue)) {
|
|
213
|
+
return Object.fromEntries(Object.entries(rawValue).map(([key2, value]) => [key2, numberValue(value)]));
|
|
214
|
+
}
|
|
215
|
+
const key = firstItemKey(nodeData);
|
|
216
|
+
if (key) return { [key]: numberValue(rawValue) };
|
|
217
|
+
}
|
|
218
|
+
return numberValue(rawValue);
|
|
219
|
+
};
|
|
220
|
+
var validateFiniteScale = (value) => {
|
|
221
|
+
if (typeof value === "number") return Number.isFinite(value) ? { valid: true } : { valid: false, error: "Please enter a valid number" };
|
|
222
|
+
const invalidKey = Object.entries(value).find(([, itemValue]) => !Number.isFinite(itemValue))?.[0];
|
|
223
|
+
return invalidKey ? { valid: false, error: `${invalidKey}: Please enter a valid number` } : { valid: true };
|
|
224
|
+
};
|
|
225
|
+
var validateRatingValue = (value, nodeData) => {
|
|
226
|
+
const finiteResult = validateFiniteScale(value);
|
|
227
|
+
if (!finiteResult.valid) return finiteResult;
|
|
228
|
+
const maxRating = positiveNumber(nodeData.maxRating) || 5;
|
|
229
|
+
const values = typeof value === "number" ? [value] : Object.values(value);
|
|
230
|
+
const outOfRange = values.find((itemValue) => itemValue < 1 || itemValue > maxRating);
|
|
231
|
+
return typeof outOfRange === "number" ? { valid: false, error: `Rating must be between 1 and ${maxRating}` } : { valid: true };
|
|
232
|
+
};
|
|
233
|
+
var validateSliderValue = (value, nodeData) => {
|
|
234
|
+
const finiteResult = validateFiniteScale(value);
|
|
235
|
+
if (!finiteResult.valid) return finiteResult;
|
|
236
|
+
const min = numberValue(nodeData.min);
|
|
237
|
+
const max = Number.isFinite(Number(nodeData.max)) ? Number(nodeData.max) : 10;
|
|
238
|
+
const values = typeof value === "number" ? [value] : Object.values(value);
|
|
239
|
+
const outOfRange = values.find((itemValue) => itemValue < min || itemValue > max);
|
|
240
|
+
return typeof outOfRange === "number" ? { valid: false, error: `Value must be between ${min} and ${max}` } : { valid: true };
|
|
241
|
+
};
|
|
242
|
+
var extractScaleValue = (value, nodeData) => {
|
|
243
|
+
const mode = inferMode(nodeData);
|
|
244
|
+
if (mode === "multi" && isRecord(value)) {
|
|
245
|
+
const items = itemsFor(nodeData);
|
|
246
|
+
return Object.entries(value).map(([key, itemValue]) => {
|
|
247
|
+
const item = items.find((candidate) => itemKey(candidate) === key);
|
|
248
|
+
return {
|
|
249
|
+
columnKey: key,
|
|
250
|
+
columnLabel: item ? itemLabel(item, key) : key,
|
|
251
|
+
numberValue: itemValue,
|
|
252
|
+
textValue: String(itemValue)
|
|
253
|
+
};
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
const scalarValue = typeof value === "number" ? value : 0;
|
|
257
|
+
return [{ numberValue: scalarValue, textValue: String(scalarValue) }];
|
|
258
|
+
};
|
|
259
|
+
var ratingLogic = {
|
|
260
|
+
type: "rating",
|
|
261
|
+
dataType: "number",
|
|
262
|
+
defaultData: ratingDefaultData,
|
|
263
|
+
defaultValue: 0,
|
|
264
|
+
normalizeValue: normalizeScaleValue,
|
|
265
|
+
validate: validateRatingValue,
|
|
266
|
+
extractValue: extractScaleValue
|
|
267
|
+
};
|
|
268
|
+
var sliderLogic = {
|
|
269
|
+
type: "slider",
|
|
270
|
+
dataType: "number",
|
|
271
|
+
defaultData: sliderDefaultData,
|
|
272
|
+
defaultValue: 0,
|
|
273
|
+
normalizeValue: normalizeScaleValue,
|
|
274
|
+
validate: validateSliderValue,
|
|
275
|
+
extractValue: extractScaleValue
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
// src/nodes/choice/manifest.ts
|
|
279
|
+
var defaultCondition3 = {
|
|
280
|
+
id: "root",
|
|
281
|
+
type: "group",
|
|
282
|
+
logicType: "AND",
|
|
283
|
+
children: []
|
|
284
|
+
};
|
|
285
|
+
var baseChoiceData = {
|
|
286
|
+
label: "",
|
|
287
|
+
description: "",
|
|
288
|
+
condition: defaultCondition3,
|
|
289
|
+
options: [],
|
|
290
|
+
randomizeOptions: false
|
|
291
|
+
};
|
|
292
|
+
var commonProperties2 = [
|
|
293
|
+
{ name: "label", label: "Question Label", type: "text" },
|
|
294
|
+
{ name: "description", label: "Description", type: "textarea" },
|
|
295
|
+
{
|
|
296
|
+
name: "condition",
|
|
297
|
+
label: "Logic Rule",
|
|
298
|
+
type: "condition",
|
|
299
|
+
defaultValue: defaultCondition3
|
|
300
|
+
},
|
|
301
|
+
{ name: "options", label: "Options", type: "options", defaultValue: [] },
|
|
302
|
+
{ name: "bulkOptions", label: "Bulk Add (one per line)", type: "textarea", placeholder: "Option A\nOption B\nOption C..." }
|
|
303
|
+
];
|
|
304
|
+
var singleChoiceDefaultData = {
|
|
305
|
+
...baseChoiceData,
|
|
306
|
+
label: "Single Choice",
|
|
307
|
+
allowOther: false,
|
|
308
|
+
otherLabel: "Other"
|
|
309
|
+
};
|
|
310
|
+
var dropdownDefaultData = {
|
|
311
|
+
...baseChoiceData,
|
|
312
|
+
label: "Dropdown",
|
|
313
|
+
searchable: true
|
|
314
|
+
};
|
|
315
|
+
var multipleChoiceDefaultData = {
|
|
316
|
+
...baseChoiceData,
|
|
317
|
+
label: "Multiple Choice",
|
|
318
|
+
minChoices: 0,
|
|
319
|
+
maxChoices: 0
|
|
320
|
+
};
|
|
321
|
+
var rankingDefaultData = {
|
|
322
|
+
...baseChoiceData,
|
|
323
|
+
label: "Ranking",
|
|
324
|
+
maxRank: 0,
|
|
325
|
+
displayMode: "drag"
|
|
326
|
+
};
|
|
327
|
+
var singleChoiceManifest = {
|
|
328
|
+
type: "singleChoice",
|
|
329
|
+
label: "Single Choice",
|
|
330
|
+
description: "Select one option",
|
|
331
|
+
category: "choice",
|
|
332
|
+
dataType: "option",
|
|
333
|
+
defaultData: singleChoiceDefaultData,
|
|
334
|
+
properties: [
|
|
335
|
+
...commonProperties2,
|
|
336
|
+
{ name: "allowOther", label: "Allow Other", type: "switch", defaultValue: false },
|
|
337
|
+
{ name: "otherLabel", label: "Other Label", type: "text", defaultValue: "Other" },
|
|
338
|
+
{ name: "randomizeOptions", label: "Randomize Options", type: "switch", defaultValue: false }
|
|
339
|
+
]
|
|
340
|
+
};
|
|
341
|
+
var dropdownManifest = {
|
|
342
|
+
type: "dropdown",
|
|
343
|
+
label: "Dropdown",
|
|
344
|
+
description: "Select from a dropdown menu",
|
|
345
|
+
category: "choice",
|
|
346
|
+
dataType: "option",
|
|
347
|
+
defaultData: dropdownDefaultData,
|
|
348
|
+
properties: [
|
|
349
|
+
...commonProperties2,
|
|
350
|
+
{ name: "searchable", label: "Searchable", type: "switch", defaultValue: true }
|
|
351
|
+
]
|
|
352
|
+
};
|
|
353
|
+
var multipleChoiceManifest = {
|
|
354
|
+
type: "multipleChoice",
|
|
355
|
+
label: "Multiple Choice",
|
|
356
|
+
description: "Select multiple options",
|
|
357
|
+
category: "choice",
|
|
358
|
+
dataType: "array",
|
|
359
|
+
defaultData: multipleChoiceDefaultData,
|
|
360
|
+
properties: [
|
|
361
|
+
...commonProperties2,
|
|
362
|
+
{ name: "minChoices", label: "Minimum Choices", type: "number", defaultValue: 0 },
|
|
363
|
+
{ name: "maxChoices", label: "Maximum Choices", type: "number", defaultValue: 0 },
|
|
364
|
+
{ name: "randomizeOptions", label: "Randomize Options", type: "switch", defaultValue: false }
|
|
365
|
+
]
|
|
366
|
+
};
|
|
367
|
+
var rankingManifest = {
|
|
368
|
+
type: "ranking",
|
|
369
|
+
label: "Ranking",
|
|
370
|
+
description: "Rank options in order",
|
|
371
|
+
category: "choice",
|
|
372
|
+
dataType: "array",
|
|
373
|
+
defaultData: rankingDefaultData,
|
|
374
|
+
properties: [
|
|
375
|
+
...commonProperties2,
|
|
376
|
+
{ name: "maxRank", label: "Maximum Rank", type: "number", defaultValue: 0 },
|
|
377
|
+
{
|
|
378
|
+
name: "displayMode",
|
|
379
|
+
label: "Display Mode",
|
|
380
|
+
type: "select",
|
|
381
|
+
defaultValue: "drag",
|
|
382
|
+
options: [
|
|
383
|
+
{ label: "Drag and Drop", value: "drag" },
|
|
384
|
+
{ label: "Dropdown Selection", value: "select" }
|
|
385
|
+
]
|
|
386
|
+
}
|
|
387
|
+
]
|
|
388
|
+
};
|
|
389
|
+
|
|
390
|
+
// src/nodes/choice/logic.ts
|
|
391
|
+
var normalizeChoiceValue = (value) => {
|
|
392
|
+
if (typeof value === "string") return value;
|
|
393
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
394
|
+
return "";
|
|
395
|
+
};
|
|
396
|
+
var normalizeChoiceArray = (value) => {
|
|
397
|
+
if (!Array.isArray(value)) return [];
|
|
398
|
+
return value.map(normalizeChoiceValue).filter(Boolean);
|
|
399
|
+
};
|
|
400
|
+
var positiveNumber2 = (value) => {
|
|
401
|
+
const parsed = Number(value);
|
|
402
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
|
|
403
|
+
};
|
|
404
|
+
var optionsFor = (nodeData) => Array.isArray(nodeData.options) ? nodeData.options : [];
|
|
405
|
+
var optionForValue = (nodeData, value) => optionsFor(nodeData).find((option) => option.value === value || option.id === value);
|
|
406
|
+
var optionLabel = (nodeData, value) => optionForValue(nodeData, value)?.label || value;
|
|
407
|
+
var optionUuid = (nodeData, value) => optionForValue(nodeData, value)?.value || value;
|
|
408
|
+
var validateOptionExists = (value, nodeData) => {
|
|
409
|
+
if (!value) return { valid: true };
|
|
410
|
+
if (optionsFor(nodeData).length === 0) return { valid: true };
|
|
411
|
+
return optionForValue(nodeData, value) ? { valid: true } : { valid: false, error: "Selected option is not available" };
|
|
412
|
+
};
|
|
413
|
+
var validateOptionArray = (value, nodeData) => {
|
|
414
|
+
if (optionsFor(nodeData).length === 0) return { valid: true };
|
|
415
|
+
const invalid = value.find((item) => !optionForValue(nodeData, item));
|
|
416
|
+
return invalid ? { valid: false, error: "Selected option is not available" } : { valid: true };
|
|
417
|
+
};
|
|
418
|
+
var extractSingleChoiceValue = (value, nodeData) => [
|
|
419
|
+
{
|
|
420
|
+
optionUuid: optionUuid(nodeData, value),
|
|
421
|
+
optionText: optionLabel(nodeData, value),
|
|
422
|
+
textValue: optionLabel(nodeData, value)
|
|
423
|
+
}
|
|
424
|
+
];
|
|
425
|
+
var singleChoiceLogic = {
|
|
426
|
+
type: "singleChoice",
|
|
427
|
+
dataType: "option",
|
|
428
|
+
defaultData: singleChoiceDefaultData,
|
|
429
|
+
defaultValue: "",
|
|
430
|
+
normalizeValue: normalizeChoiceValue,
|
|
431
|
+
validate: validateOptionExists,
|
|
432
|
+
extractValue: extractSingleChoiceValue
|
|
433
|
+
};
|
|
434
|
+
var dropdownLogic = {
|
|
435
|
+
type: "dropdown",
|
|
436
|
+
dataType: "option",
|
|
437
|
+
defaultData: dropdownDefaultData,
|
|
438
|
+
defaultValue: "",
|
|
439
|
+
normalizeValue: normalizeChoiceValue,
|
|
440
|
+
validate: validateOptionExists,
|
|
441
|
+
extractValue: extractSingleChoiceValue
|
|
442
|
+
};
|
|
443
|
+
var multipleChoiceLogic = {
|
|
444
|
+
type: "multipleChoice",
|
|
445
|
+
dataType: "array",
|
|
446
|
+
defaultData: multipleChoiceDefaultData,
|
|
447
|
+
defaultValue: [],
|
|
448
|
+
normalizeValue: normalizeChoiceArray,
|
|
449
|
+
validate: (value, nodeData) => {
|
|
450
|
+
const optionResult = validateOptionArray(value, nodeData);
|
|
451
|
+
if (!optionResult.valid) return optionResult;
|
|
452
|
+
const minChoices = positiveNumber2(nodeData.minChoices);
|
|
453
|
+
const maxChoices = positiveNumber2(nodeData.maxChoices);
|
|
454
|
+
if (minChoices && value.length < minChoices) return { valid: false, error: `Select at least ${minChoices} option(s)` };
|
|
455
|
+
if (maxChoices && value.length > maxChoices) return { valid: false, error: `Select at most ${maxChoices} option(s)` };
|
|
456
|
+
return { valid: true };
|
|
457
|
+
},
|
|
458
|
+
extractValue: (value, nodeData) => value.map((item) => ({
|
|
459
|
+
optionUuid: optionUuid(nodeData, item),
|
|
460
|
+
optionText: optionLabel(nodeData, item),
|
|
461
|
+
textValue: optionLabel(nodeData, item)
|
|
462
|
+
}))
|
|
463
|
+
};
|
|
464
|
+
var rankingLogic = {
|
|
465
|
+
type: "ranking",
|
|
466
|
+
dataType: "array",
|
|
467
|
+
defaultData: rankingDefaultData,
|
|
468
|
+
defaultValue: [],
|
|
469
|
+
normalizeValue: normalizeChoiceArray,
|
|
470
|
+
validate: (value, nodeData) => {
|
|
471
|
+
const optionResult = validateOptionArray(value, nodeData);
|
|
472
|
+
if (!optionResult.valid) return optionResult;
|
|
473
|
+
const maxRank = positiveNumber2(nodeData.maxRank);
|
|
474
|
+
if (maxRank && value.length > maxRank) return { valid: false, error: `Rank at most ${maxRank} option(s)` };
|
|
475
|
+
return { valid: true };
|
|
476
|
+
},
|
|
477
|
+
extractValue: (value, nodeData) => value.map((item, index) => {
|
|
478
|
+
const rank = index + 1;
|
|
479
|
+
const label = optionLabel(nodeData, item);
|
|
480
|
+
return {
|
|
481
|
+
optionUuid: optionUuid(nodeData, item),
|
|
482
|
+
optionText: label,
|
|
483
|
+
numberValue: rank,
|
|
484
|
+
textValue: `${rank}. ${label}`
|
|
485
|
+
};
|
|
486
|
+
})
|
|
487
|
+
};
|
|
488
|
+
|
|
489
|
+
// src/nodes/textLike/manifest.ts
|
|
490
|
+
var defaultCondition4 = {
|
|
491
|
+
id: "root",
|
|
492
|
+
type: "group",
|
|
493
|
+
logicType: "AND",
|
|
494
|
+
children: []
|
|
495
|
+
};
|
|
77
496
|
var baseTextData = {
|
|
78
497
|
label: "",
|
|
79
498
|
description: "",
|
|
80
|
-
condition:
|
|
499
|
+
condition: defaultCondition4,
|
|
81
500
|
minChars: 0,
|
|
82
501
|
maxChars: 0,
|
|
83
502
|
minWords: 0,
|
|
84
503
|
maxWords: 0
|
|
85
504
|
};
|
|
86
|
-
var
|
|
505
|
+
var commonProperties3 = [
|
|
87
506
|
{ name: "label", label: "Field Label", type: "text" },
|
|
88
507
|
{ name: "description", label: "Description", type: "textarea" },
|
|
89
508
|
{
|
|
90
509
|
name: "condition",
|
|
91
510
|
label: "Logic Rule",
|
|
92
511
|
type: "condition",
|
|
93
|
-
defaultValue:
|
|
512
|
+
defaultValue: defaultCondition4
|
|
94
513
|
}
|
|
95
514
|
];
|
|
96
515
|
var textLimitProperties = [
|
|
@@ -129,7 +548,7 @@ var textInputManifest = {
|
|
|
129
548
|
dataType: "text",
|
|
130
549
|
defaultData: textInputDefaultData,
|
|
131
550
|
properties: [
|
|
132
|
-
...
|
|
551
|
+
...commonProperties3,
|
|
133
552
|
{ name: "placeholder", label: "Placeholder", type: "text", placeholder: "e.g., Type here...", defaultValue: "" },
|
|
134
553
|
{ name: "longAnswer", label: "Long Answer (Multi-line)", type: "switch", defaultValue: false },
|
|
135
554
|
...textLimitProperties
|
|
@@ -143,7 +562,7 @@ var numberInputManifest = {
|
|
|
143
562
|
dataType: "number",
|
|
144
563
|
defaultData: numberInputDefaultData,
|
|
145
564
|
properties: [
|
|
146
|
-
...
|
|
565
|
+
...commonProperties3,
|
|
147
566
|
{ name: "min", label: "Minimum Value", type: "number" },
|
|
148
567
|
{ name: "max", label: "Maximum Value", type: "number" }
|
|
149
568
|
]
|
|
@@ -156,7 +575,7 @@ var zipCodeInputManifest = {
|
|
|
156
575
|
dataType: "text",
|
|
157
576
|
defaultData: zipCodeInputDefaultData,
|
|
158
577
|
properties: [
|
|
159
|
-
...
|
|
578
|
+
...commonProperties3,
|
|
160
579
|
{ name: "allowedZips", label: "Allowed Zip Codes", type: "fileTextarea", placeholder: "10001, 10002, 90210... (Leave empty to allow all)", helperText: "Validation: Only users entering these zip codes can proceed. Others will be blocked." }
|
|
161
580
|
]
|
|
162
581
|
};
|
|
@@ -168,7 +587,7 @@ var multiInputManifest = {
|
|
|
168
587
|
dataType: "object",
|
|
169
588
|
defaultData: multiInputDefaultData,
|
|
170
589
|
properties: [
|
|
171
|
-
...
|
|
590
|
+
...commonProperties3,
|
|
172
591
|
{ name: "fields", label: "Input Fields", type: "options", defaultValue: [], helperText: "Value column represents input type (text, number, email)" },
|
|
173
592
|
...textLimitProperties
|
|
174
593
|
]
|
|
@@ -261,12 +680,12 @@ var numberInputLogic = {
|
|
|
261
680
|
const limitResult = validateTextLimits(value, nodeData);
|
|
262
681
|
if (!limitResult.valid) return limitResult;
|
|
263
682
|
if (!value.trim()) return { valid: true };
|
|
264
|
-
const
|
|
265
|
-
if (Number.isNaN(
|
|
266
|
-
if (typeof nodeData.min === "number" &&
|
|
683
|
+
const numberValue2 = Number(value);
|
|
684
|
+
if (Number.isNaN(numberValue2)) return { valid: false, error: "Please enter a valid number" };
|
|
685
|
+
if (typeof nodeData.min === "number" && numberValue2 < nodeData.min) {
|
|
267
686
|
return { valid: false, error: `Minimum value is ${nodeData.min}` };
|
|
268
687
|
}
|
|
269
|
-
if (typeof nodeData.max === "number" &&
|
|
688
|
+
if (typeof nodeData.max === "number" && numberValue2 > nodeData.max) {
|
|
270
689
|
return { valid: false, error: `Maximum value is ${nodeData.max}` };
|
|
271
690
|
}
|
|
272
691
|
return { valid: true };
|
|
@@ -337,17 +756,31 @@ var logicRegistry = defineLogicRegistry({
|
|
|
337
756
|
dateInput: dateInputLogic,
|
|
338
757
|
multiInput: multiInputLogic,
|
|
339
758
|
zipCodeInput: zipCodeInputLogic,
|
|
759
|
+
singleChoice: singleChoiceLogic,
|
|
760
|
+
multipleChoice: multipleChoiceLogic,
|
|
761
|
+
dropdown: dropdownLogic,
|
|
762
|
+
ranking: rankingLogic,
|
|
763
|
+
rating: ratingLogic,
|
|
764
|
+
slider: sliderLogic,
|
|
765
|
+
consent: consentLogic,
|
|
340
766
|
plainText: plainTextLogic
|
|
341
767
|
});
|
|
342
768
|
export {
|
|
769
|
+
consentLogic,
|
|
343
770
|
createInitialData,
|
|
344
771
|
dateInputLogic,
|
|
345
772
|
defineLogicRegistry,
|
|
773
|
+
dropdownLogic,
|
|
346
774
|
emailInputLogic,
|
|
347
775
|
logicRegistry,
|
|
348
776
|
multiInputLogic,
|
|
777
|
+
multipleChoiceLogic,
|
|
349
778
|
numberInputLogic,
|
|
350
779
|
plainTextLogic,
|
|
780
|
+
rankingLogic,
|
|
781
|
+
ratingLogic,
|
|
782
|
+
singleChoiceLogic,
|
|
783
|
+
sliderLogic,
|
|
351
784
|
textInputLogic,
|
|
352
785
|
zipCodeInputLogic
|
|
353
786
|
};
|
package/dist/runner.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { e as CompleteRunnerRegistry, f as NodeRunner, g as NodeRunnerProps, Q as QuestionNodeDefinition, R as RunnerRegistry, c as defineQuestionNode, h as defineRunnerRegistry } from './types-
|
|
1
|
+
export { e as CompleteRunnerRegistry, f as NodeRunner, g as NodeRunnerProps, Q as QuestionNodeDefinition, R as RunnerRegistry, c as defineQuestionNode, h as defineRunnerRegistry } from './types-4zXsOMLb.mjs';
|
|
2
2
|
import 'react';
|
|
3
|
-
import './coreTypes-
|
|
3
|
+
import './coreTypes-CyFAym5A.mjs';
|
|
4
4
|
|
|
5
5
|
declare const plainTextRunner: {
|
|
6
6
|
type: "plainText";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReactNode, ComponentType } from 'react';
|
|
2
|
-
import { i as SurveyNodeType,
|
|
2
|
+
import { i as SurveyNodeType, b as NodeData, Q as QuestionNodeType, j as NodeValue, N as NodeManifest, c as NodeLogic } from './coreTypes-CyFAym5A.mjs';
|
|
3
3
|
|
|
4
4
|
interface NodeRunnerProps<TData extends NodeData = NodeData, TValue extends NodeValue = NodeValue> {
|
|
5
5
|
readonly data: Readonly<TData>;
|
package/package.json
CHANGED