@fieldia/core 0.25.0 → 0.26.1
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 +58 -2
- package/package.json +1 -1
- package/schema/page.schema.json +86 -3
- package/src/index.d.mts +1 -0
- package/src/index.d.ts +1 -0
- package/src/index.js +3 -1
- package/src/index.js.map +1 -1
- package/src/index.mjs +1 -0
- package/src/index.mjs.map +1 -1
- package/src/lib/format/head-checks.d.mts +3 -1
- package/src/lib/format/head-checks.d.ts +3 -1
- package/src/lib/format/head-checks.js +25 -4
- package/src/lib/format/head-checks.js.map +1 -1
- package/src/lib/format/head-checks.mjs +24 -4
- package/src/lib/format/head-checks.mjs.map +1 -1
- package/src/lib/format/layout.d.mts +208 -12
- package/src/lib/format/layout.d.ts +208 -12
- package/src/lib/format/layout.js +11 -6
- package/src/lib/format/layout.js.map +1 -1
- package/src/lib/format/layout.mjs +11 -6
- package/src/lib/format/layout.mjs.map +1 -1
- package/src/lib/format/page.d.mts +69 -3
- package/src/lib/format/page.d.ts +69 -3
- package/src/lib/format/page.js +3 -0
- package/src/lib/format/page.js.map +1 -1
- package/src/lib/format/page.mjs +3 -0
- package/src/lib/format/page.mjs.map +1 -1
- package/src/lib/format/records.d.mts +23 -0
- package/src/lib/format/records.d.ts +23 -0
- package/src/lib/format/records.js +28 -0
- package/src/lib/format/records.js.map +1 -0
- package/src/lib/format/records.mjs +25 -0
- package/src/lib/format/records.mjs.map +1 -0
- package/src/lib/format/references.d.mts +2 -0
- package/src/lib/format/references.d.ts +2 -0
- package/src/lib/format/references.js +13 -0
- package/src/lib/format/references.js.map +1 -1
- package/src/lib/format/references.mjs +13 -0
- package/src/lib/format/references.mjs.map +1 -1
- package/src/lib/format/translate.js +5 -3
- package/src/lib/format/translate.js.map +1 -1
- package/src/lib/format/translate.mjs +5 -3
- package/src/lib/format/translate.mjs.map +1 -1
- package/src/lib/format/upgrade.d.mts +6 -3
- package/src/lib/format/upgrade.d.ts +6 -3
- package/src/lib/format/upgrade.js +6 -3
- package/src/lib/format/upgrade.js.map +1 -1
- package/src/lib/format/upgrade.mjs +6 -3
- package/src/lib/format/upgrade.mjs.map +1 -1
- package/src/lib/format/version.d.mts +2 -2
- package/src/lib/format/version.d.ts +2 -2
- package/src/lib/format/version.js +2 -2
- package/src/lib/format/version.js.map +1 -1
- package/src/lib/format/version.mjs +2 -2
- package/src/lib/format/version.mjs.map +1 -1
- package/src/lib/record/check.js +2 -2
- package/src/lib/record/check.js.map +1 -1
- package/src/lib/record/check.mjs +3 -3
- package/src/lib/record/check.mjs.map +1 -1
- package/src/lib/record/form.d.mts +6 -2
- package/src/lib/record/form.d.ts +6 -2
- package/src/lib/record/form.js +25 -17
- package/src/lib/record/form.js.map +1 -1
- package/src/lib/record/form.mjs +26 -18
- package/src/lib/record/form.mjs.map +1 -1
- package/src/lib/record/inputs.js +8 -8
- package/src/lib/record/inputs.js.map +1 -1
- package/src/lib/record/inputs.mjs +9 -9
- package/src/lib/record/inputs.mjs.map +1 -1
- package/src/lib/record/limits.js +1 -1
- package/src/lib/record/limits.js.map +1 -1
- package/src/lib/record/limits.mjs +2 -2
- package/src/lib/record/limits.mjs.map +1 -1
- package/src/lib/record/locales/de.js +2 -0
- package/src/lib/record/locales/de.js.map +1 -1
- package/src/lib/record/locales/de.mjs +2 -0
- package/src/lib/record/locales/de.mjs.map +1 -1
- package/src/lib/record/memory-data-source.js +24 -1
- package/src/lib/record/memory-data-source.js.map +1 -1
- package/src/lib/record/memory-data-source.mjs +24 -1
- package/src/lib/record/memory-data-source.mjs.map +1 -1
- package/src/lib/record/messages.d.mts +24 -0
- package/src/lib/record/messages.d.ts +24 -0
- package/src/lib/record/messages.js +25 -0
- package/src/lib/record/messages.js.map +1 -1
- package/src/lib/record/messages.mjs +24 -0
- package/src/lib/record/messages.mjs.map +1 -1
- package/src/lib/record/record-words.d.mts +19 -0
- package/src/lib/record/record-words.d.ts +19 -0
- package/src/lib/record/record-words.js +60 -0
- package/src/lib/record/record-words.js.map +1 -0
- package/src/lib/record/record-words.mjs +56 -0
- package/src/lib/record/record-words.mjs.map +1 -0
- package/src/lib/record/rules.js +1 -1
- package/src/lib/record/rules.js.map +1 -1
- package/src/lib/record/rules.mjs +2 -2
- package/src/lib/record/rules.mjs.map +1 -1
- package/src/lib/record/run.d.mts +8 -0
- package/src/lib/record/run.d.ts +8 -0
- package/src/lib/record/run.js.map +1 -1
- package/src/lib/record/run.mjs.map +1 -1
- package/src/lib/record/search.js +2 -1
- package/src/lib/record/search.js.map +1 -1
- package/src/lib/record/search.mjs +2 -1
- package/src/lib/record/search.mjs.map +1 -1
- package/src/lib/record/structures.js +3 -3
- package/src/lib/record/structures.js.map +1 -1
- package/src/lib/record/structures.mjs +4 -4
- package/src/lib/record/structures.mjs.map +1 -1
- package/src/runtime.d.mts +4 -1
- package/src/runtime.d.ts +4 -1
- package/src/runtime.js +8 -3
- package/src/runtime.js.map +1 -1
- package/src/runtime.mjs +2 -0
- package/src/runtime.mjs.map +1 -1
package/src/lib/record/form.mjs
CHANGED
|
@@ -12,7 +12,8 @@ import { firstValues, readLooseMap, readValueMap } from './value-map.mjs';
|
|
|
12
12
|
import { resolveFilter } from './filter.mjs';
|
|
13
13
|
import { rolesAllow } from './roles.mjs';
|
|
14
14
|
import { compileFieldTone, compileTable } from './cells.mjs';
|
|
15
|
-
import {
|
|
15
|
+
import { fillMessage, MESSAGES } from './messages.mjs';
|
|
16
|
+
import { recordSentence } from './record-words.mjs';
|
|
16
17
|
import { loadedRecordOf, saveProblemOf, } from './data-source.mjs';
|
|
17
18
|
import { waitingOn, workedOutFrom } from './waits.mjs';
|
|
18
19
|
import { createUploads, fileBytesIn, uploadGoing, withoutFileBytes } from './uploads.mjs';
|
|
@@ -75,7 +76,10 @@ function innerForm(options, within, place, outer) {
|
|
|
75
76
|
// Its time zone written into each date and time field naming none, for whatever reads one from its field alone.
|
|
76
77
|
const page = zonedPage(options.page);
|
|
77
78
|
const scheduler = options.scheduler ?? hostScheduler;
|
|
78
|
-
|
|
79
|
+
// A field's label small inside a message's sentence where the page asks (`lowerLabels`).
|
|
80
|
+
const messages = page.lowerLabels ? { ...(options.messages ?? MESSAGES.en), lowerLabels: true } : (options.messages ?? MESSAGES.en);
|
|
81
|
+
/** One of the form's sentences in the words the page names its records by (`records`), else as the language says it plainly. */
|
|
82
|
+
const named = (noun, plain) => recordSentence(page.records, noun, plain, messages.locale);
|
|
79
83
|
const index = indexLayout(page.layout);
|
|
80
84
|
/** Each field node's answer rules, read once. */
|
|
81
85
|
const nodeRules = new Map();
|
|
@@ -858,7 +862,7 @@ function innerForm(options, within, place, outer) {
|
|
|
858
862
|
return undefined;
|
|
859
863
|
const at = (v) => (def.type === 'datetime' ? Date.parse(v) : Date.parse(v.slice(0, 10)));
|
|
860
864
|
if (at(value) < at(start))
|
|
861
|
-
return
|
|
865
|
+
return fillMessage(messages, messages.endBeforeStart, { end: def.label, start: page.fields[node.field].label });
|
|
862
866
|
return undefined;
|
|
863
867
|
}
|
|
864
868
|
/** Errors for the visible fields under `root`, without publishing them. */
|
|
@@ -1247,13 +1251,13 @@ function innerForm(options, within, place, outer) {
|
|
|
1247
1251
|
async function savingNow(chain) {
|
|
1248
1252
|
// A record its source does not let this person change is refused here, in its words or the form's: no source is asked.
|
|
1249
1253
|
if (page.data.kind === 'record' && state.can?.edit === false) {
|
|
1250
|
-
const problem = { kind: 'rule', message: state.can.reason ?? messages.mayNotEdit };
|
|
1254
|
+
const problem = { kind: 'rule', message: state.can.reason ?? named(messages.mayNotEditNoun, messages.mayNotEdit) };
|
|
1251
1255
|
set({ status: 'error', error: problem.message, saveProblem: problem, conflict: null });
|
|
1252
1256
|
return { reason: 'save', message: problem.message };
|
|
1253
1257
|
}
|
|
1254
1258
|
// Asked for the record shown now: another shown while it waits below, it saves nothing of that one, nor says anything there.
|
|
1255
1259
|
const asked = generation;
|
|
1256
|
-
const elsewhere = () => ({ reason: 'save', message: messages.recordReplaced });
|
|
1260
|
+
const elsewhere = () => ({ reason: 'save', message: named(messages.recordReplacedNoun, messages.recordReplaced) });
|
|
1257
1261
|
// What is still typed in a box is read first: it is what is saved, or why nothing is. A name still being looked
|
|
1258
1262
|
// up is waited for, so the record it names is what is saved — or, named by none, why nothing is.
|
|
1259
1263
|
const waiting = readTyped();
|
|
@@ -1453,6 +1457,16 @@ function innerForm(options, within, place, outer) {
|
|
|
1453
1457
|
changed(name, by, { keep });
|
|
1454
1458
|
}
|
|
1455
1459
|
/** A line added: the person's, theirs; a step's, none of theirs, and the lines they changed stay theirs. */
|
|
1460
|
+
/** What a line added now starts with: each line field's default, then what is worked out from its defaultFrom, then the record's lineDefaults. */
|
|
1461
|
+
function newLineValues(field) {
|
|
1462
|
+
const def = lineField(field);
|
|
1463
|
+
const lineFields = def.fields;
|
|
1464
|
+
const start = initialValues(lineFields, today());
|
|
1465
|
+
Object.assign(start, firstValues(lineFields, lineScope(field, start)));
|
|
1466
|
+
if (def.lineDefaults)
|
|
1467
|
+
Object.assign(start, readValueMap(def.lineDefaults, lineFields, recordScope()));
|
|
1468
|
+
return start;
|
|
1469
|
+
}
|
|
1456
1470
|
function addLine(field, values, by) {
|
|
1457
1471
|
const def = lineField(field);
|
|
1458
1472
|
const current = state.values[field] ?? [];
|
|
@@ -1460,13 +1474,7 @@ function innerForm(options, within, place, outer) {
|
|
|
1460
1474
|
let key = `new-${++lineKeys}`;
|
|
1461
1475
|
while (current.some((line) => line.key === key))
|
|
1462
1476
|
key = `new-${++lineKeys}`;
|
|
1463
|
-
|
|
1464
|
-
const lineFields = def.fields;
|
|
1465
|
-
const start = initialValues(lineFields, today());
|
|
1466
|
-
Object.assign(start, firstValues(lineFields, lineScope(field, start)));
|
|
1467
|
-
if (def.lineDefaults)
|
|
1468
|
-
Object.assign(start, readValueMap(def.lineDefaults, lineFields, recordScope()));
|
|
1469
|
-
const line = { key, values: { ...start, ...structuredCopy(values) } };
|
|
1477
|
+
const line = { key, values: { ...newLineValues(field), ...structuredCopy(values) } };
|
|
1470
1478
|
// A new line comes last, so it is numbered after the last.
|
|
1471
1479
|
if (def.sequenceField && line.values[def.sequenceField] == null) {
|
|
1472
1480
|
const numbers = current.map((l) => l.values[def.sequenceField]).filter((n) => typeof n === 'number');
|
|
@@ -1737,7 +1745,7 @@ function innerForm(options, within, place, outer) {
|
|
|
1737
1745
|
return going;
|
|
1738
1746
|
}
|
|
1739
1747
|
async function askToLetGo() {
|
|
1740
|
-
const message = messages.discardChanges;
|
|
1748
|
+
const message = named(messages.discardChangesNoun, messages.discardChanges);
|
|
1741
1749
|
const host = options.host;
|
|
1742
1750
|
let yes = false;
|
|
1743
1751
|
try {
|
|
@@ -1796,7 +1804,7 @@ function innerForm(options, within, place, outer) {
|
|
|
1796
1804
|
const go = letGo({}, chain);
|
|
1797
1805
|
return go === true ? null : go.then((yes) => (yes ? null : kept()));
|
|
1798
1806
|
}
|
|
1799
|
-
const kept = () => ({ reason: 'no', message: messages.discardChanges });
|
|
1807
|
+
const kept = () => ({ reason: 'no', message: named(messages.discardChangesNoun, messages.discardChanges) });
|
|
1800
1808
|
/**
|
|
1801
1809
|
* A step's own move — the record loaded again, or another shown — once the check let what is shown go: kept, the
|
|
1802
1810
|
* person kept their work; replaced, another record was shown before it ended (the run's steps are not for that one).
|
|
@@ -1833,7 +1841,7 @@ function innerForm(options, within, place, outer) {
|
|
|
1833
1841
|
}
|
|
1834
1842
|
/** Why a run stops whose record was replaced while it went on — quietly, when the form was closed. */
|
|
1835
1843
|
function replaced() {
|
|
1836
|
-
return disposed ? { reason: 'closed' } : { reason: 'cannot', message: messages.recordReplaced };
|
|
1844
|
+
return disposed ? { reason: 'closed' } : { reason: 'cannot', message: named(messages.recordReplacedNoun, messages.recordReplaced) };
|
|
1837
1845
|
}
|
|
1838
1846
|
/** The record a record step asks the data source about. */
|
|
1839
1847
|
const record = () => ({ model: page.data.model, id: state.recordId, fields });
|
|
@@ -1943,7 +1951,7 @@ function innerForm(options, within, place, outer) {
|
|
|
1943
1951
|
},
|
|
1944
1952
|
post,
|
|
1945
1953
|
wordsOf: (field) => wordsOfValue(fieldDef(field), state.values[field]),
|
|
1946
|
-
barred: (right) => (state.can?.[right] === false ? state.can.reason ?? messages[MAY_NOT[right]] : null),
|
|
1954
|
+
barred: (right) => (state.can?.[right] === false ? state.can.reason ?? named(messages[`${MAY_NOT[right]}Noun`], messages[MAY_NOT[right]]) : null),
|
|
1947
1955
|
});
|
|
1948
1956
|
// A moment's run is on the record it was set off on: one set off again while its run goes, and run after it, is let
|
|
1949
1957
|
// go when another record is shown by then (its steps were for that one).
|
|
@@ -1971,7 +1979,7 @@ function innerForm(options, within, place, outer) {
|
|
|
1971
1979
|
const builtin = 'builtin' in source && !list.length ? source.builtin : undefined;
|
|
1972
1980
|
if (builtin)
|
|
1973
1981
|
list.push({ do: builtin });
|
|
1974
|
-
const asked = builtin === 'archive' ? messages.archiveConfirm : builtin === 'delete' ? messages.deleteConfirm : undefined;
|
|
1982
|
+
const asked = builtin === 'archive' ? named(messages.archiveConfirmNoun, messages.archiveConfirm) : builtin === 'delete' ? named(messages.deleteConfirmNoun, messages.deleteConfirm) : undefined;
|
|
1975
1983
|
const confirm = 'confirm' in source && source.confirm !== undefined ? source.confirm : asked;
|
|
1976
1984
|
// On the record it was pressed on: another shown while its question is asked, it does nothing to that one.
|
|
1977
1985
|
scope.generation ??= generation;
|
|
@@ -2286,7 +2294,7 @@ function innerForm(options, within, place, outer) {
|
|
|
2286
2294
|
const sub = def.fields[subfield];
|
|
2287
2295
|
if (!sub)
|
|
2288
2296
|
throw new Error(`The lines of "${field}" have no field "${subfield}"`);
|
|
2289
|
-
const line = (state.values[field] ?? []).find((l) => l.key === key);
|
|
2297
|
+
const line = key === null ? { values: newLineValues(field), id: null } : (state.values[field] ?? []).find((l) => l.key === key);
|
|
2290
2298
|
if (!line)
|
|
2291
2299
|
throw new Error(`"${field}" has no line "${key}"`);
|
|
2292
2300
|
return runSearch(sub, subfield, lineContext(line.values, def.fields, context(), line.id ?? null), query, limit, options);
|