@fieldia/core 0.22.0 → 0.24.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 +135 -3
- package/package.json +1 -1
- package/schema/page.schema.json +159 -4
- package/src/index.d.mts +6 -2
- package/src/index.d.ts +6 -2
- package/src/index.js +18 -1
- package/src/index.js.map +1 -1
- package/src/index.mjs +8 -2
- package/src/index.mjs.map +1 -1
- package/src/lib/format/autofill-group.d.mts +12 -0
- package/src/lib/format/autofill-group.d.ts +12 -0
- package/src/lib/format/autofill-group.js +23 -0
- package/src/lib/format/autofill-group.js.map +1 -0
- package/src/lib/format/autofill-group.mjs +19 -0
- package/src/lib/format/autofill-group.mjs.map +1 -0
- package/src/lib/format/autofill.d.mts +14 -0
- package/src/lib/format/autofill.d.ts +14 -0
- package/src/lib/format/autofill.js +54 -0
- package/src/lib/format/autofill.js.map +1 -0
- package/src/lib/format/autofill.mjs +48 -0
- package/src/lib/format/autofill.mjs.map +1 -0
- package/src/lib/format/bulk-edit.d.mts +18 -0
- package/src/lib/format/bulk-edit.d.ts +18 -0
- package/src/lib/format/bulk-edit.js +26 -0
- package/src/lib/format/bulk-edit.js.map +1 -0
- package/src/lib/format/bulk-edit.mjs +21 -0
- package/src/lib/format/bulk-edit.mjs.map +1 -0
- package/src/lib/format/field.d.mts +55 -34
- package/src/lib/format/field.d.ts +55 -34
- package/src/lib/format/field.js +16 -2
- package/src/lib/format/field.js.map +1 -1
- package/src/lib/format/field.mjs +15 -1
- package/src/lib/format/field.mjs.map +1 -1
- package/src/lib/format/layout.d.mts +365 -66
- package/src/lib/format/layout.d.ts +365 -66
- package/src/lib/format/layout.js +22 -4
- package/src/lib/format/layout.js.map +1 -1
- package/src/lib/format/layout.mjs +20 -3
- package/src/lib/format/layout.mjs.map +1 -1
- package/src/lib/format/page.d.mts +169 -29
- package/src/lib/format/page.d.ts +169 -29
- package/src/lib/format/page.js +11 -0
- package/src/lib/format/page.js.map +1 -1
- package/src/lib/format/page.mjs +12 -1
- package/src/lib/format/page.mjs.map +1 -1
- package/src/lib/format/phone.d.mts +27 -0
- package/src/lib/format/phone.d.ts +27 -0
- package/src/lib/format/phone.js +43 -0
- package/src/lib/format/phone.js.map +1 -0
- package/src/lib/format/phone.mjs +39 -0
- package/src/lib/format/phone.mjs.map +1 -0
- package/src/lib/format/references.d.mts +10 -0
- package/src/lib/format/references.d.ts +10 -0
- package/src/lib/format/references.js +96 -1
- package/src/lib/format/references.js.map +1 -1
- package/src/lib/format/references.mjs +96 -1
- package/src/lib/format/references.mjs.map +1 -1
- package/src/lib/format/slots-options.d.mts +26 -0
- package/src/lib/format/slots-options.d.ts +26 -0
- package/src/lib/format/slots-options.js +35 -0
- package/src/lib/format/slots-options.js.map +1 -0
- package/src/lib/format/slots-options.mjs +31 -0
- package/src/lib/format/slots-options.mjs.map +1 -0
- package/src/lib/format/upgrade.d.mts +4 -1
- package/src/lib/format/upgrade.d.ts +4 -1
- package/src/lib/format/upgrade.js +4 -1
- package/src/lib/format/upgrade.js.map +1 -1
- package/src/lib/format/upgrade.mjs +4 -1
- 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/format/zoned.d.mts +8 -0
- package/src/lib/format/zoned.d.ts +8 -0
- package/src/lib/format/zoned.js +36 -0
- package/src/lib/format/zoned.js.map +1 -0
- package/src/lib/format/zoned.mjs +33 -0
- package/src/lib/format/zoned.mjs.map +1 -0
- package/src/lib/record/check.d.mts +6 -1
- package/src/lib/record/check.d.ts +6 -1
- package/src/lib/record/check.js +12 -4
- package/src/lib/record/check.js.map +1 -1
- package/src/lib/record/check.mjs +12 -4
- package/src/lib/record/check.mjs.map +1 -1
- package/src/lib/record/data-source.d.mts +188 -3
- package/src/lib/record/data-source.d.ts +188 -3
- package/src/lib/record/data-source.js.map +1 -1
- package/src/lib/record/data-source.mjs.map +1 -1
- package/src/lib/record/form.d.mts +72 -25
- package/src/lib/record/form.d.ts +72 -25
- package/src/lib/record/form.js +404 -78
- package/src/lib/record/form.js.map +1 -1
- package/src/lib/record/form.mjs +404 -78
- package/src/lib/record/form.mjs.map +1 -1
- package/src/lib/record/input-rules.d.mts +51 -9
- package/src/lib/record/input-rules.d.ts +51 -9
- package/src/lib/record/input-rules.js +119 -20
- package/src/lib/record/input-rules.js.map +1 -1
- package/src/lib/record/input-rules.mjs +118 -19
- package/src/lib/record/input-rules.mjs.map +1 -1
- package/src/lib/record/inputs.js +4 -2
- package/src/lib/record/inputs.js.map +1 -1
- package/src/lib/record/inputs.mjs +4 -2
- package/src/lib/record/inputs.mjs.map +1 -1
- package/src/lib/record/limits.d.mts +1 -1
- package/src/lib/record/limits.d.ts +1 -1
- package/src/lib/record/limits.js +4 -2
- package/src/lib/record/limits.js.map +1 -1
- package/src/lib/record/limits.mjs +4 -2
- package/src/lib/record/limits.mjs.map +1 -1
- package/src/lib/record/locales/ar.js +3 -2
- package/src/lib/record/locales/ar.js.map +1 -1
- package/src/lib/record/locales/ar.mjs +3 -2
- package/src/lib/record/locales/ar.mjs.map +1 -1
- package/src/lib/record/locales/de.js +3 -2
- package/src/lib/record/locales/de.js.map +1 -1
- package/src/lib/record/locales/de.mjs +3 -2
- package/src/lib/record/locales/de.mjs.map +1 -1
- package/src/lib/record/locales/fr.js +3 -2
- package/src/lib/record/locales/fr.js.map +1 -1
- package/src/lib/record/locales/fr.mjs +3 -2
- package/src/lib/record/locales/fr.mjs.map +1 -1
- package/src/lib/record/memory-data-source.d.mts +13 -2
- package/src/lib/record/memory-data-source.d.ts +13 -2
- package/src/lib/record/memory-data-source.js +92 -35
- package/src/lib/record/memory-data-source.js.map +1 -1
- package/src/lib/record/memory-data-source.mjs +93 -36
- package/src/lib/record/memory-data-source.mjs.map +1 -1
- package/src/lib/record/memory-schedules.d.mts +45 -0
- package/src/lib/record/memory-schedules.d.ts +45 -0
- package/src/lib/record/memory-schedules.js +81 -0
- package/src/lib/record/memory-schedules.js.map +1 -0
- package/src/lib/record/memory-schedules.mjs +78 -0
- package/src/lib/record/memory-schedules.mjs.map +1 -0
- package/src/lib/record/messages.d.mts +3 -1
- package/src/lib/record/messages.d.ts +3 -1
- package/src/lib/record/messages.js +3 -2
- package/src/lib/record/messages.js.map +1 -1
- package/src/lib/record/messages.mjs +3 -2
- package/src/lib/record/messages.mjs.map +1 -1
- package/src/lib/record/periods.d.mts +47 -0
- package/src/lib/record/periods.d.ts +47 -0
- package/src/lib/record/periods.js +86 -0
- package/src/lib/record/periods.js.map +1 -0
- package/src/lib/record/periods.mjs +79 -0
- package/src/lib/record/periods.mjs.map +1 -0
- package/src/lib/record/rules.js +5 -6
- package/src/lib/record/rules.js.map +1 -1
- package/src/lib/record/rules.mjs +5 -6
- package/src/lib/record/rules.mjs.map +1 -1
- package/src/lib/record/run.d.mts +44 -8
- package/src/lib/record/run.d.ts +44 -8
- package/src/lib/record/run.js +155 -26
- package/src/lib/record/run.js.map +1 -1
- package/src/lib/record/run.mjs +156 -27
- package/src/lib/record/run.mjs.map +1 -1
- package/src/lib/record/search.d.mts +13 -3
- package/src/lib/record/search.d.ts +13 -3
- package/src/lib/record/search.js +11 -4
- package/src/lib/record/search.js.map +1 -1
- package/src/lib/record/search.mjs +11 -4
- package/src/lib/record/search.mjs.map +1 -1
- package/src/lib/record/zones.d.mts +57 -0
- package/src/lib/record/zones.d.ts +57 -0
- package/src/lib/record/zones.js +147 -0
- package/src/lib/record/zones.js.map +1 -0
- package/src/lib/record/zones.mjs +132 -0
- package/src/lib/record/zones.mjs.map +1 -0
- package/src/runtime.d.mts +12 -5
- package/src/runtime.d.ts +12 -5
- package/src/runtime.js +32 -2
- package/src/runtime.js.map +1 -1
- package/src/runtime.mjs +7 -1
- package/src/runtime.mjs.map +1 -1
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Days counted as a list counts them: the days of a period its filter names
|
|
4
|
+
* ("This week", "Last 30 days", "Overdue"), and the span a date falls in when
|
|
5
|
+
* the list is grouped by it (its week, month, quarter or year). A date
|
|
6
|
+
* field's value is its day ("2026-10-14"); a date and time's is an instant
|
|
7
|
+
* ("2026-10-14T07:40:00.000Z"), which falls on the day it is where the page
|
|
8
|
+
* is: in the time zone given, or the computer's own. Days are counted by the
|
|
9
|
+
* calendar, never by adding hours, so a change of the clocks moves no day.
|
|
10
|
+
*
|
|
11
|
+
* Here, what both a list and a data source count: a day where a time zone
|
|
12
|
+
* says, a day's first moment there, and the span a value falls in — the
|
|
13
|
+
* memory data source groups by it, as a backend groups by its own. The list
|
|
14
|
+
* part counts a period's days and asks for them (list-days.ts in
|
|
15
|
+
* @fieldia/viewer).
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.dayIn = exports.addDays = exports.DATE_INTERVALS = exports.DATE_PERIODS = void 0;
|
|
19
|
+
exports.dayStarts = dayStarts;
|
|
20
|
+
exports.spanStart = spanStart;
|
|
21
|
+
const zones_1 = require("./zones");
|
|
22
|
+
/** The periods a list's filter can name, counted from the day the list is looked at. */
|
|
23
|
+
exports.DATE_PERIODS = ['today', 'yesterday', 'thisWeek', 'lastWeek', 'thisMonth', 'lastMonth', 'thisYear', 'last7Days', 'last30Days', 'overdue'];
|
|
24
|
+
/** The spans a date's records can be grouped in. */
|
|
25
|
+
exports.DATE_INTERVALS = ['day', 'week', 'month', 'quarter', 'year'];
|
|
26
|
+
/** A day by its numbers, the month from 1, rolled over as the calendar rolls: month 13 is next January, day 0 the last of the month before. */
|
|
27
|
+
const dayAt = (y, m, d) => new Date(Date.UTC(y, m - 1, d)).toISOString().slice(0, 10);
|
|
28
|
+
const numbersOf = (day) => day.split('-').map(Number);
|
|
29
|
+
/** A day `n` days on from another (back, for less than 0). */
|
|
30
|
+
const addDays = (day, n) => {
|
|
31
|
+
const [y, m, d] = numbersOf(day);
|
|
32
|
+
return dayAt(y, m, d + n);
|
|
33
|
+
};
|
|
34
|
+
exports.addDays = addDays;
|
|
35
|
+
/** A zone this browser knows, else none — the computer's own: a source's request may name any. */
|
|
36
|
+
const known = (timeZone) => (timeZone && (0, zones_1.isTimeZone)(timeZone) ? timeZone : undefined);
|
|
37
|
+
/** The day an instant falls on, where the time zone says (zones.ts `dayIn`, the computer's own for a zone it does not know). */
|
|
38
|
+
const dayIn = (at, timeZone) => (0, zones_1.dayIn)(at, known(timeZone));
|
|
39
|
+
exports.dayIn = dayIn;
|
|
40
|
+
/**
|
|
41
|
+
* A day's first moment where the time zone says, as an instant written as a
|
|
42
|
+
* date and time field keeps one ("2026-10-13T21:00:00.000Z" for 14 October in
|
|
43
|
+
* Cairo): its midnight, the first of two where the clocks go back across it,
|
|
44
|
+
* or the moment they go forward on a day they skip midnight.
|
|
45
|
+
*/
|
|
46
|
+
function dayStarts(day, timeZone) {
|
|
47
|
+
const zone = known(timeZone);
|
|
48
|
+
const midnight = (0, zones_1.wallOf)(day);
|
|
49
|
+
const [first] = (0, zones_1.instantsAt)(midnight, zone);
|
|
50
|
+
if (first !== undefined)
|
|
51
|
+
return new Date(first).toISOString();
|
|
52
|
+
const skip = (0, zones_1.clocksSkip)(midnight, zone);
|
|
53
|
+
return new Date(skip ? (0, zones_1.instantsAt)(skip.to, zone)[0] : Date.UTC(midnight.year, midnight.month - 1, midnight.day) - (0, zones_1.zoneOffset)(Date.UTC(midnight.year, midnight.month - 1, midnight.day), zone) * 60000).toISOString();
|
|
54
|
+
}
|
|
55
|
+
/** Its day of the week, 0 Sunday to 6 Saturday. */
|
|
56
|
+
const weekday = (day) => new Date(`${day}T00:00:00Z`).getUTCDay();
|
|
57
|
+
/**
|
|
58
|
+
* The first day of the span a date or a date and time falls in — its day,
|
|
59
|
+
* week, month, quarter or year — where `count` says: "2026-03-01" for any
|
|
60
|
+
* day of March 2026. Null for a value that is no date.
|
|
61
|
+
*/
|
|
62
|
+
function spanStart(value, interval, count = {}) {
|
|
63
|
+
if (typeof value !== 'string' || !/^\d{4}-\d{2}-\d{2}([T ]|$)/.test(value))
|
|
64
|
+
return null;
|
|
65
|
+
let day = value;
|
|
66
|
+
if (value.length > 10) {
|
|
67
|
+
const at = Date.parse(value.replace(' ', 'T'));
|
|
68
|
+
if (Number.isNaN(at))
|
|
69
|
+
return null;
|
|
70
|
+
day = (0, exports.dayIn)(at, count.timeZone);
|
|
71
|
+
}
|
|
72
|
+
const [y, m] = numbersOf(day);
|
|
73
|
+
switch (interval) {
|
|
74
|
+
case 'day':
|
|
75
|
+
return day;
|
|
76
|
+
case 'week':
|
|
77
|
+
return (0, exports.addDays)(day, -((weekday(day) - (count.weekStart ?? 1) + 7) % 7));
|
|
78
|
+
case 'month':
|
|
79
|
+
return dayAt(y, m, 1);
|
|
80
|
+
case 'quarter':
|
|
81
|
+
return dayAt(y, m - ((m - 1) % 3), 1);
|
|
82
|
+
case 'year':
|
|
83
|
+
return dayAt(y, 1, 1);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=periods.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"periods.js","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/record/periods.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Days counted as a list counts them: the days of a period its filter names
|
|
3
|
+
* ("This week", "Last 30 days", "Overdue"), and the span a date falls in when
|
|
4
|
+
* the list is grouped by it (its week, month, quarter or year). A date
|
|
5
|
+
* field's value is its day ("2026-10-14"); a date and time's is an instant
|
|
6
|
+
* ("2026-10-14T07:40:00.000Z"), which falls on the day it is where the page
|
|
7
|
+
* is: in the time zone given, or the computer's own. Days are counted by the
|
|
8
|
+
* calendar, never by adding hours, so a change of the clocks moves no day.
|
|
9
|
+
*
|
|
10
|
+
* Here, what both a list and a data source count: a day where a time zone
|
|
11
|
+
* says, a day's first moment there, and the span a value falls in — the
|
|
12
|
+
* memory data source groups by it, as a backend groups by its own. The list
|
|
13
|
+
* part counts a period's days and asks for them (list-days.ts in
|
|
14
|
+
* @fieldia/viewer).
|
|
15
|
+
*/
|
|
16
|
+
import { clocksSkip, dayIn as zoneDay, instantsAt, isTimeZone, wallOf, zoneOffset } from './zones.mjs';
|
|
17
|
+
/** The periods a list's filter can name, counted from the day the list is looked at. */
|
|
18
|
+
export const DATE_PERIODS = ['today', 'yesterday', 'thisWeek', 'lastWeek', 'thisMonth', 'lastMonth', 'thisYear', 'last7Days', 'last30Days', 'overdue'];
|
|
19
|
+
/** The spans a date's records can be grouped in. */
|
|
20
|
+
export const DATE_INTERVALS = ['day', 'week', 'month', 'quarter', 'year'];
|
|
21
|
+
/** A day by its numbers, the month from 1, rolled over as the calendar rolls: month 13 is next January, day 0 the last of the month before. */
|
|
22
|
+
const dayAt = (y, m, d) => new Date(Date.UTC(y, m - 1, d)).toISOString().slice(0, 10);
|
|
23
|
+
const numbersOf = (day) => day.split('-').map(Number);
|
|
24
|
+
/** A day `n` days on from another (back, for less than 0). */
|
|
25
|
+
export const addDays = (day, n) => {
|
|
26
|
+
const [y, m, d] = numbersOf(day);
|
|
27
|
+
return dayAt(y, m, d + n);
|
|
28
|
+
};
|
|
29
|
+
/** A zone this browser knows, else none — the computer's own: a source's request may name any. */
|
|
30
|
+
const known = (timeZone) => (timeZone && isTimeZone(timeZone) ? timeZone : undefined);
|
|
31
|
+
/** The day an instant falls on, where the time zone says (zones.ts `dayIn`, the computer's own for a zone it does not know). */
|
|
32
|
+
export const dayIn = (at, timeZone) => zoneDay(at, known(timeZone));
|
|
33
|
+
/**
|
|
34
|
+
* A day's first moment where the time zone says, as an instant written as a
|
|
35
|
+
* date and time field keeps one ("2026-10-13T21:00:00.000Z" for 14 October in
|
|
36
|
+
* Cairo): its midnight, the first of two where the clocks go back across it,
|
|
37
|
+
* or the moment they go forward on a day they skip midnight.
|
|
38
|
+
*/
|
|
39
|
+
export function dayStarts(day, timeZone) {
|
|
40
|
+
const zone = known(timeZone);
|
|
41
|
+
const midnight = wallOf(day);
|
|
42
|
+
const [first] = instantsAt(midnight, zone);
|
|
43
|
+
if (first !== undefined)
|
|
44
|
+
return new Date(first).toISOString();
|
|
45
|
+
const skip = clocksSkip(midnight, zone);
|
|
46
|
+
return new Date(skip ? instantsAt(skip.to, zone)[0] : Date.UTC(midnight.year, midnight.month - 1, midnight.day) - zoneOffset(Date.UTC(midnight.year, midnight.month - 1, midnight.day), zone) * 60000).toISOString();
|
|
47
|
+
}
|
|
48
|
+
/** Its day of the week, 0 Sunday to 6 Saturday. */
|
|
49
|
+
const weekday = (day) => new Date(`${day}T00:00:00Z`).getUTCDay();
|
|
50
|
+
/**
|
|
51
|
+
* The first day of the span a date or a date and time falls in — its day,
|
|
52
|
+
* week, month, quarter or year — where `count` says: "2026-03-01" for any
|
|
53
|
+
* day of March 2026. Null for a value that is no date.
|
|
54
|
+
*/
|
|
55
|
+
export function spanStart(value, interval, count = {}) {
|
|
56
|
+
if (typeof value !== 'string' || !/^\d{4}-\d{2}-\d{2}([T ]|$)/.test(value))
|
|
57
|
+
return null;
|
|
58
|
+
let day = value;
|
|
59
|
+
if (value.length > 10) {
|
|
60
|
+
const at = Date.parse(value.replace(' ', 'T'));
|
|
61
|
+
if (Number.isNaN(at))
|
|
62
|
+
return null;
|
|
63
|
+
day = dayIn(at, count.timeZone);
|
|
64
|
+
}
|
|
65
|
+
const [y, m] = numbersOf(day);
|
|
66
|
+
switch (interval) {
|
|
67
|
+
case 'day':
|
|
68
|
+
return day;
|
|
69
|
+
case 'week':
|
|
70
|
+
return addDays(day, -((weekday(day) - (count.weekStart ?? 1) + 7) % 7));
|
|
71
|
+
case 'month':
|
|
72
|
+
return dayAt(y, m, 1);
|
|
73
|
+
case 'quarter':
|
|
74
|
+
return dayAt(y, m - ((m - 1) % 3), 1);
|
|
75
|
+
case 'year':
|
|
76
|
+
return dayAt(y, 1, 1);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=periods.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"periods.mjs","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/record/periods.ts"],"names":[],"mappings":"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"}
|
package/src/lib/record/rules.js
CHANGED
|
@@ -26,14 +26,14 @@ function checkRules(field, label, value, rules, at) {
|
|
|
26
26
|
const level = compiled.rule.level ?? 'error';
|
|
27
27
|
if (found[level] !== undefined || !compiled.when.evaluate(at.context, at.env))
|
|
28
28
|
continue;
|
|
29
|
-
const broken = brokenAsk(compiled, field, value, at.now) ?? brokenAcross(compiled, at);
|
|
29
|
+
const broken = brokenAsk(compiled, field, value, at.now, at.env.today?.()) ?? brokenAcross(compiled, at);
|
|
30
30
|
if (broken)
|
|
31
31
|
found[level] = compiled.rule.message ?? (0, messages_1.fill)(at.messages[broken.say], { label, ...broken.values });
|
|
32
32
|
}
|
|
33
33
|
return found;
|
|
34
34
|
}
|
|
35
35
|
/** The first thing a rule asks that the answer does not keep, in the order a rule lists them. */
|
|
36
|
-
function brokenAsk({ rule, pattern }, field, value, now) {
|
|
36
|
+
function brokenAsk({ rule, pattern }, field, value, now, today) {
|
|
37
37
|
const text = typeof value === 'string' ? value : null;
|
|
38
38
|
if (text !== null && rule.minLength !== undefined && text.length < rule.minLength)
|
|
39
39
|
return { say: 'minLength', values: { min: rule.minLength } };
|
|
@@ -60,7 +60,7 @@ function brokenAsk({ rule, pattern }, field, value, now) {
|
|
|
60
60
|
return { say: 'distinct', values: { column: field.fields[rule.distinct]?.label ?? rule.distinct, value: twice } };
|
|
61
61
|
}
|
|
62
62
|
if (text !== null && rule.date !== undefined) {
|
|
63
|
-
const side = whenIs(field, text, now);
|
|
63
|
+
const side = whenIs(field, text, now, today);
|
|
64
64
|
if (rule.date === 'past' && side >= 0)
|
|
65
65
|
return { say: 'datePast' };
|
|
66
66
|
if (rule.date === 'future' && side <= 0)
|
|
@@ -103,13 +103,12 @@ function brokenAcross({ holds }, at) {
|
|
|
103
103
|
}
|
|
104
104
|
/**
|
|
105
105
|
* Whether an answer is before (-1) or after (1) now, or is now (0): a day
|
|
106
|
-
* against today, a date and time against the clock itself. A date and time
|
|
106
|
+
* against today (the form's: in its page's time zone), a date and time against the clock itself. A date and time
|
|
107
107
|
* that cannot be read is neither (NaN): the field's own rules name it.
|
|
108
108
|
*/
|
|
109
|
-
function whenIs(field, text, now) {
|
|
109
|
+
function whenIs(field, text, now, today = (0, functions_1.localDay)(now)) {
|
|
110
110
|
if (field.type === 'datetime')
|
|
111
111
|
return Math.sign(Date.parse(text) - now.getTime());
|
|
112
|
-
const today = (0, functions_1.localDay)(now);
|
|
113
112
|
return text < today ? -1 : text > today ? 1 : 0;
|
|
114
113
|
}
|
|
115
114
|
//# sourceMappingURL=rules.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rules.js","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/record/rules.ts"],"names":[],"mappings":";;AA0BA,oCAQC;AAWD,gCAgBC;AA1DD,uDAAmD;AACnD,qDAAgF;AAChF,yDAAoD;AACpD,+CAAuD;AACvD,yCAAiD;AACjD,qCAAwF;AAkBxF,SAAgB,YAAY,CAAC,KAAwC;IACnE,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAClC,IAAI;QACJ,IAAI,EAAE,IAAA,0BAAe,EAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC;QACxC,yDAAyD;QACzD,OAAO,EAAE,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,IAAI,CAAC,OAAO,IAAI,CAAC;QAChF,KAAK,EAAE,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAA,0BAAe,EAAC,IAAI,CAAC,KAAK,CAAC;KACrE,CAAC,CAAC,CAAC;AACN,CAAC;AAUD,iGAAiG;AACjG,SAAgB,UAAU,CACxB,KAAY,EACZ,KAAa,EACb,KAAwB,EACxB,KAA8B,EAC9B,EAAe;IAEf,MAAM,KAAK,GAAyC,EAAE,CAAC;IACvD,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,IAAA,gBAAO,EAAC,KAAK,EAAE,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACzD,KAAK,MAAM,QAAQ,IAAI,KAAK,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,IAAI,OAAO,CAAC;QAC7C,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,SAAS,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,CAAC;YAAE,SAAS;QACxF,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAc,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,YAAY,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"rules.js","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/record/rules.ts"],"names":[],"mappings":"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"}
|
package/src/lib/record/rules.mjs
CHANGED
|
@@ -22,14 +22,14 @@ export function checkRules(field, label, value, rules, at) {
|
|
|
22
22
|
const level = compiled.rule.level ?? 'error';
|
|
23
23
|
if (found[level] !== undefined || !compiled.when.evaluate(at.context, at.env))
|
|
24
24
|
continue;
|
|
25
|
-
const broken = brokenAsk(compiled, field, value, at.now) ?? brokenAcross(compiled, at);
|
|
25
|
+
const broken = brokenAsk(compiled, field, value, at.now, at.env.today?.()) ?? brokenAcross(compiled, at);
|
|
26
26
|
if (broken)
|
|
27
27
|
found[level] = compiled.rule.message ?? fill(at.messages[broken.say], { label, ...broken.values });
|
|
28
28
|
}
|
|
29
29
|
return found;
|
|
30
30
|
}
|
|
31
31
|
/** The first thing a rule asks that the answer does not keep, in the order a rule lists them. */
|
|
32
|
-
function brokenAsk({ rule, pattern }, field, value, now) {
|
|
32
|
+
function brokenAsk({ rule, pattern }, field, value, now, today) {
|
|
33
33
|
const text = typeof value === 'string' ? value : null;
|
|
34
34
|
if (text !== null && rule.minLength !== undefined && text.length < rule.minLength)
|
|
35
35
|
return { say: 'minLength', values: { min: rule.minLength } };
|
|
@@ -56,7 +56,7 @@ function brokenAsk({ rule, pattern }, field, value, now) {
|
|
|
56
56
|
return { say: 'distinct', values: { column: field.fields[rule.distinct]?.label ?? rule.distinct, value: twice } };
|
|
57
57
|
}
|
|
58
58
|
if (text !== null && rule.date !== undefined) {
|
|
59
|
-
const side = whenIs(field, text, now);
|
|
59
|
+
const side = whenIs(field, text, now, today);
|
|
60
60
|
if (rule.date === 'past' && side >= 0)
|
|
61
61
|
return { say: 'datePast' };
|
|
62
62
|
if (rule.date === 'future' && side <= 0)
|
|
@@ -99,13 +99,12 @@ function brokenAcross({ holds }, at) {
|
|
|
99
99
|
}
|
|
100
100
|
/**
|
|
101
101
|
* Whether an answer is before (-1) or after (1) now, or is now (0): a day
|
|
102
|
-
* against today, a date and time against the clock itself. A date and time
|
|
102
|
+
* against today (the form's: in its page's time zone), a date and time against the clock itself. A date and time
|
|
103
103
|
* that cannot be read is neither (NaN): the field's own rules name it.
|
|
104
104
|
*/
|
|
105
|
-
function whenIs(field, text, now) {
|
|
105
|
+
function whenIs(field, text, now, today = localDay(now)) {
|
|
106
106
|
if (field.type === 'datetime')
|
|
107
107
|
return Math.sign(Date.parse(text) - now.getTime());
|
|
108
|
-
const today = localDay(now);
|
|
109
108
|
return text < today ? -1 : text > today ? 1 : 0;
|
|
110
109
|
}
|
|
111
110
|
//# sourceMappingURL=rules.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rules.mjs","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/record/rules.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAyB,MAAM,wBAAwB,CAAC;AAChF,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,IAAI,EAAiB,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,QAAQ,EAA6C,MAAM,UAAU,CAAC;AAkBxF,MAAM,UAAU,YAAY,CAAC,KAAwC;IACnE,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAClC,IAAI;QACJ,IAAI,EAAE,eAAe,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC;QACxC,yDAAyD;QACzD,OAAO,EAAE,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,IAAI,CAAC,OAAO,IAAI,CAAC;QAChF,KAAK,EAAE,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC;KACrE,CAAC,CAAC,CAAC;AACN,CAAC;AAUD,iGAAiG;AACjG,MAAM,UAAU,UAAU,CACxB,KAAY,EACZ,KAAa,EACb,KAAwB,EACxB,KAA8B,EAC9B,EAAe;IAEf,MAAM,KAAK,GAAyC,EAAE,CAAC;IACvD,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACzD,KAAK,MAAM,QAAQ,IAAI,KAAK,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,IAAI,OAAO,CAAC;QAC7C,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,SAAS,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,CAAC;YAAE,SAAS;QACxF,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAc,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,YAAY,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"rules.mjs","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/record/rules.ts"],"names":[],"mappings":"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"}
|
package/src/lib/record/run.d.mts
CHANGED
|
@@ -4,13 +4,18 @@ import type { JsonValue } from '../format/json.mjs';
|
|
|
4
4
|
import type { Tone } from '../format/layout.mjs';
|
|
5
5
|
import { type ExpressionEnv } from '../expression/expression.mjs';
|
|
6
6
|
import type { ResolvedFilter } from './data-source.mjs';
|
|
7
|
-
import { type RecordId, type Values } from './values.mjs';
|
|
7
|
+
import { type RecordId, type Value, type Values } from './values.mjs';
|
|
8
8
|
/**
|
|
9
9
|
* The engine that runs steps — a button's, a moment's, or the app's own —
|
|
10
10
|
* against a form. Steps run in order; one whose `when` does not hold is
|
|
11
11
|
* passed over; the first that fails or is refused stops the rest, and the
|
|
12
12
|
* run's result says which and why. What the core cannot draw — a page opened,
|
|
13
13
|
* words said, a question asked — it asks of the host the viewer gives.
|
|
14
|
+
*
|
|
15
|
+
* A run that saves is one piece of work, as a record's button is in Flectra:
|
|
16
|
+
* when its save, or a check before it, is refused, what its own steps wrote
|
|
17
|
+
* since its last save is put back — a status a button moved stays where it
|
|
18
|
+
* was, and a field it locked stays open to put right.
|
|
14
19
|
*/
|
|
15
20
|
/** A button pressed, or a `call` step run: what the app's `onAction` is handed. */
|
|
16
21
|
export interface ActionRequest {
|
|
@@ -158,7 +163,8 @@ export interface RunResult {
|
|
|
158
163
|
/**
|
|
159
164
|
* The place, among the steps run, of the one that stopped: for a step of
|
|
160
165
|
* an `open`'s `then`, the open step's place; for a button's `action`, one
|
|
161
|
-
* past its steps. Absent when a button's `confirm` was answered No
|
|
166
|
+
* past its steps. Absent when a button's `confirm` was answered No, or when
|
|
167
|
+
* the save a record's button makes before its steps was refused.
|
|
162
168
|
*/
|
|
163
169
|
stoppedAt?: number;
|
|
164
170
|
/** The step that stopped, wherever it was. */
|
|
@@ -199,6 +205,24 @@ export interface RunScope {
|
|
|
199
205
|
* the run stops: its steps are not for that record.
|
|
200
206
|
*/
|
|
201
207
|
generation?: number;
|
|
208
|
+
/**
|
|
209
|
+
* A run the person or the app set off — a button, its key, a line's button, `form.run` — reads what is typed
|
|
210
|
+
* first (`'first'`), as a save does: before its first step that reads the form or hands its values on (`set`, a
|
|
211
|
+
* `call`, an `open` with values, a `when`…), every box is read and a name looked up waited for, and text that does
|
|
212
|
+
* not read stops it, said under its box. `'read'` once done. A moment's run takes the values as they are: it never
|
|
213
|
+
* reads a box under the person's keys.
|
|
214
|
+
*/
|
|
215
|
+
typed?: 'first' | 'read';
|
|
216
|
+
/**
|
|
217
|
+
* What the run's own steps wrote since its last save, by field: what it held
|
|
218
|
+
* before the first of them, whether that was the person's own change, and
|
|
219
|
+
* what the last wrote. Put back when the run's save is refused.
|
|
220
|
+
*/
|
|
221
|
+
wrote?: Map<string, {
|
|
222
|
+
before: Value;
|
|
223
|
+
mine: boolean;
|
|
224
|
+
after: Value;
|
|
225
|
+
}>;
|
|
202
226
|
}
|
|
203
227
|
/** What a run reaches its form by: the form gives these. */
|
|
204
228
|
export interface RunForm {
|
|
@@ -211,13 +235,25 @@ export interface RunForm {
|
|
|
211
235
|
env: ExpressionEnv;
|
|
212
236
|
};
|
|
213
237
|
today(): string;
|
|
214
|
-
/**
|
|
215
|
-
|
|
238
|
+
/**
|
|
239
|
+
* Write fields as a step does: worked out once, no person's change. Throws for a field the page lacks. `chain`, the
|
|
240
|
+
* run's: a page's `change` steps work out the person's change, and a write of theirs leaves it the person's.
|
|
241
|
+
*/
|
|
242
|
+
write(values: Values, chain: readonly string[]): void;
|
|
216
243
|
/** Write values the record holds where it is kept: no change to save. */
|
|
217
244
|
store(values: Values): void;
|
|
245
|
+
/** Whether a field holds the person's own change, not one a step or the app wrote. */
|
|
246
|
+
mine(field: string): boolean;
|
|
247
|
+
/** Put back what a run's steps wrote, as `write` does; the fields in `mine` are the person's own changes again. */
|
|
248
|
+
putBack(values: Values, mine: readonly string[]): void;
|
|
218
249
|
addLine(field: string, values: Values): void;
|
|
219
250
|
/** Check fields as sending does: what is still typed in a box read first, a name being looked up waited for. */
|
|
220
251
|
check(fields: readonly string[] | undefined): Stopped | null | Promise<Stopped | null>;
|
|
252
|
+
/**
|
|
253
|
+
* What is typed read, as a save reads it — a name being looked up waited for: null to go on, else why the run
|
|
254
|
+
* stops — text left in a box that does not read, said under its box as a check says it.
|
|
255
|
+
*/
|
|
256
|
+
typedFirst(): Promise<Stopped | null>;
|
|
221
257
|
save(chain: readonly string[]): Promise<Stopped | null>;
|
|
222
258
|
/** The number of the record shown now: each record shown — opened, loaded again, a new one — has its own. */
|
|
223
259
|
generation(): number;
|
|
@@ -279,13 +315,13 @@ export interface RunForm {
|
|
|
279
315
|
post(message: PostedMessage): Promise<boolean>;
|
|
280
316
|
/** A field's value as words in a posted message: a link's name, a choice's label. */
|
|
281
317
|
wordsOf(field: string): string;
|
|
282
|
-
/** Why the person may not archive, copy or delete the record, as its source told: their words to say; null when they may. */
|
|
283
|
-
barred?(right: 'archive' | 'duplicate' | 'delete'): string | null;
|
|
318
|
+
/** Why the person may not change, archive, copy or delete the record, as its source told: their words to say; null when they may. */
|
|
319
|
+
barred?(right: 'edit' | 'archive' | 'duplicate' | 'delete'): string | null;
|
|
284
320
|
}
|
|
285
321
|
export declare const DONE: RunResult;
|
|
286
322
|
/** Steps run against one form. Expressions are read once and kept. */
|
|
287
323
|
export declare function createRunner(form: RunForm): {
|
|
288
|
-
runSteps: (steps: readonly ActionStep[], scope: RunScope) => Promise<RunResult>;
|
|
324
|
+
runSteps: (steps: readonly ActionStep[], scope: RunScope, inner?: boolean) => Promise<RunResult>;
|
|
289
325
|
ask: (message: string) => Promise<boolean>;
|
|
290
326
|
};
|
|
291
327
|
/**
|
|
@@ -296,4 +332,4 @@ export declare function createRunner(form: RunForm): {
|
|
|
296
332
|
* meanwhile; the others (beforeSave, afterSave) do not run — a save made
|
|
297
333
|
* meanwhile goes ahead without them, so nothing waits on itself.
|
|
298
334
|
*/
|
|
299
|
-
export declare function createMoments(run: (key: string, steps: readonly ActionStep[], chain: readonly string[]) => Promise<RunResult
|
|
335
|
+
export declare function createMoments(run: (key: string, steps: readonly ActionStep[], chain: readonly string[], on?: number) => Promise<RunResult>, now?: () => number): (key: string, steps: readonly ActionStep[] | undefined, chain: readonly string[], again: boolean) => Promise<RunResult>;
|
package/src/lib/record/run.d.ts
CHANGED
|
@@ -4,13 +4,18 @@ import type { JsonValue } from '../format/json';
|
|
|
4
4
|
import type { Tone } from '../format/layout';
|
|
5
5
|
import { type ExpressionEnv } from '../expression/expression';
|
|
6
6
|
import type { ResolvedFilter } from './data-source';
|
|
7
|
-
import { type RecordId, type Values } from './values';
|
|
7
|
+
import { type RecordId, type Value, type Values } from './values';
|
|
8
8
|
/**
|
|
9
9
|
* The engine that runs steps — a button's, a moment's, or the app's own —
|
|
10
10
|
* against a form. Steps run in order; one whose `when` does not hold is
|
|
11
11
|
* passed over; the first that fails or is refused stops the rest, and the
|
|
12
12
|
* run's result says which and why. What the core cannot draw — a page opened,
|
|
13
13
|
* words said, a question asked — it asks of the host the viewer gives.
|
|
14
|
+
*
|
|
15
|
+
* A run that saves is one piece of work, as a record's button is in Flectra:
|
|
16
|
+
* when its save, or a check before it, is refused, what its own steps wrote
|
|
17
|
+
* since its last save is put back — a status a button moved stays where it
|
|
18
|
+
* was, and a field it locked stays open to put right.
|
|
14
19
|
*/
|
|
15
20
|
/** A button pressed, or a `call` step run: what the app's `onAction` is handed. */
|
|
16
21
|
export interface ActionRequest {
|
|
@@ -158,7 +163,8 @@ export interface RunResult {
|
|
|
158
163
|
/**
|
|
159
164
|
* The place, among the steps run, of the one that stopped: for a step of
|
|
160
165
|
* an `open`'s `then`, the open step's place; for a button's `action`, one
|
|
161
|
-
* past its steps. Absent when a button's `confirm` was answered No
|
|
166
|
+
* past its steps. Absent when a button's `confirm` was answered No, or when
|
|
167
|
+
* the save a record's button makes before its steps was refused.
|
|
162
168
|
*/
|
|
163
169
|
stoppedAt?: number;
|
|
164
170
|
/** The step that stopped, wherever it was. */
|
|
@@ -199,6 +205,24 @@ export interface RunScope {
|
|
|
199
205
|
* the run stops: its steps are not for that record.
|
|
200
206
|
*/
|
|
201
207
|
generation?: number;
|
|
208
|
+
/**
|
|
209
|
+
* A run the person or the app set off — a button, its key, a line's button, `form.run` — reads what is typed
|
|
210
|
+
* first (`'first'`), as a save does: before its first step that reads the form or hands its values on (`set`, a
|
|
211
|
+
* `call`, an `open` with values, a `when`…), every box is read and a name looked up waited for, and text that does
|
|
212
|
+
* not read stops it, said under its box. `'read'` once done. A moment's run takes the values as they are: it never
|
|
213
|
+
* reads a box under the person's keys.
|
|
214
|
+
*/
|
|
215
|
+
typed?: 'first' | 'read';
|
|
216
|
+
/**
|
|
217
|
+
* What the run's own steps wrote since its last save, by field: what it held
|
|
218
|
+
* before the first of them, whether that was the person's own change, and
|
|
219
|
+
* what the last wrote. Put back when the run's save is refused.
|
|
220
|
+
*/
|
|
221
|
+
wrote?: Map<string, {
|
|
222
|
+
before: Value;
|
|
223
|
+
mine: boolean;
|
|
224
|
+
after: Value;
|
|
225
|
+
}>;
|
|
202
226
|
}
|
|
203
227
|
/** What a run reaches its form by: the form gives these. */
|
|
204
228
|
export interface RunForm {
|
|
@@ -211,13 +235,25 @@ export interface RunForm {
|
|
|
211
235
|
env: ExpressionEnv;
|
|
212
236
|
};
|
|
213
237
|
today(): string;
|
|
214
|
-
/**
|
|
215
|
-
|
|
238
|
+
/**
|
|
239
|
+
* Write fields as a step does: worked out once, no person's change. Throws for a field the page lacks. `chain`, the
|
|
240
|
+
* run's: a page's `change` steps work out the person's change, and a write of theirs leaves it the person's.
|
|
241
|
+
*/
|
|
242
|
+
write(values: Values, chain: readonly string[]): void;
|
|
216
243
|
/** Write values the record holds where it is kept: no change to save. */
|
|
217
244
|
store(values: Values): void;
|
|
245
|
+
/** Whether a field holds the person's own change, not one a step or the app wrote. */
|
|
246
|
+
mine(field: string): boolean;
|
|
247
|
+
/** Put back what a run's steps wrote, as `write` does; the fields in `mine` are the person's own changes again. */
|
|
248
|
+
putBack(values: Values, mine: readonly string[]): void;
|
|
218
249
|
addLine(field: string, values: Values): void;
|
|
219
250
|
/** Check fields as sending does: what is still typed in a box read first, a name being looked up waited for. */
|
|
220
251
|
check(fields: readonly string[] | undefined): Stopped | null | Promise<Stopped | null>;
|
|
252
|
+
/**
|
|
253
|
+
* What is typed read, as a save reads it — a name being looked up waited for: null to go on, else why the run
|
|
254
|
+
* stops — text left in a box that does not read, said under its box as a check says it.
|
|
255
|
+
*/
|
|
256
|
+
typedFirst(): Promise<Stopped | null>;
|
|
221
257
|
save(chain: readonly string[]): Promise<Stopped | null>;
|
|
222
258
|
/** The number of the record shown now: each record shown — opened, loaded again, a new one — has its own. */
|
|
223
259
|
generation(): number;
|
|
@@ -279,13 +315,13 @@ export interface RunForm {
|
|
|
279
315
|
post(message: PostedMessage): Promise<boolean>;
|
|
280
316
|
/** A field's value as words in a posted message: a link's name, a choice's label. */
|
|
281
317
|
wordsOf(field: string): string;
|
|
282
|
-
/** Why the person may not archive, copy or delete the record, as its source told: their words to say; null when they may. */
|
|
283
|
-
barred?(right: 'archive' | 'duplicate' | 'delete'): string | null;
|
|
318
|
+
/** Why the person may not change, archive, copy or delete the record, as its source told: their words to say; null when they may. */
|
|
319
|
+
barred?(right: 'edit' | 'archive' | 'duplicate' | 'delete'): string | null;
|
|
284
320
|
}
|
|
285
321
|
export declare const DONE: RunResult;
|
|
286
322
|
/** Steps run against one form. Expressions are read once and kept. */
|
|
287
323
|
export declare function createRunner(form: RunForm): {
|
|
288
|
-
runSteps: (steps: readonly ActionStep[], scope: RunScope) => Promise<RunResult>;
|
|
324
|
+
runSteps: (steps: readonly ActionStep[], scope: RunScope, inner?: boolean) => Promise<RunResult>;
|
|
289
325
|
ask: (message: string) => Promise<boolean>;
|
|
290
326
|
};
|
|
291
327
|
/**
|
|
@@ -296,4 +332,4 @@ export declare function createRunner(form: RunForm): {
|
|
|
296
332
|
* meanwhile; the others (beforeSave, afterSave) do not run — a save made
|
|
297
333
|
* meanwhile goes ahead without them, so nothing waits on itself.
|
|
298
334
|
*/
|
|
299
|
-
export declare function createMoments(run: (key: string, steps: readonly ActionStep[], chain: readonly string[]) => Promise<RunResult
|
|
335
|
+
export declare function createMoments(run: (key: string, steps: readonly ActionStep[], chain: readonly string[], on?: number) => Promise<RunResult>, now?: () => number): (key: string, steps: readonly ActionStep[] | undefined, chain: readonly string[], again: boolean) => Promise<RunResult>;
|