@conform-to/dom 0.6.1 → 0.6.2

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/index.js CHANGED
@@ -2,433 +2,35 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var _rollupPluginBabelHelpers = require('./_virtual/_rollupPluginBabelHelpers.js');
6
-
7
- /**
8
- * Check if the provided reference is a form element (_input_ / _select_ / _textarea_ or _button_)
9
- */
10
- function isFieldElement(element) {
11
- return element instanceof Element && (element.tagName === 'INPUT' || element.tagName === 'SELECT' || element.tagName === 'TEXTAREA' || element.tagName === 'BUTTON');
12
- }
13
-
14
- /**
15
- * Find the corresponding paths based on the formatted name
16
- * @param name formatted name
17
- * @returns paths
18
- */
19
- function getPaths(name) {
20
- var pattern = /(\w*)\[(\d+)\]/;
21
- if (!name) {
22
- return [];
23
- }
24
- return name.split('.').flatMap(key => {
25
- var matches = pattern.exec(key);
26
- if (!matches) {
27
- return key;
28
- }
29
- if (matches[1] === '') {
30
- return Number(matches[2]);
31
- }
32
- return [matches[1], Number(matches[2])];
33
- });
34
- }
35
- function getFormData(form, submitter) {
36
- var payload = new FormData(form);
37
- if (submitter !== null && submitter !== void 0 && submitter.name) {
38
- payload.append(submitter.name, submitter.value);
39
- }
40
- return payload;
41
- }
42
- function getFormAttributes(form, submitter) {
43
- var _ref, _submitter$getAttribu, _ref2, _submitter$getAttribu2, _submitter$getAttribu3;
44
- var enforce = (value, list) => list.includes(value) ? value : list[0];
45
- var action = (_ref = (_submitter$getAttribu = submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute('formaction')) !== null && _submitter$getAttribu !== void 0 ? _submitter$getAttribu : form.getAttribute('action')) !== null && _ref !== void 0 ? _ref : "".concat(location.pathname).concat(location.search);
46
- var method = (_ref2 = (_submitter$getAttribu2 = submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute('formmethod')) !== null && _submitter$getAttribu2 !== void 0 ? _submitter$getAttribu2 : form.getAttribute('method')) !== null && _ref2 !== void 0 ? _ref2 : 'get';
47
- var encType = (_submitter$getAttribu3 = submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute('formenctype')) !== null && _submitter$getAttribu3 !== void 0 ? _submitter$getAttribu3 : form.enctype;
48
- return {
49
- action,
50
- encType: enforce(encType, ['application/x-www-form-urlencoded', 'multipart/form-data']),
51
- method: enforce(method, ['get', 'post', 'put', 'patch', 'delete'])
52
- };
53
- }
54
- function getName(paths) {
55
- return paths.reduce((name, path) => {
56
- if (typeof path === 'number') {
57
- return "".concat(name, "[").concat(path, "]");
58
- }
59
- if (name === '' || path === '') {
60
- return [name, path].join('');
61
- }
62
- return [name, path].join('.');
63
- }, '');
64
- }
65
- function getScope(intent) {
66
- var _parseListCommand$sco, _parseListCommand;
67
- var [type, ...rest] = intent.split('/');
68
- switch (type) {
69
- case 'validate':
70
- return rest.length > 0 ? rest.join('/') : null;
71
- case 'list':
72
- return (_parseListCommand$sco = (_parseListCommand = parseListCommand(intent)) === null || _parseListCommand === void 0 ? void 0 : _parseListCommand.scope) !== null && _parseListCommand$sco !== void 0 ? _parseListCommand$sco : null;
73
- default:
74
- return null;
75
- }
76
- }
77
- function isFocusedOnIntentButton(form, intent) {
78
- var element = document.activeElement;
79
- return isFieldElement(element) && element.tagName === 'BUTTON' && element.form === form && element.name === INTENT && element.value === intent;
80
- }
81
- function getValidationMessage(errors) {
82
- return [].concat(errors !== null && errors !== void 0 ? errors : []).join(String.fromCharCode(31));
83
- }
84
- function getErrors(message) {
85
- if (!message) {
86
- return [];
87
- }
88
- return message.split(String.fromCharCode(31));
89
- }
90
- var FORM_ERROR_ELEMENT_NAME = '__form__';
91
- var INTENT = '__intent__';
92
- var VALIDATION_UNDEFINED = '__undefined__';
93
- var VALIDATION_SKIPPED = '__skipped__';
94
- function reportSubmission(form, submission) {
95
- for (var [_name, message] of Object.entries(submission.error)) {
96
- // There is no need to create a placeholder button if all we want is to reset the error
97
- if (message === '') {
98
- continue;
99
- }
100
-
101
- // We can't use empty string as button name
102
- // As `form.element.namedItem('')` will always returns null
103
- var elementName = _name ? _name : FORM_ERROR_ELEMENT_NAME;
104
- var item = form.elements.namedItem(elementName);
105
- if (item instanceof RadioNodeList) {
106
- for (var field of item) {
107
- if (field.type !== 'radio') {
108
- console.warn('Repeated field name is not supported.');
109
- continue;
110
- }
111
- }
112
- }
113
- if (item === null) {
114
- // Create placeholder button to keep the error without contributing to the form data
115
- var button = document.createElement('button');
116
- button.name = elementName;
117
- button.hidden = true;
118
- button.dataset.conformTouched = 'true';
119
- form.appendChild(button);
120
- }
121
- }
122
- var focusedFirstInvalidField = false;
123
- var scope = getScope(submission.intent);
124
- var isSubmitting = submission.intent.slice(0, submission.intent.indexOf('/')) !== 'validate' && parseListCommand(submission.intent) === null;
125
- for (var element of form.elements) {
126
- if (isFieldElement(element) && element.willValidate) {
127
- var _submission$error$_el;
128
- var _elementName = element.name !== FORM_ERROR_ELEMENT_NAME ? element.name : '';
129
- var messages = [].concat((_submission$error$_el = submission.error[_elementName]) !== null && _submission$error$_el !== void 0 ? _submission$error$_el : []);
130
- var shouldValidate = scope === null || scope === _elementName;
131
- if (shouldValidate) {
132
- element.dataset.conformTouched = 'true';
133
- }
134
- if (!messages.includes(VALIDATION_SKIPPED) && !messages.includes(VALIDATION_UNDEFINED)) {
135
- var invalidEvent = new Event('invalid', {
136
- cancelable: true
137
- });
138
- element.setCustomValidity(getValidationMessage(messages));
139
- element.dispatchEvent(invalidEvent);
140
- }
141
- if (!focusedFirstInvalidField && (isSubmitting || isFocusedOnIntentButton(form, submission.intent)) && shouldValidate && element.tagName !== 'BUTTON' && !element.validity.valid) {
142
- element.focus();
143
- focusedFirstInvalidField = true;
144
- }
145
- }
146
- }
147
- }
148
- function setValue(target, paths, valueFn) {
149
- var length = paths.length;
150
- var lastIndex = length - 1;
151
- var index = -1;
152
- var pointer = target;
153
- while (pointer != null && ++index < length) {
154
- var _pointer$key;
155
- var key = paths[index];
156
- var next = paths[index + 1];
157
- var newValue = index != lastIndex ? (_pointer$key = pointer[key]) !== null && _pointer$key !== void 0 ? _pointer$key : typeof next === 'number' ? [] : {} : valueFn(pointer[key]);
158
- pointer[key] = newValue;
159
- pointer = pointer[key];
160
- }
161
- }
162
-
163
- /**
164
- * Creates an intent button on demand and trigger a form submit by clicking it.
165
- */
166
- function requestIntent(form, buttonProps) {
167
- if (!form) {
168
- console.warn('No form element is provided');
169
- return;
170
- }
171
- var button = document.createElement('button');
172
- button.name = INTENT;
173
- button.value = buttonProps.value;
174
- button.hidden = true;
175
- if (buttonProps.formNoValidate) {
176
- button.formNoValidate = true;
177
- }
178
- form.appendChild(button);
179
- button.click();
180
- form.removeChild(button);
181
- }
182
-
183
- /**
184
- * Returns the properties required to configure an intent button for validation
185
- *
186
- * @see https://conform.guide/api/react#validate
187
- */
188
- function validate(field) {
189
- return {
190
- name: INTENT,
191
- value: field ? "validate/".concat(field) : 'validate',
192
- formNoValidate: true
193
- };
194
- }
195
- function getFormElement(element) {
196
- var form = element instanceof HTMLFormElement ? element : element === null || element === void 0 ? void 0 : element.form;
197
- if (!form) {
198
- return null;
199
- }
200
- return form;
201
- }
202
- function parse(payload, options) {
203
- var submission = {
204
- intent: 'submit',
205
- payload: {},
206
- error: {}
207
- };
208
- var _loop = function _loop(_value) {
209
- if (_name2 === INTENT) {
210
- if (typeof _value !== 'string' || submission.intent !== 'submit') {
211
- throw new Error('The intent could only be set on a button');
212
- }
213
- submission.intent = _value;
214
- } else {
215
- var _paths = getPaths(_name2);
216
- setValue(submission.payload, _paths, prev => {
217
- if (!prev) {
218
- return _value;
219
- } else if (Array.isArray(prev)) {
220
- return prev.concat(_value);
221
- } else {
222
- return [prev, _value];
223
- }
224
- });
225
- }
226
- };
227
- for (var [_name2, _value] of payload.entries()) {
228
- _loop(_value);
229
- }
230
- var command = parseListCommand(submission.intent);
231
- if (command) {
232
- var paths = getPaths(command.scope);
233
- setValue(submission.payload, paths, list => {
234
- if (typeof list !== 'undefined' && !Array.isArray(list)) {
235
- throw new Error('The list command can only be applied to a list');
236
- }
237
- return updateList(list !== null && list !== void 0 ? list : [], command);
238
- });
239
- }
240
- if (typeof (options === null || options === void 0 ? void 0 : options.resolve) === 'undefined') {
241
- return submission;
242
- }
243
- var result = options.resolve(submission.payload, submission.intent);
244
- var mergeResolveResult = resolved => {
245
- var result = _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, submission), resolved), {}, {
246
- toJSON() {
247
- return {
248
- intent: this.intent,
249
- payload: this.payload,
250
- error: this.error
251
- };
252
- }
253
- });
254
- return result;
255
- };
256
- if (result instanceof Promise) {
257
- return result.then(mergeResolveResult);
258
- }
259
- return mergeResolveResult(result);
260
- }
261
- function parseListCommand(intent) {
262
- try {
263
- var [group, type, scope, json] = intent.split('/');
264
- if (group !== 'list' || !['prepend', 'append', 'replace', 'remove', 'reorder'].includes(type) || !scope) {
265
- return null;
266
- }
267
- var _payload = JSON.parse(json);
268
- return {
269
- // @ts-expect-error
270
- type,
271
- scope,
272
- payload: _payload
273
- };
274
- } catch (error) {
275
- return null;
276
- }
277
- }
278
- function updateList(list, command) {
279
- switch (command.type) {
280
- case 'prepend':
281
- {
282
- list.unshift(command.payload.defaultValue);
283
- break;
284
- }
285
- case 'append':
286
- {
287
- list.push(command.payload.defaultValue);
288
- break;
289
- }
290
- case 'replace':
291
- {
292
- list.splice(command.payload.index, 1, command.payload.defaultValue);
293
- break;
294
- }
295
- case 'remove':
296
- list.splice(command.payload.index, 1);
297
- break;
298
- case 'reorder':
299
- list.splice(command.payload.to, 0, ...list.splice(command.payload.from, 1));
300
- break;
301
- default:
302
- throw new Error('Unknown list command received');
303
- }
304
- return list;
305
- }
306
- /**
307
- * Helpers to configure an intent button for modifying a list
308
- *
309
- * @see https://conform.guide/api/react#list
310
- */
311
- var list = new Proxy({}, {
312
- get(_target, type) {
313
- switch (type) {
314
- case 'append':
315
- case 'prepend':
316
- case 'replace':
317
- case 'remove':
318
- case 'reorder':
319
- return function (scope) {
320
- var payload = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
321
- return {
322
- name: INTENT,
323
- value: "list/".concat(type, "/").concat(scope, "/").concat(JSON.stringify(payload)),
324
- formNoValidate: true
325
- };
326
- };
327
- }
328
- }
329
- });
330
-
331
- /**
332
- * Validate the form with the Constraint Validation API
333
- * @see https://conform.guide/api/react#validateconstraint
334
- */
335
- function validateConstraint(options) {
336
- var _options$formData, _options$formatMessag;
337
- var formData = (_options$formData = options === null || options === void 0 ? void 0 : options.formData) !== null && _options$formData !== void 0 ? _options$formData : new FormData(options.form);
338
- var getDefaultErrors = (validity, result) => {
339
- var errors = [];
340
- if (validity.valueMissing) errors.push('required');
341
- if (validity.typeMismatch || validity.badInput) errors.push('type');
342
- if (validity.tooShort) errors.push('minLength');
343
- if (validity.rangeUnderflow) errors.push('min');
344
- if (validity.stepMismatch) errors.push('step');
345
- if (validity.tooLong) errors.push('maxLength');
346
- if (validity.rangeOverflow) errors.push('max');
347
- if (validity.patternMismatch) errors.push('pattern');
348
- for (var [constraintName, valid] of Object.entries(result)) {
349
- if (!valid) {
350
- errors.push(constraintName);
351
- }
352
- }
353
- return errors;
354
- };
355
- var formatMessages = (_options$formatMessag = options === null || options === void 0 ? void 0 : options.formatMessages) !== null && _options$formatMessag !== void 0 ? _options$formatMessag : _ref3 => {
356
- var {
357
- defaultErrors
358
- } = _ref3;
359
- return defaultErrors;
360
- };
361
- return parse(formData, {
362
- resolve(payload, intent) {
363
- var error = {};
364
- var constraintPattern = /^constraint[A-Z][^A-Z]*$/;
365
- var _loop2 = function _loop2(element) {
366
- if (isFieldElement(element)) {
367
- var _options$acceptMultip, _options$acceptMultip2;
368
- var _name3 = element.name !== FORM_ERROR_ELEMENT_NAME ? element.name : '';
369
- var constraint = Object.entries(element.dataset).reduce((result, _ref4) => {
370
- var [name, attributeValue = ''] = _ref4;
371
- if (constraintPattern.test(name)) {
372
- var _options$constraint;
373
- var constraintName = name.slice(10).toLowerCase();
374
- var _validate = (_options$constraint = options.constraint) === null || _options$constraint === void 0 ? void 0 : _options$constraint[constraintName];
375
- if (typeof _validate === 'function') {
376
- result[constraintName] = _validate(element.value, {
377
- formData,
378
- attributeValue
379
- });
380
- } else {
381
- console.warn("Found an \"".concat(constraintName, "\" constraint with undefined definition; Please specify it on the validateConstraint API."));
382
- }
383
- }
384
- return result;
385
- }, {});
386
- var errors = formatMessages({
387
- name: _name3,
388
- validity: element.validity,
389
- constraint,
390
- defaultErrors: getDefaultErrors(element.validity, constraint)
391
- });
392
- var shouldAcceptMultipleErrors = (_options$acceptMultip = options === null || options === void 0 ? void 0 : (_options$acceptMultip2 = options.acceptMultipleErrors) === null || _options$acceptMultip2 === void 0 ? void 0 : _options$acceptMultip2.call(options, {
393
- name: _name3,
394
- payload,
395
- intent
396
- })) !== null && _options$acceptMultip !== void 0 ? _options$acceptMultip : false;
397
- if (errors.length > 0) {
398
- error[_name3] = shouldAcceptMultipleErrors ? errors : errors[0];
399
- }
400
- }
401
- };
402
- for (var element of options.form.elements) {
403
- _loop2(element);
404
- }
405
- return {
406
- error
407
- };
408
- }
409
- });
410
- }
411
-
412
- exports.FORM_ERROR_ELEMENT_NAME = FORM_ERROR_ELEMENT_NAME;
413
- exports.INTENT = INTENT;
414
- exports.VALIDATION_SKIPPED = VALIDATION_SKIPPED;
415
- exports.VALIDATION_UNDEFINED = VALIDATION_UNDEFINED;
416
- exports.getErrors = getErrors;
417
- exports.getFormAttributes = getFormAttributes;
418
- exports.getFormData = getFormData;
419
- exports.getFormElement = getFormElement;
420
- exports.getName = getName;
421
- exports.getPaths = getPaths;
422
- exports.getScope = getScope;
423
- exports.getValidationMessage = getValidationMessage;
424
- exports.isFieldElement = isFieldElement;
425
- exports.isFocusedOnIntentButton = isFocusedOnIntentButton;
426
- exports.list = list;
427
- exports.parse = parse;
428
- exports.parseListCommand = parseListCommand;
429
- exports.reportSubmission = reportSubmission;
430
- exports.requestIntent = requestIntent;
431
- exports.setValue = setValue;
432
- exports.updateList = updateList;
433
- exports.validate = validate;
434
- exports.validateConstraint = validateConstraint;
5
+ var dom = require('./dom.js');
6
+ var formdata = require('./formdata.js');
7
+ var intent = require('./intent.js');
8
+ var parse = require('./parse.js');
9
+
10
+
11
+
12
+ exports.createSubmitter = dom.createSubmitter;
13
+ exports.focusFirstInvalidControl = dom.focusFirstInvalidControl;
14
+ exports.focusFormControl = dom.focusFormControl;
15
+ exports.getFormAction = dom.getFormAction;
16
+ exports.getFormControls = dom.getFormControls;
17
+ exports.getFormElement = dom.getFormElement;
18
+ exports.getFormEncType = dom.getFormEncType;
19
+ exports.getFormMethod = dom.getFormMethod;
20
+ exports.isFieldElement = dom.isFormControl;
21
+ exports.isFocusableFormControl = dom.isFocusableFormControl;
22
+ exports.requestSubmit = dom.requestSubmit;
23
+ exports.getErrors = formdata.getErrors;
24
+ exports.getFormData = formdata.getFormData;
25
+ exports.getName = formdata.formatPaths;
26
+ exports.getPaths = formdata.getPaths;
27
+ exports.getValidationMessage = formdata.getValidationMessage;
28
+ exports.INTENT = intent.INTENT;
29
+ exports.getScope = intent.getScope;
30
+ exports.isSubmitting = intent.isSubmitting;
31
+ exports.list = intent.list;
32
+ exports.parseListCommand = intent.parseListCommand;
33
+ exports.requestIntent = intent.requestIntent;
34
+ exports.updateList = intent.updateList;
35
+ exports.validate = intent.validate;
36
+ exports.parse = parse.parse;
package/intent.d.ts ADDED
@@ -0,0 +1,84 @@
1
+ export interface IntentButtonProps {
2
+ name: typeof INTENT;
3
+ value: string;
4
+ formNoValidate?: boolean;
5
+ }
6
+ export type ListCommand<Schema = unknown> = {
7
+ type: 'prepend';
8
+ scope: string;
9
+ payload: {
10
+ defaultValue: Schema;
11
+ };
12
+ } | {
13
+ type: 'append';
14
+ scope: string;
15
+ payload: {
16
+ defaultValue: Schema;
17
+ };
18
+ } | {
19
+ type: 'replace';
20
+ scope: string;
21
+ payload: {
22
+ defaultValue: Schema;
23
+ index: number;
24
+ };
25
+ } | {
26
+ type: 'remove';
27
+ scope: string;
28
+ payload: {
29
+ index: number;
30
+ };
31
+ } | {
32
+ type: 'reorder';
33
+ scope: string;
34
+ payload: {
35
+ from: number;
36
+ to: number;
37
+ };
38
+ };
39
+ export interface ListCommandButtonBuilder {
40
+ append<Schema>(name: string, payload?: {
41
+ defaultValue: Schema;
42
+ }): IntentButtonProps;
43
+ prepend<Schema>(name: string, payload?: {
44
+ defaultValue: Schema;
45
+ }): IntentButtonProps;
46
+ replace<Schema>(name: string, payload: {
47
+ defaultValue: Schema;
48
+ index: number;
49
+ }): IntentButtonProps;
50
+ remove(name: string, payload: {
51
+ index: number;
52
+ }): IntentButtonProps;
53
+ reorder(name: string, payload: {
54
+ from: number;
55
+ to: number;
56
+ }): IntentButtonProps;
57
+ }
58
+ export declare const INTENT = "__intent__";
59
+ /**
60
+ *
61
+ * @param payload
62
+ * @returns
63
+ */
64
+ export declare function getIntent(payload: FormData | URLSearchParams): string;
65
+ /**
66
+ * Returns the properties required to configure an intent button for validation
67
+ *
68
+ * @see https://conform.guide/api/react#validate
69
+ */
70
+ export declare function validate(field?: string): IntentButtonProps;
71
+ export declare function requestIntent(form: HTMLFormElement | undefined, buttonProps: {
72
+ value: string;
73
+ formNoValidate?: boolean;
74
+ }): void;
75
+ /**
76
+ * Helpers to configure an intent button for modifying a list
77
+ *
78
+ * @see https://conform.guide/api/react#list
79
+ */
80
+ export declare const list: ListCommandButtonBuilder;
81
+ export declare function isSubmitting(intent: string): boolean;
82
+ export declare function getScope(intent: string): string | null;
83
+ export declare function parseListCommand<Schema = unknown>(intent: string): ListCommand<Schema> | null;
84
+ export declare function updateList<Schema>(list: Array<Schema>, command: ListCommand<Schema>): Array<Schema>;
package/intent.js ADDED
@@ -0,0 +1,132 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var dom = require('./dom.js');
6
+
7
+ var INTENT = '__intent__';
8
+
9
+ /**
10
+ *
11
+ * @param payload
12
+ * @returns
13
+ */
14
+ function getIntent(payload) {
15
+ if (!payload.has(INTENT)) {
16
+ return 'submit';
17
+ }
18
+ var [intent, ...rest] = payload.getAll(INTENT);
19
+ if (typeof intent !== 'string' || rest.length > 0) {
20
+ throw new Error('The intent could only be set on a button');
21
+ }
22
+ payload.delete(INTENT);
23
+ return intent;
24
+ }
25
+
26
+ /**
27
+ * Returns the properties required to configure an intent button for validation
28
+ *
29
+ * @see https://conform.guide/api/react#validate
30
+ */
31
+ function validate(field) {
32
+ return {
33
+ name: INTENT,
34
+ value: field ? "validate/".concat(field) : 'validate',
35
+ formNoValidate: true
36
+ };
37
+ }
38
+ function requestIntent(form, buttonProps) {
39
+ if (!form) {
40
+ console.warn('No form element is provided');
41
+ return;
42
+ }
43
+ var submitter = dom.createSubmitter({
44
+ name: INTENT,
45
+ value: buttonProps.value,
46
+ hidden: true,
47
+ formNoValidate: buttonProps.formNoValidate
48
+ });
49
+ dom.requestSubmit(form, submitter);
50
+ }
51
+
52
+ /**
53
+ * Helpers to configure an intent button for modifying a list
54
+ *
55
+ * @see https://conform.guide/api/react#list
56
+ */
57
+ var list = new Proxy({}, {
58
+ get(_target, type) {
59
+ return function (scope) {
60
+ var payload = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
61
+ return {
62
+ name: INTENT,
63
+ value: "list/".concat(type, "/").concat(scope, "/").concat(JSON.stringify(payload)),
64
+ formNoValidate: true
65
+ };
66
+ };
67
+ }
68
+ });
69
+ function isSubmitting(intent) {
70
+ return intent.slice(0, intent.indexOf('/')) !== 'validate' && parseListCommand(intent) === null;
71
+ }
72
+ function getScope(intent) {
73
+ var _parseListCommand$sco, _parseListCommand;
74
+ var [type, ...rest] = intent.split('/');
75
+ switch (type) {
76
+ case 'validate':
77
+ return rest.length > 0 ? rest.join('/') : null;
78
+ case 'list':
79
+ return (_parseListCommand$sco = (_parseListCommand = parseListCommand(intent)) === null || _parseListCommand === void 0 ? void 0 : _parseListCommand.scope) !== null && _parseListCommand$sco !== void 0 ? _parseListCommand$sco : null;
80
+ default:
81
+ return null;
82
+ }
83
+ }
84
+ function parseListCommand(intent) {
85
+ try {
86
+ var [group, type, scope, json] = intent.split('/');
87
+ if (group !== 'list' || !['prepend', 'append', 'replace', 'remove', 'reorder'].includes(type) || !scope) {
88
+ return null;
89
+ }
90
+ var _payload = JSON.parse(json);
91
+ return {
92
+ // @ts-expect-error
93
+ type,
94
+ scope,
95
+ payload: _payload
96
+ };
97
+ } catch (error) {
98
+ return null;
99
+ }
100
+ }
101
+ function updateList(list, command) {
102
+ switch (command.type) {
103
+ case 'prepend':
104
+ list.unshift(command.payload.defaultValue);
105
+ break;
106
+ case 'append':
107
+ list.push(command.payload.defaultValue);
108
+ break;
109
+ case 'replace':
110
+ list.splice(command.payload.index, 1, command.payload.defaultValue);
111
+ break;
112
+ case 'remove':
113
+ list.splice(command.payload.index, 1);
114
+ break;
115
+ case 'reorder':
116
+ list.splice(command.payload.to, 0, ...list.splice(command.payload.from, 1));
117
+ break;
118
+ default:
119
+ throw new Error('Unknown list command received');
120
+ }
121
+ return list;
122
+ }
123
+
124
+ exports.INTENT = INTENT;
125
+ exports.getIntent = getIntent;
126
+ exports.getScope = getScope;
127
+ exports.isSubmitting = isSubmitting;
128
+ exports.list = list;
129
+ exports.parseListCommand = parseListCommand;
130
+ exports.requestIntent = requestIntent;
131
+ exports.updateList = updateList;
132
+ exports.validate = validate;