@marktiderman/genesis-forms 0.5.0 → 0.6.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 +128 -0
- package/dist/destinations.cjs +55 -3
- package/dist/destinations.cjs.map +1 -1
- package/dist/destinations.d.cts +1 -1
- package/dist/destinations.d.ts +1 -1
- package/dist/destinations.js +55 -3
- package/dist/destinations.js.map +1 -1
- package/dist/{engine-BDq0XJ21.d.cts → engine-CpfOz8FN.d.ts} +10 -3
- package/dist/{engine-Qzp6bX6O.d.ts → engine-DC4YTPdr.d.cts} +10 -3
- package/dist/index.cjs +484 -62
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +29 -7
- package/dist/index.d.ts +29 -7
- package/dist/index.js +461 -63
- package/dist/index.js.map +1 -1
- package/dist/server.cjs +541 -21
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +193 -3
- package/dist/server.d.ts +193 -3
- package/dist/server.js +522 -22
- package/dist/server.js.map +1 -1
- package/dist/testing.cjs +314 -21
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +4 -4
- package/dist/testing.d.ts +4 -4
- package/dist/testing.js +314 -21
- package/dist/testing.js.map +1 -1
- package/dist/{types-BhYUbLJ-.d.cts → types-oAckGR_Z.d.cts} +10 -0
- package/dist/{types-BhYUbLJ-.d.ts → types-oAckGR_Z.d.ts} +10 -0
- package/dist/validate-B5WKHbst.d.cts +322 -0
- package/dist/validate-GpTXPwyl.d.ts +322 -0
- package/package.json +1 -1
- package/dist/validate-Bs1lyoOl.d.ts +0 -131
- package/dist/validate-BsZ0YTQS.d.cts +0 -131
package/dist/index.cjs
CHANGED
|
@@ -952,6 +952,65 @@ function summarizeValue(value, field2) {
|
|
|
952
952
|
if (Array.isArray(value)) return value.join(", ");
|
|
953
953
|
return String(value);
|
|
954
954
|
}
|
|
955
|
+
var OPTION_LIMITS = {
|
|
956
|
+
/** Characters in a description. */
|
|
957
|
+
description: 500,
|
|
958
|
+
/** Characters in an image URL. */
|
|
959
|
+
image: 2048,
|
|
960
|
+
/** Attributes on one option. */
|
|
961
|
+
attributes: 20,
|
|
962
|
+
/** Characters in an attribute's name. */
|
|
963
|
+
attributeName: 64,
|
|
964
|
+
/** Characters in one attribute value. */
|
|
965
|
+
attributeValue: 200,
|
|
966
|
+
/** Values in one attribute's list. */
|
|
967
|
+
attributeItems: 50
|
|
968
|
+
};
|
|
969
|
+
function isHttpsUrl(url) {
|
|
970
|
+
return typeof url === "string" && url.length <= OPTION_LIMITS.image && /^https:\/\/[^\s/?#@\\]+(?:[/?#][^\s]*)?$/i.test(url) && // No control characters anywhere (a line break would end a CSV row or an HTML attribute).
|
|
971
|
+
![...url].some((c) => c.charCodeAt(0) < 32 || c.charCodeAt(0) === 127);
|
|
972
|
+
}
|
|
973
|
+
function attributeName(name) {
|
|
974
|
+
return name.trim() !== "" && name.length <= OPTION_LIMITS.attributeName && !(name in Object.prototype);
|
|
975
|
+
}
|
|
976
|
+
function readAttributes(raw) {
|
|
977
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return void 0;
|
|
978
|
+
const out = {};
|
|
979
|
+
let count = 0;
|
|
980
|
+
for (const name of Object.keys(raw)) {
|
|
981
|
+
if (count >= OPTION_LIMITS.attributes) break;
|
|
982
|
+
if (!attributeName(name)) continue;
|
|
983
|
+
const v = raw[name];
|
|
984
|
+
const fits = (x) => typeof x === "string" && x.length <= OPTION_LIMITS.attributeValue;
|
|
985
|
+
if (fits(v)) out[name] = v;
|
|
986
|
+
else if (Array.isArray(v) && v.length <= OPTION_LIMITS.attributeItems && v.every(fits)) out[name] = [...v];
|
|
987
|
+
else continue;
|
|
988
|
+
count++;
|
|
989
|
+
}
|
|
990
|
+
return count ? out : void 0;
|
|
991
|
+
}
|
|
992
|
+
function readOption(raw) {
|
|
993
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return null;
|
|
994
|
+
const o = raw;
|
|
995
|
+
if (typeof o.value !== "string") return null;
|
|
996
|
+
const out = { value: o.value };
|
|
997
|
+
if (typeof o.label === "string") out.label = o.label;
|
|
998
|
+
if (typeof o.description === "string" && o.description.trim() && o.description.length <= OPTION_LIMITS.description) {
|
|
999
|
+
out.description = o.description;
|
|
1000
|
+
}
|
|
1001
|
+
if (isHttpsUrl(o.image)) out.image = o.image;
|
|
1002
|
+
const attributes = readAttributes(o.attributes);
|
|
1003
|
+
if (attributes) out.attributes = attributes;
|
|
1004
|
+
return out;
|
|
1005
|
+
}
|
|
1006
|
+
function optionJson(option) {
|
|
1007
|
+
const out = { value: option.value };
|
|
1008
|
+
if (option.label !== void 0) out.label = option.label;
|
|
1009
|
+
if (option.description !== void 0) out.description = option.description;
|
|
1010
|
+
if (option.image !== void 0) out.image = option.image;
|
|
1011
|
+
if (option.attributes !== void 0) out.attributes = { ...option.attributes };
|
|
1012
|
+
return out;
|
|
1013
|
+
}
|
|
955
1014
|
var OTHER_MAX_LENGTH = 200;
|
|
956
1015
|
function otherOption(field2) {
|
|
957
1016
|
const other = field2.props?.other;
|
|
@@ -969,14 +1028,21 @@ var typedOther = (field2, value) => isOtherValue(field2, value) && value.trim()
|
|
|
969
1028
|
function choiceOptions(field2) {
|
|
970
1029
|
const raw = field2.props?.options;
|
|
971
1030
|
if (!Array.isArray(raw)) return [];
|
|
972
|
-
return raw.flatMap(
|
|
973
|
-
|
|
974
|
-
|
|
1031
|
+
return raw.flatMap((o) => {
|
|
1032
|
+
const option = readOption(o);
|
|
1033
|
+
return option ? [option] : [];
|
|
1034
|
+
});
|
|
975
1035
|
}
|
|
976
1036
|
function optionsSource(field2) {
|
|
977
1037
|
const raw = field2.props?.optionsFrom;
|
|
978
1038
|
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return void 0;
|
|
979
|
-
|
|
1039
|
+
if (raw.source !== "host" || typeof raw.key !== "string" || !raw.key) return void 0;
|
|
1040
|
+
const out = { source: "host", key: raw.key };
|
|
1041
|
+
const filter = raw.filter;
|
|
1042
|
+
if (filter && typeof filter === "object" && !Array.isArray(filter) && typeof filter.attribute === "string" && filter.attribute && typeof filter.field === "string" && filter.field) {
|
|
1043
|
+
out.filter = { attribute: filter.attribute, field: filter.field };
|
|
1044
|
+
}
|
|
1045
|
+
return out;
|
|
980
1046
|
}
|
|
981
1047
|
function hostList(hostOptions, key) {
|
|
982
1048
|
if (!hostOptions || !Object.prototype.hasOwnProperty.call(hostOptions, key)) return [];
|
|
@@ -985,11 +1051,10 @@ function hostList(hostOptions, key) {
|
|
|
985
1051
|
const seen = /* @__PURE__ */ new Set();
|
|
986
1052
|
const out = [];
|
|
987
1053
|
for (const o of list) {
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
out.push(typeof label === "string" ? { value, label } : { value });
|
|
1054
|
+
const option = readOption(o);
|
|
1055
|
+
if (!option || !option.value || seen.has(option.value)) continue;
|
|
1056
|
+
seen.add(option.value);
|
|
1057
|
+
out.push(option);
|
|
993
1058
|
}
|
|
994
1059
|
return out;
|
|
995
1060
|
}
|
|
@@ -1004,7 +1069,7 @@ function withHostOptions(definition, hostOptions) {
|
|
|
1004
1069
|
const added = hostList(hostOptions, from.key).filter((o) => !taken.has(o.value));
|
|
1005
1070
|
if (!added.length) return block;
|
|
1006
1071
|
changed = true;
|
|
1007
|
-
const options = [...own2, ...added].map(
|
|
1072
|
+
const options = [...own2, ...added].map(optionJson);
|
|
1008
1073
|
return { ...block, props: { ...block.props, options } };
|
|
1009
1074
|
});
|
|
1010
1075
|
return changed ? { ...definition, blocks } : definition;
|
|
@@ -1273,6 +1338,47 @@ function dateLimits(field2) {
|
|
|
1273
1338
|
}
|
|
1274
1339
|
for (const manifest of [...builtins, ...structuredFieldTypes, calculatedFieldType, photoFieldType]) registerFieldType(manifest);
|
|
1275
1340
|
|
|
1341
|
+
// src/hidden.ts
|
|
1342
|
+
var MAX_HIDDEN_STRING_LENGTH = 1e3;
|
|
1343
|
+
var DECIMAL = /^-?\d+(\.\d+)?$/;
|
|
1344
|
+
function coerceHiddenValue(value, type) {
|
|
1345
|
+
if (typeof value === "string" && value.length > MAX_HIDDEN_STRING_LENGTH) return void 0;
|
|
1346
|
+
if (type === "string") {
|
|
1347
|
+
if (typeof value === "string") return value;
|
|
1348
|
+
if (typeof value === "boolean" || typeof value === "number" && Number.isFinite(value)) return String(value);
|
|
1349
|
+
return void 0;
|
|
1350
|
+
}
|
|
1351
|
+
if (type === "number") {
|
|
1352
|
+
if (typeof value === "number") return Number.isFinite(value) ? value : void 0;
|
|
1353
|
+
if (typeof value !== "string" || !DECIMAL.test(value)) return void 0;
|
|
1354
|
+
const n = Number(value);
|
|
1355
|
+
return Number.isFinite(n) ? n : void 0;
|
|
1356
|
+
}
|
|
1357
|
+
if (typeof value === "boolean") return value;
|
|
1358
|
+
if (value === "true") return true;
|
|
1359
|
+
if (value === "false") return false;
|
|
1360
|
+
return void 0;
|
|
1361
|
+
}
|
|
1362
|
+
function coerceHidden(definition, raw, options = {}) {
|
|
1363
|
+
const declared = new Map((definition.hidden ?? []).map((h) => [h.name, h]));
|
|
1364
|
+
const values = {};
|
|
1365
|
+
const ignored = [];
|
|
1366
|
+
if (!isPlainObject(raw)) return { values, ignored };
|
|
1367
|
+
for (const name of Object.keys(raw)) {
|
|
1368
|
+
const value = raw[name];
|
|
1369
|
+
if (value === void 0) continue;
|
|
1370
|
+
const spec = declared.get(name);
|
|
1371
|
+
if (!spec || options.sources && !options.sources.includes(spec.source)) {
|
|
1372
|
+
ignored.push(name);
|
|
1373
|
+
continue;
|
|
1374
|
+
}
|
|
1375
|
+
const coerced = coerceHiddenValue(value, spec.type);
|
|
1376
|
+
if (coerced === void 0) ignored.push(name);
|
|
1377
|
+
else Object.defineProperty(values, name, { value: coerced, enumerable: true, writable: true, configurable: true });
|
|
1378
|
+
}
|
|
1379
|
+
return { values, ignored };
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1276
1382
|
// src/logic.ts
|
|
1277
1383
|
function own(record, key) {
|
|
1278
1384
|
return Object.prototype.hasOwnProperty.call(record, key) ? record[key] : void 0;
|
|
@@ -1404,6 +1510,225 @@ function fieldMap(def) {
|
|
|
1404
1510
|
return map;
|
|
1405
1511
|
}
|
|
1406
1512
|
|
|
1513
|
+
// src/options.ts
|
|
1514
|
+
var CHOICE_FIELD_TYPES = /* @__PURE__ */ new Set(["single-choice", "multi-choice", "dropdown"]);
|
|
1515
|
+
var isChoice = (block) => !!block && block.kind === "field" && CHOICE_FIELD_TYPES.has(block.type);
|
|
1516
|
+
function put(record, key, value) {
|
|
1517
|
+
Object.defineProperty(record, key, { value, enumerable: true, writable: true, configurable: true });
|
|
1518
|
+
}
|
|
1519
|
+
function optionFilter(field2) {
|
|
1520
|
+
return optionsSource(field2)?.filter;
|
|
1521
|
+
}
|
|
1522
|
+
function answerValues(answer) {
|
|
1523
|
+
const one = (v) => typeof v === "string" ? [v] : typeof v === "number" || typeof v === "boolean" ? [String(v)] : [];
|
|
1524
|
+
if (answer === void 0 || answer === null) return [];
|
|
1525
|
+
return Array.isArray(answer) ? answer.flatMap(one) : one(answer);
|
|
1526
|
+
}
|
|
1527
|
+
function optionMatches(option, attribute, answer) {
|
|
1528
|
+
const have = option.attributes && Object.prototype.hasOwnProperty.call(option.attributes, attribute) ? option.attributes[attribute] : void 0;
|
|
1529
|
+
if (have === void 0) return false;
|
|
1530
|
+
const wanted = answerValues(answer);
|
|
1531
|
+
return (Array.isArray(have) ? have : [have]).some((v) => wanted.includes(v));
|
|
1532
|
+
}
|
|
1533
|
+
function filterSource(definition, key) {
|
|
1534
|
+
return definition.blocks.find((b) => b.kind === "field" && b.key === key);
|
|
1535
|
+
}
|
|
1536
|
+
function visibleOptions(definition, field2, values) {
|
|
1537
|
+
const options = choiceOptions(field2);
|
|
1538
|
+
const filter = optionFilter(field2);
|
|
1539
|
+
if (!filter) return options;
|
|
1540
|
+
const source = filterSource(definition, filter.field);
|
|
1541
|
+
if (!source || source.id === field2.id) return options;
|
|
1542
|
+
const answer = own(values, source.id);
|
|
1543
|
+
if (isEmptyValue(answer, source)) return options;
|
|
1544
|
+
return options.filter((o) => optionMatches(o, filter.attribute, answer));
|
|
1545
|
+
}
|
|
1546
|
+
function answersOnPath(state) {
|
|
1547
|
+
const out = /* @__PURE__ */ Object.create(null);
|
|
1548
|
+
for (const id of state.path) out[id] = own(state.values, id);
|
|
1549
|
+
return out;
|
|
1550
|
+
}
|
|
1551
|
+
var OUTSIDE_FILTER = "Choose one of the options.";
|
|
1552
|
+
function filteredChoiceError(definition, field2, value, values) {
|
|
1553
|
+
if (!optionFilter(field2) || isEmptyValue(value, field2)) return null;
|
|
1554
|
+
const all = new Set(choiceOptions(field2).map((o) => o.value));
|
|
1555
|
+
const shown2 = new Set(visibleOptions(definition, field2, values).map((o) => o.value));
|
|
1556
|
+
const picked = answerValues(value);
|
|
1557
|
+
return picked.some((v) => all.has(v) && !shown2.has(v)) ? OUTSIDE_FILTER : null;
|
|
1558
|
+
}
|
|
1559
|
+
function hasOptionFilters(definition) {
|
|
1560
|
+
return definition.blocks.some((b) => isChoice(b) && optionFilter(b) !== void 0);
|
|
1561
|
+
}
|
|
1562
|
+
function clearFilteredAnswers(definition, values, changedId) {
|
|
1563
|
+
const changed = definition.blocks.find((b) => b.kind === "field" && b.id === changedId);
|
|
1564
|
+
if (!changed) return values;
|
|
1565
|
+
const keys = /* @__PURE__ */ new Set([changed.key]);
|
|
1566
|
+
let out = values;
|
|
1567
|
+
for (const block of definition.blocks) {
|
|
1568
|
+
if (!isChoice(block)) continue;
|
|
1569
|
+
const filter = optionFilter(block);
|
|
1570
|
+
if (!filter || !keys.has(filter.field)) continue;
|
|
1571
|
+
const value = own(out, block.id);
|
|
1572
|
+
if (value === void 0 || isEmptyValue(value, block)) continue;
|
|
1573
|
+
const all = new Set(choiceOptions(block).map((o) => o.value));
|
|
1574
|
+
const shown2 = new Set(visibleOptions(definition, block, out).map((o) => o.value));
|
|
1575
|
+
const keep = (v) => typeof v !== "string" || !all.has(v) || shown2.has(v);
|
|
1576
|
+
let next = value;
|
|
1577
|
+
if (Array.isArray(value)) {
|
|
1578
|
+
const kept = value.filter(keep);
|
|
1579
|
+
if (kept.length !== value.length) next = kept.length ? kept : void 0;
|
|
1580
|
+
} else if (!keep(value)) next = void 0;
|
|
1581
|
+
if (next === value) continue;
|
|
1582
|
+
if (out === values) out = { ...values };
|
|
1583
|
+
put(out, block.id, next);
|
|
1584
|
+
keys.add(block.key);
|
|
1585
|
+
}
|
|
1586
|
+
return out;
|
|
1587
|
+
}
|
|
1588
|
+
var SEARCHABLE_OPTION_COUNT = 10;
|
|
1589
|
+
function isSearchable(field2, optionCount = choiceOptions(field2).length) {
|
|
1590
|
+
const setting = field2.props?.searchable;
|
|
1591
|
+
if (setting === true || setting === false) return setting;
|
|
1592
|
+
return optionCount > SEARCHABLE_OPTION_COUNT;
|
|
1593
|
+
}
|
|
1594
|
+
function fold(text) {
|
|
1595
|
+
return text.normalize("NFD").replace(/[̀-ͯ]/g, "").toLowerCase();
|
|
1596
|
+
}
|
|
1597
|
+
function searchOptions(options, query) {
|
|
1598
|
+
const words = fold(query).split(/\s+/).filter(Boolean);
|
|
1599
|
+
if (!words.length) return [...options];
|
|
1600
|
+
return options.filter((o) => {
|
|
1601
|
+
const text = fold([o.label ?? "", o.value, o.description ?? ""].join(" "));
|
|
1602
|
+
return words.every((w) => text.includes(w));
|
|
1603
|
+
});
|
|
1604
|
+
}
|
|
1605
|
+
var MAX_PREFILL_PARAM_LENGTH = 64;
|
|
1606
|
+
function isPrefillParam(param) {
|
|
1607
|
+
return typeof param === "string" && param.length <= MAX_PREFILL_PARAM_LENGTH && /^[A-Za-z0-9_.-]+$/.test(param);
|
|
1608
|
+
}
|
|
1609
|
+
function prefillSetting(field2) {
|
|
1610
|
+
if (!CHOICE_FIELD_TYPES.has(field2.type)) return void 0;
|
|
1611
|
+
const raw = field2.props?.prefill;
|
|
1612
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw) || !isPrefillParam(raw.param)) return void 0;
|
|
1613
|
+
return { param: raw.param, hideWhenPrefilled: raw.hideWhenPrefilled === true };
|
|
1614
|
+
}
|
|
1615
|
+
function paramValues(params, name) {
|
|
1616
|
+
let raw;
|
|
1617
|
+
if (typeof params.getAll === "function") {
|
|
1618
|
+
raw = params.getAll(name);
|
|
1619
|
+
} else if (Object.prototype.hasOwnProperty.call(params, name)) {
|
|
1620
|
+
raw = params[name];
|
|
1621
|
+
}
|
|
1622
|
+
const list = Array.isArray(raw) ? raw : raw === void 0 ? [] : [raw];
|
|
1623
|
+
return list.filter((v) => typeof v === "string" && v !== "" && v.length <= MAX_HIDDEN_STRING_LENGTH);
|
|
1624
|
+
}
|
|
1625
|
+
function prefillFromLink(definition, params, values = {}) {
|
|
1626
|
+
const out = {};
|
|
1627
|
+
if (!params || typeof params !== "object") return out;
|
|
1628
|
+
const seen = {};
|
|
1629
|
+
for (const id of Object.keys(values)) put(seen, id, values[id]);
|
|
1630
|
+
for (const block of definition.blocks) {
|
|
1631
|
+
if (!isChoice(block)) continue;
|
|
1632
|
+
const setting = prefillSetting(block);
|
|
1633
|
+
if (!setting || own(seen, block.id) !== void 0) continue;
|
|
1634
|
+
const raw = paramValues(params, setting.param);
|
|
1635
|
+
if (!raw.length) continue;
|
|
1636
|
+
const shown2 = new Set(visibleOptions(definition, block, seen).map((o) => o.value));
|
|
1637
|
+
let value;
|
|
1638
|
+
if (block.type === "multi-choice") {
|
|
1639
|
+
const picked = [];
|
|
1640
|
+
for (const r of raw) {
|
|
1641
|
+
for (const v of shown2.has(r) ? [r] : r.split(",").map((s) => s.trim())) {
|
|
1642
|
+
if (shown2.has(v) && !picked.includes(v)) picked.push(v);
|
|
1643
|
+
}
|
|
1644
|
+
}
|
|
1645
|
+
if (picked.length) value = picked;
|
|
1646
|
+
} else value = raw.find((v) => shown2.has(v));
|
|
1647
|
+
if (value === void 0) continue;
|
|
1648
|
+
put(out, block.id, value);
|
|
1649
|
+
put(seen, block.id, value);
|
|
1650
|
+
}
|
|
1651
|
+
return out;
|
|
1652
|
+
}
|
|
1653
|
+
function hiddenByPrefill(definition, state) {
|
|
1654
|
+
const hideable = /* @__PURE__ */ new Set();
|
|
1655
|
+
for (const b of definition.blocks) {
|
|
1656
|
+
if (isChoice(b) && prefillSetting(b)?.hideWhenPrefilled) hideable.add(b.id);
|
|
1657
|
+
}
|
|
1658
|
+
if (!hideable.size) return [];
|
|
1659
|
+
const prefilled = /* @__PURE__ */ new Set();
|
|
1660
|
+
for (const e of state.events) {
|
|
1661
|
+
if (e.type !== "answer" || !hideable.has(e.field)) continue;
|
|
1662
|
+
if (e.source === "prefill") prefilled.add(e.field);
|
|
1663
|
+
else prefilled.delete(e.field);
|
|
1664
|
+
}
|
|
1665
|
+
if (!prefilled.size) return [];
|
|
1666
|
+
const fields = new Map(definition.blocks.map((b) => [b.id, b]));
|
|
1667
|
+
return state.path.filter((id) => {
|
|
1668
|
+
if (!prefilled.has(id) || own(state.errors, id) !== void 0) return false;
|
|
1669
|
+
const field2 = fields.get(id);
|
|
1670
|
+
return !isEmptyValue(own(state.values, id), field2);
|
|
1671
|
+
});
|
|
1672
|
+
}
|
|
1673
|
+
function respondentPath(definition, state) {
|
|
1674
|
+
const hidden = hiddenByPrefill(definition, state);
|
|
1675
|
+
if (!hidden.length) return [...state.path];
|
|
1676
|
+
const skip = new Set(hidden);
|
|
1677
|
+
return state.path.filter((id) => !skip.has(id));
|
|
1678
|
+
}
|
|
1679
|
+
function snapshotOf(byValue, value) {
|
|
1680
|
+
const option = byValue.get(value);
|
|
1681
|
+
if (option) return { value, label: option.label ?? value };
|
|
1682
|
+
return { value, label: value, other: true };
|
|
1683
|
+
}
|
|
1684
|
+
function answerSnapshots(definition, answers) {
|
|
1685
|
+
const out = {};
|
|
1686
|
+
for (const block of definition.blocks) {
|
|
1687
|
+
if (!isChoice(block) || !optionsSource(block)) continue;
|
|
1688
|
+
const value = own(answers, block.id);
|
|
1689
|
+
if (isEmptyValue(value, block)) continue;
|
|
1690
|
+
const byValue = new Map(choiceOptions(block).map((o) => [o.value, o]));
|
|
1691
|
+
let snapshot;
|
|
1692
|
+
if (Array.isArray(value)) {
|
|
1693
|
+
const items = value.filter((v) => typeof v === "string").map((v) => snapshotOf(byValue, v));
|
|
1694
|
+
if (items.length) snapshot = items;
|
|
1695
|
+
} else if (typeof value === "string") snapshot = snapshotOf(byValue, value);
|
|
1696
|
+
if (snapshot) put(out, block.id, snapshot);
|
|
1697
|
+
}
|
|
1698
|
+
return out;
|
|
1699
|
+
}
|
|
1700
|
+
function answersFromSnapshots(definition, snapshots) {
|
|
1701
|
+
const answers = {};
|
|
1702
|
+
const missing = {};
|
|
1703
|
+
for (const block of definition.blocks) {
|
|
1704
|
+
if (!isChoice(block)) continue;
|
|
1705
|
+
const raw = own(snapshots, block.id);
|
|
1706
|
+
const list = (Array.isArray(raw) ? raw : raw === void 0 ? [] : [raw]).flatMap((s) => {
|
|
1707
|
+
const o = readOption(s);
|
|
1708
|
+
if (!o) return [];
|
|
1709
|
+
const label = o.label ?? o.value;
|
|
1710
|
+
return [s.other === true ? { value: o.value, label, other: true } : { value: o.value, label }];
|
|
1711
|
+
});
|
|
1712
|
+
if (!list.length) continue;
|
|
1713
|
+
const options = choiceOptions(block);
|
|
1714
|
+
const byValue = new Set(options.map((o) => o.value));
|
|
1715
|
+
const allowsOther = block.props?.other !== void 0 && block.props?.other !== false;
|
|
1716
|
+
const found = [];
|
|
1717
|
+
const lost = [];
|
|
1718
|
+
for (const s of list) {
|
|
1719
|
+
let value;
|
|
1720
|
+
if (byValue.has(s.value)) value = s.value;
|
|
1721
|
+
else if (s.other) value = allowsOther ? s.value : void 0;
|
|
1722
|
+
else value = options.find((o) => fold(o.label ?? o.value) === fold(s.label))?.value;
|
|
1723
|
+
if (value === void 0) lost.push(s);
|
|
1724
|
+
else if (!found.includes(value)) found.push(value);
|
|
1725
|
+
}
|
|
1726
|
+
if (found.length) put(answers, block.id, block.type === "multi-choice" ? found : found[0]);
|
|
1727
|
+
if (lost.length) put(missing, block.id, lost);
|
|
1728
|
+
}
|
|
1729
|
+
return { answers, missing };
|
|
1730
|
+
}
|
|
1731
|
+
|
|
1407
1732
|
// src/recall.ts
|
|
1408
1733
|
var TOKEN = /\{\{\s*(field|hidden):([A-Za-z0-9_-]+)\s*(?:\|([^}]*))?\}\}/g;
|
|
1409
1734
|
function recall(text, scope) {
|
|
@@ -1483,6 +1808,31 @@ function parseForm(input) {
|
|
|
1483
1808
|
const optionalBoolean = (v, path) => {
|
|
1484
1809
|
if (v !== void 0 && typeof v !== "boolean") issue(path, "Must be true or false.");
|
|
1485
1810
|
};
|
|
1811
|
+
const optionDetails = (o, at) => {
|
|
1812
|
+
if (o.description !== void 0 && (typeof o.description !== "string" || o.description.length > OPTION_LIMITS.description)) {
|
|
1813
|
+
issue(`${at}.description`, `Must be text of at most ${OPTION_LIMITS.description} characters.`);
|
|
1814
|
+
}
|
|
1815
|
+
if (o.image !== void 0 && !isHttpsUrl(o.image)) {
|
|
1816
|
+
issue(`${at}.image`, `Must be an https:// link of at most ${OPTION_LIMITS.image} characters.`);
|
|
1817
|
+
}
|
|
1818
|
+
if (o.attributes === void 0) return;
|
|
1819
|
+
const attributes = o.attributes;
|
|
1820
|
+
if (!isObject2(attributes) || Object.keys(attributes).length > OPTION_LIMITS.attributes) {
|
|
1821
|
+
issue(`${at}.attributes`, `Must be an object of at most ${OPTION_LIMITS.attributes} attributes.`);
|
|
1822
|
+
return;
|
|
1823
|
+
}
|
|
1824
|
+
const fits = (x) => typeof x === "string" && x.length <= OPTION_LIMITS.attributeValue;
|
|
1825
|
+
for (const [name2, v] of Object.entries(attributes)) {
|
|
1826
|
+
if (!name2.trim() || name2.length > OPTION_LIMITS.attributeName || RESERVED.has(name2)) {
|
|
1827
|
+
issue(`${at}.attributes`, `${shown(name2)} isn't a usable attribute name (at most ${OPTION_LIMITS.attributeName} characters).`);
|
|
1828
|
+
} else if (!fits(v) && !(Array.isArray(v) && v.length <= OPTION_LIMITS.attributeItems && v.every(fits))) {
|
|
1829
|
+
issue(
|
|
1830
|
+
`${at}.attributes.${name2}`,
|
|
1831
|
+
`Must be text, or a list of at most ${OPTION_LIMITS.attributeItems} texts, each at most ${OPTION_LIMITS.attributeValue} characters.`
|
|
1832
|
+
);
|
|
1833
|
+
}
|
|
1834
|
+
}
|
|
1835
|
+
};
|
|
1486
1836
|
const name = (v, path, what) => {
|
|
1487
1837
|
if (typeof v !== "string" || !v) {
|
|
1488
1838
|
issue(path, `${what} must be a non-empty string.`);
|
|
@@ -1655,7 +2005,31 @@ function parseForm(input) {
|
|
|
1655
2005
|
} else if (typeof block.type === "string" && !CHOICE_TYPES.has(block.type)) {
|
|
1656
2006
|
warnings.push({ path: `${path}.props.optionsFrom`, message: "Only single choice, multiple choice and dropdown questions take options from the app." });
|
|
1657
2007
|
}
|
|
2008
|
+
const filter = isObject2(from) ? from.filter : void 0;
|
|
2009
|
+
if (filter !== void 0) {
|
|
2010
|
+
const at = `${path}.props.optionsFrom.filter`;
|
|
2011
|
+
if (!isObject2(filter) || typeof filter.attribute !== "string" || !filter.attribute || filter.attribute.length > OPTION_LIMITS.attributeName || typeof filter.field !== "string" || !filter.field) {
|
|
2012
|
+
issue(at, `Must be { attribute, field }: an attribute name (at most ${OPTION_LIMITS.attributeName} characters) and an earlier question's key.`);
|
|
2013
|
+
} else if (!keys.has(filter.field)) {
|
|
2014
|
+
issue(`${at}.field`, `"${filter.field}" must be the key of an earlier question.`);
|
|
2015
|
+
}
|
|
2016
|
+
}
|
|
1658
2017
|
}
|
|
2018
|
+
const prefill = isObject2(block.props) ? block.props.prefill : void 0;
|
|
2019
|
+
if (prefill !== void 0) {
|
|
2020
|
+
if (!isObject2(prefill) || !isPrefillParam(prefill.param)) {
|
|
2021
|
+
issue(
|
|
2022
|
+
`${path}.props.prefill`,
|
|
2023
|
+
`Must be { param, hideWhenPrefilled? }: a link parameter of letters, digits, "_", "-" or "." (at most ${MAX_PREFILL_PARAM_LENGTH} characters).`
|
|
2024
|
+
);
|
|
2025
|
+
} else {
|
|
2026
|
+
optionalBoolean(prefill.hideWhenPrefilled, `${path}.props.prefill.hideWhenPrefilled`);
|
|
2027
|
+
if (typeof block.type === "string" && !CHOICE_TYPES.has(block.type)) {
|
|
2028
|
+
warnings.push({ path: `${path}.props.prefill`, message: "Only single choice, multiple choice and dropdown questions are filled in from a link." });
|
|
2029
|
+
}
|
|
2030
|
+
}
|
|
2031
|
+
}
|
|
2032
|
+
if (isObject2(block.props)) optionalBoolean(block.props.searchable, `${path}.props.searchable`);
|
|
1659
2033
|
if (!isObject2(block.props) || !isJson(block.props)) issue(`${path}.props`, "Must be a JSON object.");
|
|
1660
2034
|
else if (block.props.options !== void 0) {
|
|
1661
2035
|
const options = block.props.options;
|
|
@@ -1664,7 +2038,10 @@ function parseForm(input) {
|
|
|
1664
2038
|
options.forEach((o, j) => {
|
|
1665
2039
|
const at = `${path}.props.options[${j}]`;
|
|
1666
2040
|
if (!isObject2(o) || typeof o.value !== "string") issue(at, "Each option needs a string value.");
|
|
1667
|
-
else
|
|
2041
|
+
else {
|
|
2042
|
+
optionalText(o.label, `${at}.label`);
|
|
2043
|
+
optionDetails(o, at);
|
|
2044
|
+
}
|
|
1668
2045
|
});
|
|
1669
2046
|
if (from === void 0) {
|
|
1670
2047
|
choices.set(
|
|
@@ -1978,9 +2355,24 @@ var props = (all) => Object.fromEntries(Object.entries(all).filter((e) => e[1] !
|
|
|
1978
2355
|
var choiceProps = (o) => {
|
|
1979
2356
|
const out = {};
|
|
1980
2357
|
if (o.options || !o.optionsFrom) {
|
|
1981
|
-
out.options = (o.options ?? []).map(
|
|
2358
|
+
out.options = (o.options ?? []).map(
|
|
2359
|
+
(x) => props({
|
|
2360
|
+
value: x.value,
|
|
2361
|
+
label: x.label || void 0,
|
|
2362
|
+
description: x.description,
|
|
2363
|
+
image: x.image,
|
|
2364
|
+
attributes: x.attributes
|
|
2365
|
+
})
|
|
2366
|
+
);
|
|
1982
2367
|
}
|
|
1983
|
-
if (o.optionsFrom)
|
|
2368
|
+
if (o.optionsFrom) {
|
|
2369
|
+
const { source, key, filter } = o.optionsFrom;
|
|
2370
|
+
out.optionsFrom = filter ? { source, key, filter: { attribute: filter.attribute, field: filter.field } } : { source, key };
|
|
2371
|
+
}
|
|
2372
|
+
if (o.prefill) {
|
|
2373
|
+
out.prefill = o.prefill.hideWhenPrefilled ? { param: o.prefill.param, hideWhenPrefilled: true } : { param: o.prefill.param };
|
|
2374
|
+
}
|
|
2375
|
+
if (o.searchable !== void 0) out.searchable = o.searchable;
|
|
1984
2376
|
if (o.other) out.other = o.other === true ? true : props({ label: o.other.label });
|
|
1985
2377
|
return out;
|
|
1986
2378
|
};
|
|
@@ -2181,47 +2573,6 @@ ${list}`);
|
|
|
2181
2573
|
};
|
|
2182
2574
|
}
|
|
2183
2575
|
|
|
2184
|
-
// src/hidden.ts
|
|
2185
|
-
var MAX_HIDDEN_STRING_LENGTH = 1e3;
|
|
2186
|
-
var DECIMAL = /^-?\d+(\.\d+)?$/;
|
|
2187
|
-
function coerceHiddenValue(value, type) {
|
|
2188
|
-
if (typeof value === "string" && value.length > MAX_HIDDEN_STRING_LENGTH) return void 0;
|
|
2189
|
-
if (type === "string") {
|
|
2190
|
-
if (typeof value === "string") return value;
|
|
2191
|
-
if (typeof value === "boolean" || typeof value === "number" && Number.isFinite(value)) return String(value);
|
|
2192
|
-
return void 0;
|
|
2193
|
-
}
|
|
2194
|
-
if (type === "number") {
|
|
2195
|
-
if (typeof value === "number") return Number.isFinite(value) ? value : void 0;
|
|
2196
|
-
if (typeof value !== "string" || !DECIMAL.test(value)) return void 0;
|
|
2197
|
-
const n = Number(value);
|
|
2198
|
-
return Number.isFinite(n) ? n : void 0;
|
|
2199
|
-
}
|
|
2200
|
-
if (typeof value === "boolean") return value;
|
|
2201
|
-
if (value === "true") return true;
|
|
2202
|
-
if (value === "false") return false;
|
|
2203
|
-
return void 0;
|
|
2204
|
-
}
|
|
2205
|
-
function coerceHidden(definition, raw, options = {}) {
|
|
2206
|
-
const declared = new Map((definition.hidden ?? []).map((h) => [h.name, h]));
|
|
2207
|
-
const values = {};
|
|
2208
|
-
const ignored = [];
|
|
2209
|
-
if (!isPlainObject(raw)) return { values, ignored };
|
|
2210
|
-
for (const name of Object.keys(raw)) {
|
|
2211
|
-
const value = raw[name];
|
|
2212
|
-
if (value === void 0) continue;
|
|
2213
|
-
const spec = declared.get(name);
|
|
2214
|
-
if (!spec || options.sources && !options.sources.includes(spec.source)) {
|
|
2215
|
-
ignored.push(name);
|
|
2216
|
-
continue;
|
|
2217
|
-
}
|
|
2218
|
-
const coerced = coerceHiddenValue(value, spec.type);
|
|
2219
|
-
if (coerced === void 0) ignored.push(name);
|
|
2220
|
-
else Object.defineProperty(values, name, { value: coerced, enumerable: true, writable: true, configurable: true });
|
|
2221
|
-
}
|
|
2222
|
-
return { values, ignored };
|
|
2223
|
-
}
|
|
2224
|
-
|
|
2225
2576
|
// src/validate.ts
|
|
2226
2577
|
var REQUIRED_MESSAGE = "This question needs an answer.";
|
|
2227
2578
|
function runCustom(validator, value) {
|
|
@@ -2325,16 +2676,34 @@ function build(given, options, replaying = false, budget) {
|
|
|
2325
2676
|
return at === void 0 ? event : { ...event, at };
|
|
2326
2677
|
};
|
|
2327
2678
|
const isVisibleIn = (s, id) => s.path.includes(id);
|
|
2679
|
+
const filters = hasOptionFilters(definition);
|
|
2680
|
+
const clearFiltered = (values, id) => filters ? clearFilteredAnswers(definition, values, id) : values;
|
|
2328
2681
|
const errorsFor = (s, ids) => {
|
|
2329
2682
|
const errors = {};
|
|
2683
|
+
let shown2;
|
|
2330
2684
|
for (const id of ids) {
|
|
2331
2685
|
const field2 = fields.get(id);
|
|
2332
2686
|
if (!field2 || !isVisibleIn(s, id)) continue;
|
|
2333
|
-
const
|
|
2687
|
+
const value = own(s.values, id);
|
|
2688
|
+
let message = validateField(field2, value, { custom: options.validators?.[id] });
|
|
2689
|
+
if (!message && filters) message = filteredChoiceError(definition, field2, value, shown2 ??= answersOnPath(s));
|
|
2334
2690
|
if (message) errors[id] = message;
|
|
2335
2691
|
}
|
|
2336
2692
|
return errors;
|
|
2337
2693
|
};
|
|
2694
|
+
const skipped = (s) => new Set(hiddenByPrefill(definition, s));
|
|
2695
|
+
const shownFrom = (s, from, skip) => {
|
|
2696
|
+
for (let i = from; i < s.path.length; i++) if (!skip.has(s.path[i])) return s.path[i];
|
|
2697
|
+
return void 0;
|
|
2698
|
+
};
|
|
2699
|
+
const showCurrent = () => {
|
|
2700
|
+
if (!state.current) return;
|
|
2701
|
+
const skip = skipped(state);
|
|
2702
|
+
if (!skip.has(state.current)) return;
|
|
2703
|
+
const at = state.path.indexOf(state.current);
|
|
2704
|
+
const shown2 = at < 0 ? void 0 : shownFrom(state, at, skip);
|
|
2705
|
+
if (shown2) state = { ...state, current: shown2, furthest: state.furthest === state.current ? shown2 : state.furthest };
|
|
2706
|
+
};
|
|
2338
2707
|
let unsettled = false;
|
|
2339
2708
|
let formulasStale = false;
|
|
2340
2709
|
const settleNow = (needValues = true) => {
|
|
@@ -2363,13 +2732,13 @@ function build(given, options, replaying = false, budget) {
|
|
|
2363
2732
|
const errors = { ...state.errors };
|
|
2364
2733
|
delete errors[id];
|
|
2365
2734
|
if (batch) {
|
|
2366
|
-
state.values = { ...state.values, [id]: value };
|
|
2735
|
+
state.values = clearFiltered({ ...state.values, [id]: value }, id);
|
|
2367
2736
|
state.errors = errors;
|
|
2368
2737
|
log(event);
|
|
2369
2738
|
unsettled = true;
|
|
2370
2739
|
return;
|
|
2371
2740
|
}
|
|
2372
|
-
const { values, path } = settle({ ...state.values, [id]: value }, state.hidden);
|
|
2741
|
+
const { values, path } = settle(clearFiltered({ ...state.values, [id]: value }, id), state.hidden);
|
|
2373
2742
|
emit({ ...state, values, path, errors, events: log(event) });
|
|
2374
2743
|
};
|
|
2375
2744
|
const engine = {
|
|
@@ -2400,7 +2769,7 @@ function build(given, options, replaying = false, budget) {
|
|
|
2400
2769
|
return false;
|
|
2401
2770
|
}
|
|
2402
2771
|
const at = state.path.indexOf(state.current);
|
|
2403
|
-
const target = state
|
|
2772
|
+
const target = shownFrom(state, at + 1, skipped(state));
|
|
2404
2773
|
if (!target) {
|
|
2405
2774
|
emit({ ...state, events });
|
|
2406
2775
|
return true;
|
|
@@ -2412,8 +2781,9 @@ function build(given, options, replaying = false, budget) {
|
|
|
2412
2781
|
back() {
|
|
2413
2782
|
if (state.status === "completed") return;
|
|
2414
2783
|
const history = [...state.history];
|
|
2784
|
+
const skip = skipped(state);
|
|
2415
2785
|
let previous = history.pop();
|
|
2416
|
-
while (previous && !state.path.includes(previous)) previous = history.pop();
|
|
2786
|
+
while (previous && (!state.path.includes(previous) || skip.has(previous))) previous = history.pop();
|
|
2417
2787
|
if (!previous) return;
|
|
2418
2788
|
emit({ ...state, current: previous, history, events: log(stamp({ type: "back" })) });
|
|
2419
2789
|
},
|
|
@@ -2441,15 +2811,18 @@ function build(given, options, replaying = false, budget) {
|
|
|
2441
2811
|
return out;
|
|
2442
2812
|
}
|
|
2443
2813
|
};
|
|
2444
|
-
|
|
2814
|
+
const fromLink = options.linkParams ? prefillFromLink(definition, options.linkParams, options.initialValues) : {};
|
|
2815
|
+
const initialValues = Object.keys(fromLink).length ? { ...fromLink, ...options.initialValues } : options.initialValues;
|
|
2816
|
+
if (initialValues) {
|
|
2445
2817
|
const wasBatch = batch;
|
|
2446
2818
|
batch = true;
|
|
2447
|
-
for (const [id, value] of Object.entries(
|
|
2819
|
+
for (const [id, value] of Object.entries(initialValues)) {
|
|
2448
2820
|
if (!fields.has(id) || value === void 0) continue;
|
|
2449
2821
|
answer(id, value, stamp({ type: "answer", field: id, value, source: "prefill" }));
|
|
2450
2822
|
}
|
|
2451
2823
|
settleNow();
|
|
2452
2824
|
batch = wasBatch;
|
|
2825
|
+
showCurrent();
|
|
2453
2826
|
}
|
|
2454
2827
|
const resumeAt = options.resumeAt;
|
|
2455
2828
|
if (resumeAt && !replaying && state.path.includes(resumeAt)) {
|
|
@@ -2468,18 +2841,22 @@ function build(given, options, replaying = false, budget) {
|
|
|
2468
2841
|
}
|
|
2469
2842
|
} else if (event.type === "next") {
|
|
2470
2843
|
settleNow(false);
|
|
2844
|
+
showCurrent();
|
|
2471
2845
|
if (formulasStale && isCalculated(fields.get(state.current ?? ""))) settleNow(true);
|
|
2472
2846
|
engine.next();
|
|
2473
2847
|
} else if (event.type === "back") {
|
|
2474
2848
|
settleNow(false);
|
|
2849
|
+
showCurrent();
|
|
2475
2850
|
engine.back();
|
|
2476
2851
|
} else if (event.type === "submit") {
|
|
2477
2852
|
settleNow();
|
|
2853
|
+
showCurrent();
|
|
2478
2854
|
engine.submit();
|
|
2479
2855
|
}
|
|
2480
2856
|
};
|
|
2481
2857
|
const finish = () => {
|
|
2482
2858
|
settleNow();
|
|
2859
|
+
showCurrent();
|
|
2483
2860
|
batch = false;
|
|
2484
2861
|
state = { ...state, events: [...state.events] };
|
|
2485
2862
|
};
|
|
@@ -2490,7 +2867,12 @@ function replay(definition, events, options = {}) {
|
|
|
2490
2867
|
}
|
|
2491
2868
|
function replayWithin(definition, events, options, maxWork) {
|
|
2492
2869
|
const budget = void 0 ;
|
|
2493
|
-
const { engine, apply, finish } = build(
|
|
2870
|
+
const { engine, apply, finish } = build(
|
|
2871
|
+
definition,
|
|
2872
|
+
{ ...options, initialValues: void 0, linkParams: void 0, clock: () => void 0 },
|
|
2873
|
+
true,
|
|
2874
|
+
budget
|
|
2875
|
+
);
|
|
2494
2876
|
try {
|
|
2495
2877
|
for (const event of events) apply(event);
|
|
2496
2878
|
finish();
|
|
@@ -2662,7 +3044,24 @@ function describeCondition(condition, def, fields = fieldMap(def)) {
|
|
|
2662
3044
|
return `${left} ${op} ${right}`;
|
|
2663
3045
|
}
|
|
2664
3046
|
|
|
3047
|
+
// src/carry.ts
|
|
3048
|
+
function carryAnswers(from, to, answers, extra = {}) {
|
|
3049
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
3050
|
+
for (const block of from.blocks) {
|
|
3051
|
+
if (block.kind === "field" && answers[block.id] !== void 0) byKey.set(block.key, answers[block.id]);
|
|
3052
|
+
}
|
|
3053
|
+
for (const [key, value] of Object.entries(extra)) {
|
|
3054
|
+
if (value !== null && value !== void 0 && !byKey.has(key)) byKey.set(key, value);
|
|
3055
|
+
}
|
|
3056
|
+
const out = {};
|
|
3057
|
+
for (const block of to.blocks) {
|
|
3058
|
+
if (block.kind === "field" && byKey.has(block.key)) out[block.id] = byKey.get(block.key);
|
|
3059
|
+
}
|
|
3060
|
+
return out;
|
|
3061
|
+
}
|
|
3062
|
+
|
|
2665
3063
|
exports.CALCULATED_TYPE = CALCULATED_TYPE;
|
|
3064
|
+
exports.CHOICE_FIELD_TYPES = CHOICE_FIELD_TYPES;
|
|
2666
3065
|
exports.COMPUTED_FIELD_TYPES = COMPUTED_FIELD_TYPES;
|
|
2667
3066
|
exports.DEFAULT_PHOTO_FILES = DEFAULT_PHOTO_FILES;
|
|
2668
3067
|
exports.DEFAULT_PHOTO_SIZE_MB = DEFAULT_PHOTO_SIZE_MB;
|
|
@@ -2679,20 +3078,28 @@ exports.MAX_PHOTO_FILES = MAX_PHOTO_FILES;
|
|
|
2679
3078
|
exports.MAX_PHOTO_ID_LENGTH = MAX_PHOTO_ID_LENGTH;
|
|
2680
3079
|
exports.MAX_PHOTO_NAME_LENGTH = MAX_PHOTO_NAME_LENGTH;
|
|
2681
3080
|
exports.MAX_PHOTO_SIZE_MB = MAX_PHOTO_SIZE_MB;
|
|
3081
|
+
exports.MAX_PREFILL_PARAM_LENGTH = MAX_PREFILL_PARAM_LENGTH;
|
|
2682
3082
|
exports.MAX_SETTLE_ITEMS = MAX_SETTLE_ITEMS;
|
|
2683
3083
|
exports.MAX_TABLE_CELL_LENGTH = MAX_TABLE_CELL_LENGTH;
|
|
2684
3084
|
exports.MAX_TABLE_COLUMNS = MAX_TABLE_COLUMNS;
|
|
2685
3085
|
exports.MAX_TIMESTAMP_SECONDS = MAX_TIMESTAMP_SECONDS;
|
|
3086
|
+
exports.OPTION_LIMITS = OPTION_LIMITS;
|
|
2686
3087
|
exports.OTHER_MAX_LENGTH = OTHER_MAX_LENGTH;
|
|
2687
3088
|
exports.PHOTO_FORMATS = PHOTO_FORMATS;
|
|
2688
3089
|
exports.PHOTO_TYPE = PHOTO_TYPE;
|
|
2689
3090
|
exports.REQUIRED_MESSAGE = REQUIRED_MESSAGE;
|
|
3091
|
+
exports.SEARCHABLE_OPTION_COUNT = SEARCHABLE_OPTION_COUNT;
|
|
2690
3092
|
exports.STRUCTURED_FIELD_TYPES = STRUCTURED_FIELD_TYPES;
|
|
2691
3093
|
exports.UPLOAD_FIELD_TYPES = UPLOAD_FIELD_TYPES;
|
|
3094
|
+
exports.answerSnapshots = answerSnapshots;
|
|
3095
|
+
exports.answersFromSnapshots = answersFromSnapshots;
|
|
3096
|
+
exports.answersOnPath = answersOnPath;
|
|
2692
3097
|
exports.calculatedProps = calculatedProps;
|
|
2693
3098
|
exports.calculatedValue = calculatedValue;
|
|
2694
3099
|
exports.canonicalJson = canonicalJson;
|
|
3100
|
+
exports.carryAnswers = carryAnswers;
|
|
2695
3101
|
exports.choiceOptions = choiceOptions;
|
|
3102
|
+
exports.clearFilteredAnswers = clearFilteredAnswers;
|
|
2696
3103
|
exports.coerceHidden = coerceHidden;
|
|
2697
3104
|
exports.coerceHiddenValue = coerceHiddenValue;
|
|
2698
3105
|
exports.computePath = computePath;
|
|
@@ -2704,6 +3111,7 @@ exports.evaluate = evaluate;
|
|
|
2704
3111
|
exports.evaluateFormula = evaluateFormula;
|
|
2705
3112
|
exports.explain = explain;
|
|
2706
3113
|
exports.f = f;
|
|
3114
|
+
exports.filteredChoiceError = filteredChoiceError;
|
|
2707
3115
|
exports.fingerprint = fingerprint;
|
|
2708
3116
|
exports.formProgress = formProgress;
|
|
2709
3117
|
exports.formatCalculated = formatCalculated;
|
|
@@ -2713,18 +3121,26 @@ exports.formulaNumber = formulaNumber;
|
|
|
2713
3121
|
exports.formulaRefs = formulaRefs;
|
|
2714
3122
|
exports.furthestReached = furthestReached;
|
|
2715
3123
|
exports.getFieldType = getFieldType;
|
|
3124
|
+
exports.hasOptionFilters = hasOptionFilters;
|
|
3125
|
+
exports.hiddenByPrefill = hiddenByPrefill;
|
|
2716
3126
|
exports.isEmptyValue = isEmptyValue;
|
|
2717
3127
|
exports.isFormEvent = isFormEvent;
|
|
3128
|
+
exports.isHttpsUrl = isHttpsUrl;
|
|
2718
3129
|
exports.isIsoDate = isIsoDate;
|
|
2719
3130
|
exports.isJson = isJson;
|
|
2720
3131
|
exports.isOtherValue = isOtherValue;
|
|
2721
3132
|
exports.isPhotoFormat = isPhotoFormat;
|
|
2722
3133
|
exports.isPhotoRef = isPhotoRef;
|
|
3134
|
+
exports.isPrefillParam = isPrefillParam;
|
|
3135
|
+
exports.isSearchable = isSearchable;
|
|
2723
3136
|
exports.isSensitive = isSensitive;
|
|
2724
3137
|
exports.listFieldTypes = listFieldTypes;
|
|
2725
3138
|
exports.listLimits = listLimits;
|
|
2726
3139
|
exports.normalizeValue = normalizeValue;
|
|
2727
3140
|
exports.numberLimits = numberLimits;
|
|
3141
|
+
exports.optionFilter = optionFilter;
|
|
3142
|
+
exports.optionJson = optionJson;
|
|
3143
|
+
exports.optionMatches = optionMatches;
|
|
2728
3144
|
exports.optionsSource = optionsSource;
|
|
2729
3145
|
exports.otherOption = otherOption;
|
|
2730
3146
|
exports.parseForm = parseForm;
|
|
@@ -2736,18 +3152,24 @@ exports.photoLimits = photoLimits;
|
|
|
2736
3152
|
exports.photoRefs = photoRefs;
|
|
2737
3153
|
exports.photoSizeMessage = photoSizeMessage;
|
|
2738
3154
|
exports.photoTypeMessage = photoTypeMessage;
|
|
3155
|
+
exports.prefillFromLink = prefillFromLink;
|
|
3156
|
+
exports.prefillSetting = prefillSetting;
|
|
2739
3157
|
exports.ratingDisplay = ratingDisplay;
|
|
3158
|
+
exports.readOption = readOption;
|
|
2740
3159
|
exports.recall = recall;
|
|
2741
3160
|
exports.registerFieldType = registerFieldType;
|
|
2742
3161
|
exports.renameFormulaKey = renameFormulaKey;
|
|
2743
3162
|
exports.replay = replay;
|
|
3163
|
+
exports.respondentPath = respondentPath;
|
|
2744
3164
|
exports.ruleVisible = ruleVisible;
|
|
2745
3165
|
exports.scaleLabels = scaleLabels;
|
|
3166
|
+
exports.searchOptions = searchOptions;
|
|
2746
3167
|
exports.steps = steps;
|
|
2747
3168
|
exports.summarizeValue = summarizeValue;
|
|
2748
3169
|
exports.tableColumns = tableColumns;
|
|
2749
3170
|
exports.tableLimits = tableLimits;
|
|
2750
3171
|
exports.validateField = validateField;
|
|
3172
|
+
exports.visibleOptions = visibleOptions;
|
|
2751
3173
|
exports.when = when;
|
|
2752
3174
|
exports.withHostOptions = withHostOptions;
|
|
2753
3175
|
//# sourceMappingURL=index.cjs.map
|